> layout.link.add(pv.Line)
This statement adds a new Line mark to the layout, extending from the
`layout.link` mark prototype, which provides useful properties for
inheritance, such as positioning the control points of the line using
the `x` and `y` attributes of the associated node data:
.left(function(d) d.x)
.top(function(d) d.y)
The magic is that the Line is not added directly to the layout, but
instead added to a new Panel that is replicated for each link in the
graph. We could rewrite the `add` to be explicit, which would look
like this:
layout.add(pv.Panel)
.data(function() layout.links())
.add(pv.Line)
.data(function(p) [p.sourceNode, p.targetNode])
.left(function(d) d.x)
.top(function(d) d.y)
...
We want to draw a line between every pair of connected nodes, i.e., a
line per link. The Line mark renders a polyline (or a spline) with any
number of control points. In this case, however, our lines have
exactly two control points: the source node and the target node. So,
the data associated with the Line is an array of two nodes, and the
data associated with the enclosing Panel is the array of all links.
So, one simple way that you can implement your own network layout is
to initialize the `x` and `y` attributes of the node data, which will
result in setting the positions of the nodes and the links between
them. Another way that you can do it is to override the `top` and
`left` properties of the node prototype:
layout.node
.top(... a function to set the top position ...)
.left(... a function to set the left position ...);
Subsequent calls to layout.node.add and layout.link.add will inherit
the overridden top and left properties. There's a simple example of
this in Gitorious at tests/layout/network.html.
Mike