512 lines
20 KiB
HTML
512 lines
20 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>GoJS Nodes -- Northwoods Software</title>
|
|
<!-- Copyright 1998-2017 by Northwoods Software Corporation. -->
|
|
<script src="../release/go.js"></script>
|
|
<script src="goIntro.js"></script>
|
|
</head>
|
|
<body onload="goIntro()">
|
|
<div id="container" class="container-fluid">
|
|
<div id="content">
|
|
|
|
<h1>Nodes</h1>
|
|
<p>
|
|
You can customize your nodes to have exactly the appearance and behavior that you want.
|
|
So far you have only seen very simple nodes.
|
|
But if you have seen the <a href="../samples/index.html">Sample Applications</a>,
|
|
you have seen many other kinds of nodes.
|
|
</p>
|
|
<p>
|
|
In this page we demonstrate some of the choices you can make when designing your nodes.
|
|
</p>
|
|
|
|
<h2 id="SurroundingContent">Surrounding Content</h2>
|
|
<p>
|
|
It is common to surround interesting information with a border or other background.
|
|
</p>
|
|
<h3 id="SimpleBorders">Simple borders</h3>
|
|
<p>
|
|
Many of the simplest nodes just consist of a <a>Panel</a> of type <a>Panel.Auto</a> with a <a>Shape</a>
|
|
surrounding a <a>TextBlock</a>.
|
|
</p>
|
|
<pre data-language="javascript" id="border">
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Auto",
|
|
$(go.Shape, "Rectangle",
|
|
new go.Binding("fill", "color")),
|
|
$(go.TextBlock,
|
|
{ margin: 5 },
|
|
new go.Binding("text", "key"))
|
|
);
|
|
|
|
diagram.model.nodeDataArray = [
|
|
{ key: "Alpha", color: "lightblue" }
|
|
];
|
|
</pre>
|
|
<script>goCode("border", 300, 150)</script>
|
|
|
|
<h3 id="ShapedNodes">Shaped nodes</h3>
|
|
<p>
|
|
The Shape surrounding the content need not be rectangular.
|
|
This example demonstrates a number of shapes.
|
|
</p>
|
|
<pre data-language="javascript" id="shapes">
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Auto",
|
|
$(go.Shape,
|
|
new go.Binding("figure", "fig"),
|
|
new go.Binding("fill", "color")),
|
|
$(go.TextBlock,
|
|
{ margin: 5 },
|
|
new go.Binding("text", "key"))
|
|
);
|
|
|
|
diagram.model.nodeDataArray = [
|
|
{ key: "Alpha", color: "lightblue", fig: "RoundedRectangle" },
|
|
{ key: "Beta", color: "lightblue", fig: "Ellipse" },
|
|
{ key: "Gamma", color: "lightblue", fig: "Hexagon" },
|
|
{ key: "Delta", color: "lightblue", fig: "FramedRectangle" },
|
|
{ key: "Epsilon", color: "lightblue", fig: "Cloud" },
|
|
{ key: "Zeta", color: "lightblue", fig: "Procedure" }
|
|
];
|
|
</pre>
|
|
<script>goCode("shapes", 300, 150)</script>
|
|
<p>
|
|
The surrounding/background object need not be a <a>Shape</a>.
|
|
You could use a <a>Picture</a> or even a more complex object such as a <a>Panel</a>.
|
|
</p>
|
|
|
|
<h3 id="ComplexContents">Complex contents</h3>
|
|
<p>
|
|
The content of an Auto <a>Panel</a> need not be limited to a single <a>TextBlock</a> --
|
|
you can have arbitrarily complex panels of objects.
|
|
In this example the content is a Table Panel with three rows of TextBlocks.
|
|
</p>
|
|
<pre data-language="javascript" id="borderedtable">
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Auto",
|
|
$(go.Shape,
|
|
{ fill: $(go.Brush, "Linear", { 0: "white", 1: "lightblue" }),
|
|
stroke: "darkblue", strokeWidth: 2 }),
|
|
$(go.Panel, "Table",
|
|
{ defaultAlignment: go.Spot.Left, margin: 4 },
|
|
$(go.RowColumnDefinition, { column: 1, width: 4 }),
|
|
$(go.TextBlock,
|
|
{ row: 0, column: 0, columnSpan: 3, alignment: go.Spot.Center },
|
|
{ font: "bold 12pt sans-serif" },
|
|
new go.Binding("text", "key")),
|
|
$(go.TextBlock, "First: ",
|
|
{ row: 1, column: 0 }),
|
|
$(go.TextBlock,
|
|
{ row: 1, column: 2 },
|
|
new go.Binding("text", "prop1")),
|
|
$(go.TextBlock, "Second: ",
|
|
{ row: 2, column: 0 }),
|
|
$(go.TextBlock,
|
|
{ row: 2, column: 2 },
|
|
new go.Binding("text", "prop2"))
|
|
)
|
|
);
|
|
|
|
diagram.model.nodeDataArray = [
|
|
{ key: "Alpha", prop1: "value of 'prop1'", prop2: "the other property" }
|
|
];
|
|
</pre>
|
|
<script>goCode("borderedtable", 300, 150)</script>
|
|
|
|
<h3 id="FixedSizeNodes">Fixed-size nodes</h3>
|
|
<p>
|
|
The above examples have the "Auto" Panel surround some content, where the content might be of different sizes.
|
|
That results in the Nodes having different sizes.
|
|
</p>
|
|
<p>
|
|
If you want a <a>Panel</a> (and thus a Node, because <a>Node</a> inherits from <a>Part</a> which inherits from <a>Panel</a>)
|
|
to be of fixed size, set <a>GraphObject.desiredSize</a> on that panel.
|
|
(Equivalently, you can set <a>GraphObject.width</a> and <a>GraphObject.height</a>.)
|
|
That may result in the clipping of content that is too large,
|
|
or it may result in extra space if the content is smaller than the available area provided by the "Auto" Panel.
|
|
</p>
|
|
<pre data-language="javascript" id="fixedsize">
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Auto",
|
|
{ desiredSize: new go.Size(100, 50) }, // on Panel
|
|
$(go.Shape,
|
|
new go.Binding("figure", "fig"),
|
|
new go.Binding("fill", "color")),
|
|
$(go.TextBlock,
|
|
{ margin: 5 },
|
|
new go.Binding("text", "key"))
|
|
);
|
|
diagram.model.nodeDataArray = [
|
|
{ key: "Alpha", color: "lightblue", fig: "RoundedRectangle" },
|
|
{ key: "Beta", color: "lightblue", fig: "Ellipse" },
|
|
{ key: "Gamma", color: "lightblue", fig: "Hexagon" },
|
|
{ key: "Delta", color: "lightblue", fig: "FramedRectangle" },
|
|
{ key: "Epsilon,Epsilon,Epsilon", color: "lightblue", fig: "Cloud" },
|
|
{ key: "Z", color: "lightblue", fig: "Procedure" }
|
|
];
|
|
</pre>
|
|
<script>goCode("fixedsize", 500, 200)</script>
|
|
<p>
|
|
Note how the "Epsilon..." TextBlock is measured with the constraint of having a limited width,
|
|
as imposed by the Panel's width. That results in the text being wrapped before (maybe) being clipped.
|
|
</p>
|
|
<p>
|
|
You probably do not want to set the desiredSize of the main element, the Shape in this case above.
|
|
If you did, that would not constrain how the content elements are sized within the Panel.
|
|
</p>
|
|
<pre data-language="javascript" id="fixedsize2">
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Auto",
|
|
$(go.Shape,
|
|
{ desiredSize: new go.Size(100, 50) }, // on main element, not on Panel
|
|
new go.Binding("figure", "fig"),
|
|
new go.Binding("fill", "color")),
|
|
$(go.TextBlock,
|
|
{ margin: 5 },
|
|
new go.Binding("text", "key"))
|
|
);
|
|
diagram.model.nodeDataArray = [
|
|
{ key: "Alpha", color: "lightblue", fig: "RoundedRectangle" },
|
|
{ key: "Beta", color: "lightblue", fig: "Ellipse" },
|
|
{ key: "Gamma", color: "lightblue", fig: "Hexagon" },
|
|
{ key: "Delta", color: "lightblue", fig: "FramedRectangle" },
|
|
{ key: "Epsilon,Epsilon,Epsilon", color: "lightblue", fig: "Cloud" },
|
|
{ key: "Z", color: "lightblue", fig: "Procedure" }
|
|
];
|
|
</pre>
|
|
<script>goCode("fixedsize2", 500, 200)</script>
|
|
<p>
|
|
Note how the TextBlock is measured without the constraint of having a limited width from the Panel.
|
|
That results in the text being treated as a single long line, which is then clipped by the Panel.
|
|
</p>
|
|
|
|
<h2 id="StackedContent">Stacked Content</h2>
|
|
<p>
|
|
Many simple nodes consist of a few objects positioned above each other or next to each other.
|
|
</p>
|
|
|
|
<h3 id="Icons">Icons</h3>
|
|
<p>
|
|
Perhaps the most commonly seen kind of node can be implemented using a Vertical <a>Panel</a>.
|
|
</p>
|
|
<pre data-language="javascript" id="icons">
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Vertical",
|
|
$(go.Picture,
|
|
{ maxSize: new go.Size(50, 50) },
|
|
new go.Binding("source", "img")),
|
|
$(go.TextBlock,
|
|
{ margin: new go.Margin(3, 0, 0, 0),
|
|
maxSize: new go.Size(100, 30),
|
|
isMultiline: false },
|
|
new go.Binding("text", "text"))
|
|
);
|
|
|
|
diagram.model.nodeDataArray = [
|
|
{ text: "kitten", img: "images/50x40.png" }
|
|
];
|
|
</pre>
|
|
<script>goCode("icons", 300, 150)</script>
|
|
<p>
|
|
Of course you are not limited to just two objects in a panel.
|
|
In fact you can have as many GraphObjects in a "Vertical" or a "Horizontal" Panel as you like.
|
|
</p>
|
|
<pre data-language="javascript" id="icons2">
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Vertical",
|
|
$(go.TextBlock,
|
|
{ margin: new go.Margin(3, 0, 0, 0),
|
|
maxSize: new go.Size(100, 30),
|
|
isMultiline: false,
|
|
font: "bold 10pt sans-serif" },
|
|
new go.Binding("text", "head")),
|
|
$(go.Picture,
|
|
{ maxSize: new go.Size(50, 50) },
|
|
new go.Binding("source", "img")),
|
|
$(go.TextBlock,
|
|
{ margin: new go.Margin(3, 0, 0, 0),
|
|
maxSize: new go.Size(100, 30),
|
|
isMultiline: false },
|
|
new go.Binding("text", "foot"))
|
|
);
|
|
diagram.model.nodeDataArray = [
|
|
{ head: "Kitten", foot: "Tantomile", img: "images/50x40.png" }
|
|
];
|
|
</pre>
|
|
<script>goCode("icons2", 300, 150)</script>
|
|
|
|
<h3 id="SmallIcons">Small icons</h3>
|
|
<p>
|
|
Another commonly seen kind of node can be implemented using a Horizontal <a>Panel</a>.
|
|
</p>
|
|
<pre data-language="javascript" id="smallicons">
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Horizontal",
|
|
$(go.Picture,
|
|
{ maxSize: new go.Size(16, 16) },
|
|
new go.Binding("source", "img")),
|
|
$(go.TextBlock,
|
|
{ margin: new go.Margin(0, 0, 0, 2) },
|
|
new go.Binding("text", "text"))
|
|
);
|
|
|
|
diagram.model.nodeDataArray = [
|
|
{ text: "kitten", img: "images/50x40.png" }
|
|
];
|
|
</pre>
|
|
<script>goCode("smallicons", 300, 150)</script>
|
|
|
|
<h2 id="NestedPanels">Nested Panels</h2>
|
|
<p>
|
|
Panels can be nested.
|
|
For example, here is a node consisting of an "Vertical" Panel consisting of an "Auto" Panel surrounding a "Vertical" Panel including a "Horizontal" Panel.
|
|
The outer "Vertical" Panel arranges the main stuff on top and a TextBlock on the bottom.
|
|
The "Auto" Panel supplies a border around everything but the bottom text.
|
|
The inner "Vertical" Panel places three objects vertically in a stack.
|
|
The "Horizontal" Panel which is the first element of the "Vertical" Panel places three objects horizontally in a row.
|
|
</p>
|
|
<pre data-language="javascript" id="nestedpanel1">
|
|
// common styling for each indicator
|
|
function makeIndicator(propName) { // the data property name
|
|
return $(go.Shape,
|
|
"Circle",
|
|
{ width: 8, height: 8, fill: "white", strokeWidth: 0, margin: 5 },
|
|
new go.Binding("fill", propName));
|
|
}
|
|
|
|
function makeImagePath(icon) { return "../samples/images/" + icon; }
|
|
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Vertical",
|
|
$(go.Panel, "Auto",
|
|
{ background: "white" },
|
|
{ portId: "" }, // this whole panel acts as the only port for the node
|
|
$(go.Shape, // the border
|
|
{ fill: "transparent", stroke: "lightgray" }),
|
|
$(go.Panel, "Vertical", // everything within the border
|
|
$(go.Panel, "Horizontal", // the row of status indicators
|
|
makeIndicator("ind0"),
|
|
makeIndicator("ind1"),
|
|
makeIndicator("ind2")
|
|
), // end Horizontal Panel
|
|
$(go.Picture,
|
|
{ width: 32, height: 32, margin: 4 },
|
|
new go.Binding("source", "icon", makeImagePath)),
|
|
$(go.TextBlock,
|
|
{ stretch: go.GraphObject.Horizontal, textAlign: "center" },
|
|
new go.Binding("text", "number"),
|
|
new go.Binding("background", "color"))
|
|
) // end Vertical Panel
|
|
), // end Auto Panel
|
|
$(go.TextBlock,
|
|
{ margin: 4 },
|
|
new go.Binding("text"))
|
|
);
|
|
|
|
diagram.model.nodeDataArray = [
|
|
{ key: 1, text: "Device Type A", number: 17, icon: "server switch.jpg", color: "moccasin",
|
|
ind0: "red", ind1: "orange", ind2: "mediumspringgreen" },
|
|
{ key: 2, text: "Device Type B", number: 97, icon: "voice atm switch.jpg", color: "mistyrose",
|
|
ind0: "lightgray", ind1: "orange", ind2: "green" }
|
|
];
|
|
diagram.model.linkDataArray = [
|
|
{ from: 1, to: 2 }
|
|
];
|
|
</pre>
|
|
<script>goCode("nestedpanel1", 300, 150)</script>
|
|
|
|
<h2 id="DecoratedContent">Decorated Content</h2>
|
|
<p>
|
|
Sometimes you want to have a simple node that may display additional visuals
|
|
to indicate what state it is in.
|
|
</p>
|
|
|
|
<p>
|
|
One way to implement this is to use a Spot <a>Panel</a>, where the main element is itself a Panel
|
|
containing the elements that you always want to display, and there are additional objects located at spots around the main element.
|
|
</p>
|
|
<pre data-language="javascript" id="spotdecorations">
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Spot",
|
|
// the main content:
|
|
$(go.Panel, "Vertical",
|
|
$(go.Picture,
|
|
{ maxSize: new go.Size(50, 50) },
|
|
new go.Binding("source", "img")),
|
|
$(go.TextBlock,
|
|
{ margin: new go.Margin(3, 0, 0, 0) },
|
|
new go.Binding("text", "text"),
|
|
new go.Binding("stroke", "error", function(err) { return err ? "red" : "black" }))
|
|
),
|
|
// decorations:
|
|
$(go.Shape, "TriangleUp",
|
|
{ alignment: go.Spot.TopLeft,
|
|
fill: "yellow", width: 14, height: 14,
|
|
visible: false },
|
|
new go.Binding("visible", "info", function(i) { return i ? true : false; })),
|
|
$(go.Shape, "StopSign",
|
|
{ alignment: go.Spot.TopRight,
|
|
fill: "red", width: 14, height: 14,
|
|
visible: false },
|
|
new go.Binding("visible", "error")),
|
|
{
|
|
toolTip:
|
|
$(go.Adornment, "Auto",
|
|
$(go.Shape, { fill: "#FFFFCC" },
|
|
new go.Binding("visible", "info", function(i) { return i ? true : false; })),
|
|
$(go.TextBlock, { margin: 4 },
|
|
new go.Binding("text", "info"))
|
|
)
|
|
}
|
|
);
|
|
|
|
diagram.model.nodeDataArray = [
|
|
{ text: "kitten", img: "images/50x40.png", info: "" },
|
|
{ text: "kitten", img: "images/50x40.png", error: true, info: "shredded curtains" }
|
|
];
|
|
</pre>
|
|
<script>goCode("spotdecorations", 300, 150)</script>
|
|
|
|
<p>
|
|
As another example of a node decoration, this implements a "ribbon" at the top right corner of the node.
|
|
The ribbon is implemented by a <a>Panel</a> that contains both a <a>Shape</a> and a <a>TextBlock</a>,
|
|
and the panel is positioned by its <a>GraphObject.alignment</a> and <a>GraphObject.alignmentFocus</a> in
|
|
the Spot Panel that also is the <a>Node</a>.
|
|
The appearance of the ribbon is achieved by using a custom <a>Geometry</a> and binding <a>GraphObject.opacity</a>.
|
|
</p>
|
|
<pre data-language="javascript" id="ribbondecorations">
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Spot",
|
|
{ locationSpot: go.Spot.Center, locationObjectName: "BODY" },
|
|
{ selectionObjectName: "BODY" },
|
|
$(go.Panel, "Auto",
|
|
{ name: "BODY", width: 150, height: 100 },
|
|
{ portId: "" },
|
|
$(go.Shape,
|
|
{ fill: "lightgray", stroke: null, strokeWidth: 0 }),
|
|
$(go.TextBlock,
|
|
new go.Binding("text"))
|
|
),
|
|
$(go.Panel, "Spot",
|
|
new go.Binding("opacity", "ribbon", function(t) { return t ? 1 : 0; }),
|
|
// note that the opacity defaults to zero (not visible),
|
|
// in case there is no "ribbon" property
|
|
{ opacity: 0,
|
|
alignment: new go.Spot(1, 0, 5, -5),
|
|
alignmentFocus: go.Spot.TopRight },
|
|
$(go.Shape, // the ribbon itself
|
|
{ geometryString: "F1 M0 0 L30 0 70 40 70 70z",
|
|
fill: "red", stroke: null, strokeWidth: 0 }),
|
|
$(go.TextBlock,
|
|
new go.Binding("text", "ribbon"),
|
|
{ alignment: new go.Spot(1, 0, -29, 29),
|
|
angle: 45, maxSize: new go.Size(100, NaN),
|
|
stroke: "white", font: "bold 13px sans-serif", textAlign: "center" })
|
|
)
|
|
);
|
|
|
|
diagram.model = new go.GraphLinksModel([
|
|
{ key: 1, text: "Alpha" },
|
|
{ key: 2, text: "Beta", ribbon: "NEWEST" }
|
|
],[
|
|
]);
|
|
</pre>
|
|
<script>goCode("ribbondecorations", 500, 150)</script>
|
|
|
|
<h2 id="PositionAndLocation">Position and Location</h2>
|
|
<p>
|
|
Nodes are positioned in document coordinates.
|
|
(For more information, read <a href="viewport.html">Coordinate Systems</a>.)
|
|
The point at which a Node resides, in document coordinates, is normally the top-left corner of the Node's <a>GraphObject.actualBounds</a>.
|
|
If you set the <a>GraphObject.position</a> of a Node, you will be modifying the <code>x</code> and <code>y</code> values of the node's <a>GraphObject.actualBounds</a>.
|
|
</p>
|
|
<p>
|
|
However there are times when it is more natural to think that the "point" of a Node is not at the top-left corner but at some other spot within.
|
|
This is especially true when you want any variably-sized text labels or occasional decorations to be ignored regarding the node's location.
|
|
That is why Nodes also have a "location" which refers to a point inside the Node.
|
|
If you set the <a>Part.location</a> of a Node, you will be lining up the location point of the node to be at that point in document coordinates.
|
|
When you move a Node you are actually changing its <a>Part.location</a>.
|
|
</p>
|
|
<p>
|
|
By default the location of a Node is the same as its position.
|
|
However you can set the <a>Part.locationSpot</a> to cause the location point to be at some spot in the node's actualBounds.
|
|
Furthermore you can set the <a>Part.locationObjectName</a> to cause the location point to be at some spot in some element within the node.
|
|
The position will always be at the top-left corner of the whole node,
|
|
but the location may be some point at some spot in some object within the node.
|
|
</p>
|
|
<pre data-language="javascript" id="positionlocation">
|
|
diagram.initialContentAlignment = go.Spot.Center;
|
|
diagram.grid.visible = true;
|
|
|
|
diagram.add(
|
|
$(go.Node, "Vertical",
|
|
{ position: new go.Point(0, 0) }, // set the Node.position
|
|
$(go.TextBlock, "position", { editable: true }),
|
|
$(go.Shape, { name: "SHAPE", width: 30, height: 30, fill: "lightgreen" })
|
|
));
|
|
|
|
diagram.add(
|
|
$(go.Node, "Vertical",
|
|
{
|
|
location: new go.Point(100, 0), // set the Node.location
|
|
locationObjectName: "SHAPE" // the location point is on the element named "SHAPE"
|
|
},
|
|
$(go.TextBlock, "location", { editable: true }),
|
|
$(go.Shape, { name: "SHAPE", width: 30, height: 30, fill: "lightgreen" })
|
|
));
|
|
</pre>
|
|
<script>goCode("positionlocation", 500, 200)</script>
|
|
<p>
|
|
In this example both nodes have the same Y-coordinate value of zero.
|
|
Note how in the above example the "position" Node has the top-left corner of the node at the grid point.
|
|
Yet the "location" Node has the top-left corner of the green square at the grid point.
|
|
If you edit the text of each node after double-clicking on the text,
|
|
note how the green square moves relative to the diagram grid for the "position" node,
|
|
but that it does not move for the "location" node.
|
|
</p>
|
|
<p>
|
|
It is common to specify the <a>Part.locationSpot</a> to be <code>go.Spot.Center</code> so that the location point
|
|
is at the center of some element in the node, rather than at the top-left corner of that element.
|
|
</p>
|
|
<pre data-language="javascript" id="positionlocation2">
|
|
diagram.initialContentAlignment = go.Spot.Center;
|
|
diagram.grid.visible = true;
|
|
|
|
diagram.add(
|
|
$(go.Node, "Vertical",
|
|
{ position: new go.Point(0, 0) }, // set the Node.position
|
|
$(go.TextBlock, "position", { editable: true }),
|
|
$(go.Panel, "Auto",
|
|
$(go.Shape, "Circle", { name: "SHAPE", width: 16, height: 16, fill: "lightgreen" }),
|
|
$(go.Shape, "Circle", { width: 6, height: 6, strokeWidth: 0 })
|
|
)
|
|
));
|
|
|
|
diagram.add(
|
|
$(go.Node, "Vertical",
|
|
{
|
|
location: new go.Point(100, 0), // set the Node.location
|
|
locationObjectName: "SHAPE", // the location point is at the center of "SHAPE"
|
|
locationSpot: go.Spot.Center
|
|
},
|
|
$(go.TextBlock, "location", { editable: true }),
|
|
$(go.Panel, "Auto",
|
|
$(go.Shape, "Circle", { name: "SHAPE", width: 16, height: 16, fill: "lightgreen" }),
|
|
$(go.Shape, "Circle", { width: 6, height: 6, strokeWidth: 0 })
|
|
)
|
|
));
|
|
</pre>
|
|
<script>goCode("positionlocation2", 500, 200)</script>
|
|
<p>
|
|
If the position or location of a Node is not <a>Point.isReal</a>, it will not be seen, because GoJS will not know where to draw the node.
|
|
In fact the default value for a node's position or location is <code>NaN, NaN</code> and it is the responsibility of either the <a>Diagram.layout</a>
|
|
or data bindings to assign real point values for each node.
|
|
</p>
|
|
</div>
|
|
</body>
|
|
</html>
|