XForms/供求关系
外观
< XForms
您希望使用动态图表创建概念的简单说明。 您希望使用范围控件来更改输入并查看该更改对输出的影响。

这还不能使用范围控件。 我使用 SVG 和 JavaScript 编写了它,并且正在将其移植到 XForms。 我还需要使用 CSS 来清理标记。
<?xml version="1.0" encoding="utf-8"?>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<svg
xmlns="http://www.w3.org/2000/svg"
xml:space="preserve" width="300" height="450" onload="OnLoadEvent(evt)">
<defs>
<g id="arrowMarker">
<g stroke="black" stroke-width="1">
<line x1="6" y1="-2" x2="0" y2="0"/>
<line x1="6" y1="+2" x2="0" y2="0"/>
</g>
</g>
<marker id="startMarker" markerWidth="48" markerHeight="24" viewBox="-4 -4 25 5" orient="auto" refX="0" refY="0" markerUnits="strokeWidth">
<g>
<use xlink:href="#arrowMarker" transform="rotate(180)" stroke-width="1" stroke="black"/>
</g>
</marker>
</defs>
<!-- Title -->
<text x="125" y="30" style="text-anchor:middle; font-family:Ariel-Narrow; font-weight:bold; font-size:18">Price and Demand</text>
<!-- bounding box including all elements -->
<rect x="10" y="10" width="250" height="430" style="stroke:black; stroke-width:2; fill:none"/>
<!-- all drawing is done with the origin being at (0,0) -->
<!-- graph itself -->
<g transform="translate(30 40)">
<!-- vertical price axis -->
<line x1="0" x2="0" y1="200" y2="0" style="fill:none;stroke:black;stroke-width:1;" marker-end="url(#startMarker)"/>
<text x="15" y="10">P</text>
<!-- horizontal axis quantity-->
<line x1="0" x2="200" y1="200" y2="200" style="fill:none;stroke:black;stroke-width:1;" marker-end="url(#startMarker)"/>
<text x="205" y="205">Q</text>
<!-- fixed demmand curve -->
<path id="demmand_curve" style="stroke:red; stroke-width:3" d="M0,0 200,200"/>
<text x="120" y="-10" transform="rotate(45)">Demand</text>
<!-- initial value of price -->
<circle id="newPrice" cx="0" cy="100" r="4" style="stroke:blue; fill:blue"/>
<text id="priceLabel" x="163" y="20" style="text-anchor:end">Input: Price =</text>
<text id="priceText" x="163" y="20">100</text>
<text id="quantityLabel" x="163" y="35" style="text-anchor:end">Output: Quantity =</text>
<text id="quantityText" x="163" y="35">100</text>
<line id="vertLine" x1="100" y1="100" x2="100" y2="200" style="stroke-dasharray: 1, 4;stroke:black;stroke-width:1; "/>
<line id="horizLine" x1="0" y1="100" x2="100" y2="100" style="stroke-dasharray: 1, 4;stroke:black;stroke-width:1; "/>
<g id="explanation" transform="translate(0 260)">
<text x="10" y="0">Adjust price by moving the slider.</text>
<text x="0" y="50">Note that as the input (price) changes.</text>
<text x="10" y="65">the quantity sold also changes.</text>
<text x="0" y="90">At high prices a low quantity is sold.</text>
<text x="0" y="110">At low prices a high quantity is sold.</text>
</g>
<g id="slider" transform="translate(0 220)" xoffset="30">
<rect x="0" y="0" width="210" height="20" style="fill:#c0c0c0"/>
<line style="stroke:black;stroke-width:2;" x1="5" y1="6" x2="205" y2="6"/>
<line style="stroke:white;stroke-width:2;" x1="5" y1="8" x2="205" y2="8"/>
<path style="stroke:black;fill:none;" d="M5,16 5,20 M25,16 25,20 M45,16 45,20 M65,16 65,20 M85,16 85,20 M105,16 105,20 M125,16 125,20 M145,16 145,20 M165,16 165,20 M185,16 185,20 M205,16 205,20"/>
<g id="thumb" transform="translate(100 0)">
<path style="stroke:none;fill:#c0c0c0;" d="M1,2 1,12 5,15 9,12 9,2 Z"/>
<path style="stroke:white;fill:none;" d="M9,1 1,1 1,11"/>
<path style="stroke:black;fill:none;" d="M5,16 10,12 10,2"/>
</g>
<g id="explanation" transform="translate(20 230)">
<text x="0" y="0">Note that as the input (price) moves, the quantity sold changes.</text>
<text x="0" y="20">At high prices a low quantity is sold.</text>
<text x="0" y="40">At low prices a high low quantity is sold.</text>
</g>
</g>
</g>
<script><![CDATA[
// == Slider object based on version by Dr. Stefan Goessner at http://www.mecxpert.de/svg/slider.html
var slider=null, thumb=null, sliderActive = false;
var newPrice=null, priceText=null, quantityText=null, vertLine=null, horizLine=null;
// -----------------------------------------------------------
function SliderDown(event)
{
sliderActive = true;
}
function SliderUp(event)
{
sliderActive = false;
// window.status = "slider is inactive";
}
function SliderMove(event)
{
var value = event.getClientX() - parseFloat(slider.getAttribute("xoffset")) - 4;
if (sliderActive && value > 0 && value < 200)
{
thumb.setAttribute("transform", "translate(" + (value) + " 0)");
SliderCallback(value);
}
}
function SliderClick(event)
{
var value = event.getClientX() - parseFloat(slider.getAttribute("xoffset")) - 4;
if (value > 0 && value < 200)
{
thumb.setAttribute("transform", "translate(" + (value) + " 0)");
SliderCallback(value);
}
}
function SliderCallback(val)
{
// this is where we change the values
newPrice.setAttribute("cy", val);
horizLine.setAttribute("y1", val);
horizLine.setAttribute("y2", val);
horizLine.setAttribute("x2", val);
vertLine.setAttribute("x1", val);
vertLine.setAttribute("x2", val);
vertLine.setAttribute("y1", val);
priceText.firstChild.nodeValue=(200-val);
quantityText.firstChild.nodeValue=(val);
//= Math.round((val*1000)/1000);
window.status = "price is " + (val);
}
function OnLoadEvent(event) // called, when svg file is loaded (s. onLoad=..) ..
{
var doc = event.getTarget() != null ? event.getTarget().getOwnerDocument() : null;
if (doc != null)
{
slider = doc.getElementById("slider");
thumb = doc.getElementById("thumb");
newPrice = doc.getElementById("newPrice");
priceText = doc.getElementById("priceText");
quantityText = doc.getElementById("quantityText");
vertLine = doc.getElementById("vertLine");
horizLine = doc.getElementById("horizLine");
slider.addEventListener("mousedown", SliderDown, false);
slider.addEventListener("mouseup", SliderUp, false);
slider.addEventListener("mousemove", SliderMove, false);
slider.addEventListener("click", SliderClick, false);
}
}
]]></script>
</svg>
<header>
<xf:model>
<xf:instance xmlns="">
<data>
<price>100</price>
</data>
</xf:instance>
</xf:model>
</header>
<body>
<xf:range ref="price" start="0" end="200" step="1">
<xf:label>Price: </xf:label>
</xf:range>
<xf:output ref="price" >
<xf:label>Price: </xf:label>
</xf:output>
</body>
</html>