dc.graph
Version:
Graph visualizations integrated with crossfilter and dc.js
396 lines (393 loc) • 23 kB
HTML
<html>
<head>
<meta charset="utf-8">
<title>doc</title>
<style>
/*github.com style (c) Vasily Polovnyov <vast@whiteants.net>*/
pre code {
display: block; padding: 0.5em;
color: #333;
background: #f8f8ff
}
pre .comment,
pre .template_comment,
pre .diff .header,
pre .javadoc {
color: #998;
font-style: italic
}
pre .keyword,
pre .css .rule .keyword,
pre .winutils,
pre .javascript .title,
pre .nginx .title,
pre .subst,
pre .request,
pre .status {
color: #333;
font-weight: bold
}
pre .number,
pre .hexcolor,
pre .ruby .constant {
color: #099;
}
pre .string,
pre .tag .value,
pre .phpdoc,
pre .tex .formula {
color: #d14
}
pre .title,
pre .id {
color: #900;
font-weight: bold
}
pre .javascript .title,
pre .lisp .title,
pre .clojure .title,
pre .subst {
font-weight: normal
}
pre .class .title,
pre .haskell .type,
pre .vhdl .literal,
pre .tex .command {
color: #458;
font-weight: bold
}
pre .tag,
pre .tag .title,
pre .rules .property,
pre .django .tag .keyword {
color: #000080;
font-weight: normal
}
pre .attribute,
pre .variable,
pre .lisp .body {
color: #008080
}
pre .regexp {
color: #009926
}
pre .class {
color: #458;
font-weight: bold
}
pre .symbol,
pre .ruby .symbol .string,
pre .lisp .keyword,
pre .tex .special,
pre .prompt {
color: #990073
}
pre .built_in,
pre .lisp .title,
pre .clojure .built_in {
color: #0086b3
}
pre .preprocessor,
pre .pi,
pre .doctype,
pre .shebang,
pre .cdata {
color: #999;
font-weight: bold
}
pre .deletion {
background: #fdd
}
pre .addition {
background: #dfd
}
pre .diff .change {
background: #0086b3
}
pre .chunk {
color: #aaa
}
</style>
</head>
<body>
<h1 id="dc-graph-js-api">dc.graph.js API</h1>
<ul>
<li><a href="#diagram">Diagram</a></li>
<li><a href="#legend">Legend</a></li>
</ul>
<h2 id="diagram">Diagram</h2>
<p>The dc_graph.diagram is a dc.js-compatible network visualization component. It registers in
the dc.js chart registry and its nodes and edges are generated from crossfilter groups. It
logically derives from
<a href="https://github.com/dc-js/dc.js/blob/master/web/docs/api-latest.md#base-mixin">the dc.js Base Mixin</a>,
but it does not physically derive from it since so much is different about network visualization
versus conventional diagraming.</p>
<h4 id="-width-value-">.width([value])</h4>
<p>Set or get the width attribute of the diagram. See <code>.height</code> below. Default: 200</p>
<h4 id="-height-value-">.height([value])</h4>
<p>Set or get the height attribute of the diagram. The width and height are applied to the SVG
element generated by the diagram when rendered. If a value is given, then the diagram is returned
for method chaining. If no value is given, then the current value of the height attribute will
be returned. Default: 200</p>
<h4 id="-root-rootelement-">.root([rootElement])</h4>
<p>Get or set the root element, which is usually the parent div. Normally the root is set when the
diagram is constructed; setting it later may have unexpected consequences.</p>
<h4 id="-mousezoomable-boolean-">.mouseZoomable([boolean])</h4>
<p>Get or set whether mouse wheel rotation or touchpad gestures will zoom the diagram, and whether dragging
on the background pans the diagram.</p>
<h4 id="-nodedimension-value-">.nodeDimension([value])</h4>
<p>Set or get the crossfilter dimension which represents the nodes (vertices) in the diagram. Typically there will
be a crossfilter instance for the nodes, and another for the edges.</p>
<p><em>The node dimension currently does nothing, but once selection is supported, it will be used for
filtering other charts on the same crossfilter instance based on the nodes selected.</em></p>
<h4 id="-nodegroup-value-mandatory-">.nodeGroup([value]) - <strong>mandatory</strong></h4>
<p>Set or get the crossfilter group which is the data source for the nodes in the diagram. The diagram will
use the group's <code>.all()</code> method to get an array of <code>{key, value}</code> pairs, where the key is a unique
identifier, and the value is usually an object containing the node's attributes. All accessors work
with these key/value pairs.</p>
<p>If the group is changed or returns different values, the next call to <code>.redraw()</code> will reflect the changes
incrementally.</p>
<p>It is possible to pass another object with the same <code>.all()</code> interface instead of a crossfilter group.</p>
<h4 id="-edgedimension-value-">.edgeDimension([value])</h4>
<p>Set or get the crossfilter dimension which represents the edges in the diagram. Typically there will
be a crossfilter instance for the nodes, and another for the edges.</p>
<p><em>The edge dimension currently does nothing, but once selection is supported, it will be used for filtering
other charts on the same crossfilter instance based on the edges selected.</em></p>
<h4 id="-edgegroup-value-mandatory-">.edgeGroup([value]) - <strong>mandatory</strong></h4>
<p>Set or get the crossfilter group which is the data source for the edges in the diagram. See <code>.nodeGroup</code>
above for the way data is loaded from a crossfilter group.</p>
<p>The values in the key/value pairs returned by <code>diagram.edgeGroup().all()</code> need to support, at a minimum,
the <code>nodeSource</code> and <code>nodeTarget</code>, which should return the same keys as the <code>nodeKey</code></p>
<h4 id="-nodekey-function-">.nodeKey([function])</h4>
<p>Set or get the function which will be used to retrieve the unique key for each node. By default, this
accesses the <code>key</code> field of the object passed to it. The keys should match the keys returned by the
<code>.edgeSource</code> and <code>.edgeTarget</code>.</p>
<h4 id="-edgekey-function-">.edgeKey([function])</h4>
<p>Set or get the function which will be used to retrieve the unique key for each edge. By default, this
accesses the <code>key</code> field of the object passed to it.</p>
<h4 id="-edgesource-function-">.edgeSource([function])</h4>
<p>Set or get the function which will be used to retrieve the source (origin/tail) key of the edge objects.
The key must equal the key returned by the <code>.nodeKey</code> for one of the nodes; if it does not, or
if the node is currently filtered out, the edge will not be displayed. By default, looks for
<code>.value.sourcename</code>.</p>
<h4 id="-edgetarget-function-">.edgeTarget([function])</h4>
<p>Set or get the function which will be used to retrieve the target (destination/head) key of the edge objects.
The key must equal the key returned by the <code>.nodeKey</code> for one of the nodes; if it does not, or
if the node is currently filtered out, the edge will not be displayed. By default, looks for
<code>.value.targetname</code>.</p>
<h4 id="-noderadius-function-">.nodeRadius([function])</h4>
<p>Set or get the function which will be used to retrieve the radius, in pixels, for each node. This
determines the height of nodes, and the width, if <code>nodeFitLabel</code> is false. Default: 25</p>
<h4 id="-nodestrokewidth-function-">.nodeStrokeWidth([function])</h4>
<p>Set or get the function which will be used to retrieve the stroke width, in pixels, for drawing the outline of each
node. According to the SVG specification, the outline will be drawn half on top of the fill, and half
outside. Default: 1</p>
<h4 id="-nodestroke-function-">.nodeStroke([function])</h4>
<p>Set or get the function which will be used to retrieve the stroke color for the outline of each
node. Default: black</p>
<h4 id="-nodefillscale-d3-scale-">.nodeFillScale([d3.scale])</h4>
<p>If set, the value returned from <code>nodeFill</code> will be processed through this d3.scale
to return the fill color. If falsy, uses the identity function (no scale). Default: null.</p>
<h4 id="-nodefill-function-">.nodeFill([function])</h4>
<p>Set or get the function which will be used to retrieve the fill color for the body of each
node. Default: white</p>
<h4 id="-nodepadding-number-">.nodePadding([number])</h4>
<p>Set or get the padding or minimum distance, in pixels, between nodes in the diagram. Default: 6</p>
<h4 id="-nodelabel-function-">.nodeLabel([function])</h4>
<p>Set or get the function which will be used to retrieve the label text to display in each node. By
default, looks for a field <code>label</code> or <code>name</code> inside the <code>value</code> field.</p>
<h4 id="-nodelabelfill-function-">.nodeLabelFill([function])</h4>
<p>Set or get the function which will be used to retrieve the label fill color. Default: null</p>
<h4 id="-nodefitlabel-function-">.nodeFitLabel([function])</h4>
<p>Whether to fit the node shape around the label. Default: true</p>
<h4 id="-nodeshape-object-">.nodeShape([object]</h4>
<p>The shape to use for drawing each node, specified as an object with at least the field
<code>shape</code>: ellipse, polygon</p>
<p>If <code>shape = polygon</code>:</p>
<ul>
<li><code>sides</code>: number of sides for a polygon</li>
</ul>
<h4 id="-nodetitle-function-">.nodeTitle([function])</h4>
<p>Set or get the function which will be used to retrieve the node title, usually rendered as a tooltip.
By default, uses the key of the node.</p>
<h4 id="-nodeordering-function-">.nodeOrdering([function])</h4>
<p>By default, nodes are added to the layout in the order that <code>.nodeGroup().all()</code> returns them. If
specified, <code>.nodeOrdering</code> provides an accessor that returns a key to sort the nodes on.
It would be better not to rely on ordering to affect layout, but it does matter.</p>
<h4 id="-nodefixed-function-">.nodeFixed([function])</h4>
<p>Specify an accessor that returns an {x,y} coordinate for a node that should be
<a href="https://github.com/tgdwyer/WebCola/wiki/Fixed-Node-Positions">fixed in place</a>, and returns
falsy for other nodes.</p>
<h4 id="-edgestroke-function-">.edgeStroke([function])</h4>
<p>Set or get the function which will be used to retrieve the stroke color for the edges. Default: black</p>
<h4 id="-edgestrokewidth-function-">.edgeStrokeWidth([function])</h4>
<p>Set or get the function which will be used to retrieve the stroke width for the edges. Default: 1</p>
<h4 id="-edgeopacity-function-">.edgeOpacity([function])</h4>
<p>Set or get the function which will be used to retrieve the edge opacity, a number from 0 to 1. Default: 1</p>
<h4 id="-edgelabel-function-">.edgeLabel([function])</h4>
<p>Set or get the function which will be used to retrieve the edge label text. The label is displayed when
an edge is hovered over. By default, uses the <code>edgeKey</code>.</p>
<h4 id="-edgearrowhead-function-">.edgeArrowhead([function])</h4>
<p>Set or get the function which will be used to retrieve the name of the arrowhead to use for the target/
head/destination of the edge. Arrow symbols can be specified with <code>.defineArrow()</code>. Return null to
display no arrowhead. Default: 'vee'</p>
<h4 id="-edgearrowtail-function-">.edgeArrowtail([function])</h4>
<p>Set or get the function which will be used to retrieve the name of the arrow tail to use for the source/
tail/source of the edge. Arrow symbols can be specified with <code>.defineArrow()</code>. Return null to
display no arrowhead. Default: null</p>
<h4 id="-edgeislayout-function-">.edgeIsLayout([function])</h4>
<p>To draw an edge but not have it affect the layout, specify a function which returns false for that edge.
By default, will return false if the <code>notLayout</code> field of the edge is truthy, true otherwise.</p>
<h4 id="-lengthstrategy-string-">.lengthStrategy([string])</h4>
<p>Currently, three strategies are supported for specifying the lengths of edges:</p>
<ul>
<li>'individual' - uses the <code>edgeLength</code> for each edge. If it returns falsy, uses the <code>baseLength</code></li>
<li>'symmetric', 'jaccard' - compute the edge length based on the graph structure around the edge. See <a href="https://github.com/tgdwyer/WebCola/wiki/link-lengths">the
cola.js wiki</a> for more details.</li>
<li>'none' - no edge lengths will be specified</li>
</ul>
<h4 id="-edgelength-function-">.edgeLength([function])</h4>
<p>When the <code>.lengthStrategy</code> is 'individual', this accessor will be used to read the length of each edge.
By default, reads the <code>distance</code> field of the edge. If the distance is falsy, uses the <code>baseLength</code>.</p>
<h4 id="-baselength-number-">.baseLength([number])</h4>
<p>Gets or sets the default edge length (in pixels) when the <code>.lengthStrategy</code> is 'individual', and the base
value to be multiplied for 'symmetric' and 'jaccard' edge lengths.</p>
<h4 id="-highlightneighbors-boolean-">.highlightNeighbors([boolean])</h4>
<p>Whether to highlight neighboring edges when hovering over a node. Not completely working yet.
Default: false.</p>
<h4 id="-transitionduration-number-">.transitionDuration([number])</h4>
<p>Gets or sets the transition duration, the length of time each change to the diagram will be animated</p>
<p> .timeLimit([number])
Gets or sets the maximum time spent doing layout for a render or redraw. Set to 0 for now limit.
Default: 0</p>
<h4 id="-constrain-function-">.constrain([function])</h4>
<p>This function will be called with the current nodes and edges on each redraw in order to derive new
layout constraints. By default, no constraints will be added beyond those for edge lengths, but this
can be used to generate alignment (rank) or axis constraints. See
<a href="https://github.com/tgdwyer/WebCola/wiki/Constraints">the cola.js wiki</a> for more details. The constraints
are built from scratch on each redraw.</p>
<h4 id="-paralleledgeoffset-number-">.parallelEdgeOffset([number])</h4>
<p>If there are multiple edges between the same two nodes, start them this many pixels away from the original
so they don't overlap.
Default: 5</p>
<h4 id="-edgeordering-function-">.edgeOrdering([function])</h4>
<p>By default, edges are added to the layout in the order that <code>.edgeGroup().all()</code> returns them. If
specified, <code>.edgeOrdering</code> provides an accessor that returns a key to sort the edges on.
It would be better not to rely on ordering to affect layout, but it does matter. (Probably less
than node ordering, but it does affect which parallel edge is which.)</p>
<h4 id="-initlayoutonredraw-boolean-">.initLayoutOnRedraw([boolean])</h4>
<p>Currently there are some bugs when the same instance of cola.js is used multiple times. (In particular,
overlaps between nodes may not be eliminated [if cola is not reinitialized]
(<a href="https://github.com/tgdwyer/WebCola/issues/118">https://github.com/tgdwyer/WebCola/issues/118</a>)). This flag can be set true to construct a new cola
layout object on each redraw. However, layout seems to be more stable if this is set false, so hopefully
this will be fixed soon.</p>
<h4 id="-layoutunchanged-boolean-">.layoutUnchanged([boolean])</h4>
<p>Whether to perform layout when the data is unchanged from the last redraw. Default: false</p>
<h4 id="-relayout-">.relayout()</h4>
<p>When <code>layoutUnchanged</code> is false, call this when changing a parameter in order to force layout
to happen again. (Yes, probably should not be necessary.)</p>
<h4 id="-inducenodes-boolean-">.induceNodes([boolean])</h4>
<p>By default, all nodes are included, and edges are only included if both end-nodes are visible.
If <code>.induceNodes</code> is set, then only nodes which have at least one edge will be shown.</p>
<h4 id="-modlayout-function-">.modLayout([function])</h4>
<p>If it is desired to modify the cola layout object after it is created, this function can be called to add
a modifier function which takes the layout object.</p>
<h4 id="-showlayoutsteps-boolean-">.showLayoutSteps([boolean])</h4>
<p>If this flag is true, the positions of nodes and will be updated while layout is iterating. If false,
the positions will only be updated once layout has stabilized. Note: this may not be
compatible with transitionDuration. Default: false</p>
<h4 id="-legend-object-">.legend([object])</h4>
<p>Assigns a legend object which will be displayed within the same SVG element and according
to the visual encoding of this diagram.</p>
<h4 id="-child-string-object-">.child([string], [object])</h4>
<p>Specifies another kind of child, e.g. tooltip control.</p>
<h4 id="-handledisconnected-boolean-">.handleDisconnected([boolean])</h4>
<p>Instructs cola.js to fit the connected components. Default: false</p>
<h4 id="-redraw-">.redraw()</h4>
<p>Computes a new layout based on the nodes and edges in the edge groups, and displays the diagram.
To the extent possible, the diagram will minimize changes in positions from the previous layout.
<code>.render()</code> must be called the first time, and <code>.redraw()</code> can be called after that.</p>
<p><code>.redraw()</code> will be triggered by changes to the filters in any other charts in the same dc.js
chart group.</p>
<h4 id="-render-">.render()</h4>
<p>Erases any existing SVG elements and draws the diagram from scratch. <code>.render()</code> must be called
the first time, and <code>.redraw()</code> can be called after that.</p>
<h4 id="-on-">.on()</h4>
<p>Attaches an event handler to the diagram. Currently the only diagram event is <code>end</code>, signalling
that diagram layout has completed.</p>
<h4 id="-getstats-">.getStats()</h4>
<p>Returns an object with current statistics on graph layout.</p>
<ul>
<li><code>nnodes</code> - number of nodes displayed</li>
<li><code>nedges</code> - number of edges displayed</li>
</ul>
<h4 id="-select-selector-">.select(selector)</h4>
<p>Execute a d3 single selection in the diagram's scope using the given selector and return the d3
selection. Roughly the same as</p>
<pre><code class="lang-js">d3.select(<span class="hljs-string">'#diagram-id'</span>).select(selector)
</code></pre>
<p>Since this function returns a d3 selection, it is not chainable. (However, d3 selection calls can
be chained after it.)</p>
<h4 id="-selectall-selector-">.selectAll(selector)</h4>
<p>Selects all elements that match the d3 single selector in the diagram's scope, and return the d3
selection. Roughly the same as</p>
<pre><code class="lang-js">d3.select(<span class="hljs-string">'#diagram-id'</span>).selectAll(selector)
</code></pre>
<p>Since this function returns a d3 selection, it is not chainable. (However, d3 selection calls can
be chained after it.)</p>
<h4 id="-svg-svgelement-">.svg([svgElement])</h4>
<p>Returns the top svg element for this specific chart. You can also pass in a new svg element, but
setting the svg element on a diagram may have unexpected consequences.</p>
<h4 id="-resetsvg-">.resetSvg()</h4>
<p>Remove the diagram's SVG elements from the dom and recreate the container SVG element.</p>
<h4 id="-definearrow-name-width-height-refx-refy-drawf-">.defineArrow(name, width, height, refX, refY, drawf)</h4>
<p>Creates an svg marker definition for drawing edge arrow tails or heads.</p>
<ul>
<li><strong>name</strong> - the <code>id</code> to give the marker. When this identifier is returned by <code>.edgeArrowhead</code>
or <code>.edgeArrowtail</code>, that edge will be drawn with the specified marker for its source or target.</li>
<li><strong>width</strong> - the width, in pixels, to draw the marker</li>
<li><strong>height</strong> - the height, in pixels, to draw the marker</li>
<li><strong>refX</strong>, <strong>refY</strong> - the reference position, in marker coordinates, which will be aligned to the
endpoint of the edge</li>
<li><p><strong>drawf</strong> - a function to draw the marker using d3 SVG primitives, which takes the marker object as
its parameter. The <code>viewBox</code> of the marker is <code>0 -5 10 10</code>, so the arrow should be drawn from (0, -5)
to (10, 5) and it will be moved and sized based on the other parameter, and rotated based on the
orientation of the edge.</p>
<p>For example, the built-in <code>vee</code> arrow is defined so:</p>
<pre><code class="lang-js">_chart.defineArrow(<span class="hljs-string">'vee'</span>, <span class="hljs-number">12</span>, <span class="hljs-number">12</span>, <span class="hljs-number">10</span>, <span class="hljs-number">0</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(marker)</span> </span>{
marker.append(<span class="hljs-string">'svg:path'</span>)
.attr(<span class="hljs-string">'d'</span>, <span class="hljs-string">'M0,-5 L10,0 L0,5 L3,0'</span>)
.attr(<span class="hljs-string">'stroke-width'</span>, <span class="hljs-string">'0px'</span>);
});
(If further customization is required, it is possible to append other `svg:defs` to `chart.svg()`
and use refer to them by `id`.)
</code></pre>
</li>
</ul>
<h2 id="legend">Legend</h2>
<p>The dc_graph.legend will show labeled examples of nodes (and someday edges), within the frame of a dc_graph.diagram.</p>
<h4 id="-x-value-">.x([value])</h4>
<p>Set or get x coordinate for legend widget. Default: 0.</p>
<h4 id="-y-value-">.y([value])</h4>
<p>Set or get y coordinate for legend widget. Default: 0.</p>
<h4 id="-gap-value-">.gap([value])</h4>
<p>Set or get gap between legend items. Default: 5.</p>
<h4 id="-nodewidth-value-">.nodeWidth([value])</h4>
<p>Set or get legend node width. Default: 30.</p>
<h4 id="-nodeheight-value-">.nodeHeight([value])</h4>
<p>Set or get legend node height. Default: 30.</p>
<h4 id="-exemplars-object-">.exemplars([object])</h4>
<p>Specifies an object where the keys are the names of items to add to the legend, and the values are
objects which will be passed to the accessors of the attached diagram in order to determine the
drawing attributes. Alternately, if the key needs to be specified separately from the name, the
function can take an array of {name, key, value} objects.</p>
<h4 id="-parent-object-">.parent([object])</h4>
<p>Assigns this tip object to a diagram. It will show tips for nodes in that diagram.</p>
<h4 id="-content-function-">.content([function])</h4>
<p>Specifies the function to generate content for the tooltip. This function has
the signature <code>function(d, k)</code>, where <code>d</code> is the datum of the node being hovered over,
and <code>k</code> is a continuation. The function should fetch the content, asynchronously
if needed, and then pass it forward to <code>k</code>.</p>
</body>
</html>