UNPKG

44.2 kBMarkdownView Raw
1# d3-graphviz
2
3Renders SVG from graphs described in the [DOT](https://www.graphviz.org/doc/info/lang.html) language using the [Viz.js](https://github.com/mdaines/viz.js/) port of [Graphviz](http://www.graphviz.org) and does animated transitions between graphs.
4
5[![Build Status](https://travis-ci.org/magjac/d3-graphviz.svg?branch=master)](https://travis-ci.org/magjac/d3-graphviz)
6[![codecov](https://codecov.io/gh/magjac/d3-graphviz/branch/master/graph/badge.svg)](https://codecov.io/gh/magjac/d3-graphviz)
7[![npm version](https://img.shields.io/npm/v/d3-graphviz.svg?style=flat)](https://www.npmjs.com/package/d3-graphviz)
8[![unpkg](http://img.badgesize.io/https://unpkg.com/d3-graphviz/build/d3-graphviz.js?compression=gzip&label=unpkg&style=flat&cache=false)](https://unpkg.com/d3-graphviz/build/d3-graphviz.js)
9[![unpkg min](http://img.badgesize.io/https://unpkg.com/d3-graphviz/build/d3-graphviz.min.js?compression=gzip&label=unpkg%20min&style=flat&cache=false)](https://unpkg.com/d3-graphviz/build/d3-graphviz.min.js)
10<a href="https://join.slack.com/t/d3-graphviz/shared_invite/enQtMzMwODQzMDI5MDA5LTExYTgyYThhNzI3YjJlODRiMzQ3MWM3YWI5ZjAyMTI2MmI4YWIwMDM4ZmY5MDQzNjkzMDY4YTRmMTU1YzIzNTY"><img src="images/slack_rgb_cropped.png" height="20px"></a>
11
12## Features
13* Rendering of SVG graphs from [DOT](https://www.graphviz.org/doc/info/lang.html) source
14* Animated transition of one graph into another
15* Edge path tweening
16* Node shape tweening
17* Fade-in and fade-out of entering and exiting nodes and edges
18* Animated growth of entering edges
19* Panning & zooming of the generated graph
20
21Graphviz methods typically return the graphviz renderer instance, allowing the concise application of multiple operations on a given graph renderer instance via method chaining.
22
23To render a graph, select an element, call [*selection*.graphviz](#selection_graphviz), and then render from a [DOT](https://www.graphviz.org/doc/info/lang.html) source string. For example:
24
25```js
26d3.select("#graph")
27 .graphviz()
28 .renderDot('digraph {a -> b}');
29```
30
31It is also possible to call [d3.graphviz](#d3_graphviz) with a selector as the argument like so:
32
33```js
34d3.graphviz("#graph")
35 .renderDot('digraph {a -> b}');
36```
37
38[<img src="images/a-b.png">](http://bl.ocks.org/magjac/a23d1f1405c2334f288a9cca4c0ef05b)
39
40This basic example can also bee seen [here](http://bl.ocks.org/magjac/a23d1f1405c2334f288a9cca4c0ef05b).
41
42A more colorful demo can be seen [here](http://bl.ocks.org/magjac/4acffdb3afbc4f71b448a210b5060bca).
43
44## Installing
45
46If you use NPM, `npm install d3-graphviz`. Otherwise, download the [latest release](https://github.com/magjac/d3-graphviz/releases/latest).
47
48## Principles of Operation
49
50Uses [Viz.js](https://github.com/mdaines/viz.js/) to do a layout of a graph specified in the [DOT](https://www.graphviz.org/doc/info/lang.html) language and generates an SVG text representation, which is analyzed and converted into a data representation. Then [D3](https://d3js.org/) is used to join this data with a selected DOM element, render the SVG graph on that element and to animate transitioning of one graph into another.
51
52## Contents
53
54* [API Reference](#api-reference)
55* [Examples](#examples)
56* [Building Applications with d3-graphviz](#building-applications-with-d3-graphviz)
57* [Data Format](#data-format)
58* [Performance](#performance)
59* [Requirements](#requirements)
60* [Support](#support)
61* [Development](#development)
62* [Credits](#credits)
63
64## API Reference
65
66* [Defining the viz.js Script Tag](#defining-the-vizjs-script-tag)
67* [Creating a Graphviz Renderer](#creating-a-graphviz-renderer)
68* [Setting and Getting Options](#setting-and-getting-options)
69* [Rendering](#rendering)
70* [Images](#images)
71* [Creating Transitions](#creating-transitions)
72* [Control Flow](#control-flow)
73* [Controlling Fade-In & Fade-Out](#controlling-fade-in--fade-out)
74* [Controlling Animated Growth of Entering Edges](#controlling-animated-growth-of-entering-edges)
75* [Controlling Path Tweening](#controlling-path-tweening)
76* [Controlling Shape Tweening](#controlling-shape-tweening)
77* [Maintaining Object Constancy](#maintaining-object-constancy)
78* [Customizing Graph Attributes](#customizing-graph-attributes)
79* [Accessing Elements of the Generated Graph](#accessing-elements-of-the-generated-graph)
80* [Modifying an Existing Graph and Animating the Changes](#modifying-an-existing-graph-and-animating-the-changes)
81* [Large Graphs](#large-graphs)
82
83### Defining the viz.js Script Tag
84
85The "viz.js" script provides a function named *Viz*. If a web worker is used, this function is called from the web worker which then loads and compiles the "viz.js" script explicitly. In this case, it's unneccesary to let the browser also load and compile the script. This is accomplished by using the script tag "javascript/worker" which the browser does not identify to be Javascript and therefore does not compile. However, there is one d3-graphviz function, [*drawNode*](#graphviz_drawNode) that calls the the *Viz* function directly and if it is going to be used, the script type must be "application/javascript" or "text/javascript".
86
87Examples:
88
89`<script src="https://unpkg.com/viz.js@1.8.1/viz.js" type="application/javascript/"></script>`
90
91This will always work, but will not be optimal if the script is used in a web worker only.
92
93`<script src="https://unpkg.com/viz.js@1.8.1/viz.js" type="javascript/worker"></script>`
94
95This will work if a web worker is used and the [*drawNode*](#graphviz_drawNode) is not used and will give shorter page load time.
96
97The following table summarizes the recommended script type:
98
99| | *useWorker* = true (default) | *useWorker* = false |
100|---------------------------------|------------------------------|------------------------|
101| <b>*drawNode()* is not used</b> | javascript/worker | application/javascript |
102| <b>*drawNode()* is used</b> | application/javascript | application/javascript |
103
104### Creating a Graphviz Renderer
105
106#### Creating a Graphviz Renderer on an Existing Selection
107
108<a name="selection_graphviz" href="#selection_graphviz">#</a> <i>selection</i>.<b>graphviz</b>([<i>options</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/selection/graphviz.js "Source")
109
110Returns a new graphviz renderer instance on the first element in the given *selection*. If a graphviz renderer instance already exists on that element, instead returns the existing graphviz renderer instance. If *options* is specified and is an object, its properties are taken to be options to the graphviz renderer. All options except the *useWorker* option can also be changed later, using individual methods or the [<i>graphviz</i>.<b>options</b>](#graphviz_options) method, see below. The currently supported options are:
111
112| Option | Default value |
113|--------|---------------|
114| [convertEqualSidedPolygons](#graphviz_convertEqualSidedPolygons) | true |
115| [engine](#graphviz_engine) | 'dot' |
116| [fade](#graphviz_fade) | true |
117| [fit](#graphviz_scale) | false |
118| [growEnteringEdges](#graphviz_growEnteringEdges) | true |
119| [height](#graphviz_height) | null |
120| [keyMode](#graphviz_keyMode) | 'title' |
121| [totalMemory](#graphviz_totalMemory) | undefined (giving [Viz.js](https://github.com/mdaines/viz.js/) default) |
122| [scale](#graphviz_scale) | 1 |
123| [tweenPaths](#graphviz_tweenPaths) | true |
124| [tweenPrecision](#graphviz_tweenPrecision) | 1 |
125| [tweenShapes](#graphviz_tweenShapes) | true |
126| useWorker¹ | true |
127| [width](#graphviz_width) | null |
128| [zoom](#graphviz_zoom) | true |
129
130¹ Only has effect when the graphviz renderer instance is created.
131
132If the *useWorker* option is falsey, no web worker is used for the layout stage. The rest of the options are described below. Only the specified options will be changed. The others will keep their current values. If *options* is a boolean it is taken to be the useWorker option (for backwards compatibility).
133
134#### Creating a Graphviz Renderer Using a Selector String or a Node
135
136<a name="d3_graphviz" href="#d3_graphviz">#</a> <b>d3.graphviz</b>(<i>selector</i>[, <i>options</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/graphviz.js "Source")
137
138Creates a new graphviz renderer instance on the first element matching the given *selector* string. If the *selector* is not a string, instead creates a new graphviz renderer instance on the specified node. If a graphviz renderer instance already exists on that element, instead returns the existing graphviz renderer instance. See [<i>selection</i>.<b>graphviz</b>](#selection_graphviz) for a description of the *options* argument.
139
140### Setting and Getting Options
141
142<a name="graphviz_options" href="#graphviz_options">#</a> <i>graphviz</i>.<b>options</b>([<i>options</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/options.js "Source")
143
144If *options* is specified it is taken to be an object whose properties are used to set options to the graphviz renderer. See [<i>selection</i>.<b>graphviz</b>](#selection_graphviz) for a list of supported options. Most options can also be changed by individual methods which are described separately. If *options* is not specified, a copy of the currently set options are returned as an object.
145
146### Rendering
147
148<a name="graphviz_renderDot" href="#graphviz_renderDot">#</a> <i>graphviz</i>.<b>renderDot</b>(<i>dotSrc</i>[, <i>callback</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/renderDot.js "Source")
149
150Starts rendering of an SVG graph from the specified *dotSrc* string and appends it to the selection the grapviz renderer instance was generated on. [<i>graphviz</i>.<b>renderDot</b>](#graphviz_renderDot) returns "immediately", while the rendering is performed in the backgound. The layout stage is performed by a web worker (unless the use of a web worker was disabled when the renderer instance was created).
151
152It is also possible to do the [Graphviz](https://www.graphviz.org/doc/info/lang.html) layout in a first separate stage and do the actual rendering of the SVG as a second step like so:
153
154```js
155d3.select("#graph")
156 .graphviz()
157 .dot('digraph {a -> b}')
158 .render();
159```
160
161This enables doing the computational intensive layout stages for multiple graphs before doing the potentially synchronized rendering of all the graphs simultaneously.
162
163<a name="graphviz_dot" href="#graphviz_dot">#</a> <i>graphviz</i>.<b>dot</b>(<i>dotSrc</i>[, <i>callback</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/dot.js "Source")
164
165Starts computation of the layout of a graph from the specified *dotSrc* string and saves the data for rendering the SVG with [<i>graphviz</i>.<b>render</b>](#graphviz_render) at a later stage. [<i>graphviz</i>.<b>dot</b>](#graphviz_dot) returns "immediately", while the layout is performed by a web worker in the backgound. If *callback* is specified and not null, it is called with the `this` context as the graphviz instance, when the layout, data extraction and data processing has been finished.
166
167<a name="graphviz_render" href="#graphviz_render">#</a> <i>graphviz</i>.<b>render</b>([<i>callback</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/dot.js "Source")
168
169Starts rendering of an SVG graph from data saved by [<i>graphviz</i>.<b>dot</b>](#graphviz_dot) and appends it to the selection the grapviz renderer instance was generated on. [<i>graphviz</i>.<b>render</b>](#graphviz_render) returns "immediately", while the rendering is performed in the backgound. If computation of a layout, started with the [<i>graphviz</i>.<b>dot</b>](#graphviz_dot) method has not yet finsihed, the rendering task is placed in a queue and will commence when the layout is ready. If *callback* is specified and not null, it is called with the `this` context as the graphviz instance, when the graphviz renderer has finished all actions.
170
171<a name="graphviz_engine" href="#graphviz_engine">#</a> <i>graphviz</i>.<b>engine</b>(<i>engine</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/engine.js "Source")
172
173Sets the [Graphviz](http://www.graphviz.org) layout engine name to the specified *engine* string. The engine name must be set before attaching the [DOT](https://www.graphviz.org/doc/info/lang.html) source. If it is changed after this, an eror is thrown. Supports all engines that [Viz.js](https://github.com/mdaines/viz.js/) supports. Currently these are:
174
175* <b>circo</b>
176* <b>dot</b> (default)
177* <b>fdp</b>
178* <b>neato</b> (not supported with [viz-lite.js](https://github.com/mdaines/viz.js#lite-version))
179* <b>osage</b>
180* <b>patchwork</b>
181* <b>twopi</b>
182
183<b>sfdp</b> is currently not supported.
184
185<a name="graphviz_onerror" href="#graphviz_onerror">#</a> <i>graphviz</i>.<b>onerror</b>(<i>callback</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/onerror.js "Source")
186
187If *callback* is specified and not null, it is called with the `this` context as the graphviz instance and the error message as the first argument, if the layout computation encounters an error. If *callback* is null, removes any previously registered callback.
188
189### Images
190<a name="graphviz_addImage" href="#graphviz_images">#</a> <i>graphviz</i>.<b>addImage</b>(<i>path</i>,<i>width</i>,<i>height</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/images.js "Source")
191
192Add image references as dictated by viz.js, **must be done before renderDot() or dot()**.
193addImage can be called multiple times.
194
195*path* may be a filename ("example.png"), relative or absolute path ("/images/example.png"), or a URL ("http://example.com/image.png")
196Dimensions(*width*,*height*) may be specified with units: in, px, pc, pt, cm, or mm. If no units are given or dimensions are given as numbers, points (pt) are used.
197
198Graphviz does not actually load image data when this option is used — images are referenced with the dimensions given, e.g. in SVG by an \<image> element with width and height attributes.
199
200```js
201d3.graphviz("#graph")
202 .addImage("images/first.png", "400px", "300px")
203 .addImage("images/second.png", "400px", "300px")
204 .renderDot('digraph { a[image="images/first.png"]; b[image="images/second.png"]; a -> b }');
205```
206
207### Creating Transitions
208<a name="graphviz_transition" href="#graphviz_transition">#</a> <i>graphviz</i>.<b>transition</b>([<i>name</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/transition.js "Source")
209
210Applies the specified transition *name* to subsequent SVG rendering. Accepts the same arguments as [<i>selection</i>.<b>transition</b>](https://github.com/d3/d3-transition#selection_transition) or a function, but returns the graph renderer instance, not the transition. If *name* is a function, it is taken to be a transition factory. A transition factory is a function that returns a transition; when the rendering starts, the factory is evaluated once, with the `this` context as the graphviz instance. To attach a preconfigured transition, first create a transition intance with [d3.transition](https://github.com/d3/d3-transition#transition), configure it and attach it with [<i>graphviz</i>.<b>transition</b>](#graphviz_transition) like so:
211
212```js
213var t = d3.transition()
214 .duration(750)
215 .ease(d3.easeLinear);
216
217d3.select("#graph").graphviz()
218 .transition(t)
219 .renderDot('digraph {a -> b}');
220```
221
222A transition is scheduled when it is created. The above example will schedule the transition *before* the layout is computed, i.e. synchronously. But if, instead, a transition factory is used, the transition will be scheduled *after* the layout is computed, i.e. asynchronously.
223
224<b>NOTE:</b> Transitions should be named if zooming is enabled. Transitions using the null name [will be interrupted](https://github.com/d3/d3-zoom/issues/110) by the [zoom behavior](https://github.com/d3/d3-zoom), causing the graph to be rendered incorrectly.
225
226<a name="graphviz_active" href="#graphviz_active">#</a> <i>graphviz</i>.<b>active</b>([<i>name</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/transition.js "Source")
227
228Returns the active transition on the generated graph's top level <b>svg</b> with the specified *name*, if any. If no *name* is specified, null is used. Returns null if there is no such active transition on the top level <b>svg</b> node. This method is useful for creating chained transitions.
229
230### Controlling SVG Size and Graph Size
231
232The SVG size determines the area in which the graph can be panned and zoomed, while the graph size determines the area that the graph occupies before it is panned or zoomed. The default is that these two areas are the same.
233
234The size of the graph is determined in three optional steps:
235
2361. The SVG size can be set with [<i>graphviz</i>.<b>width</b>](#graphviz_width) and/or [<i>graphviz</i>.<b>height</b>](#graphviz_height).
2372. The graph can be scaled to fit the SVG size with [<i>graphviz</i>.<b>fit</b>](#graphviz_fit) or maintain its original size.
2383. The graph can be additionally scaled with a scaling factor with [<i>graphviz</i>.<b>scale</b>](#graphviz_scale).
239
240<a name="graphviz_width" href="#graphviz_width">#</a> <i>graphviz</i>.<b>width</b>(<i>width</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/width.js "Source")
241
242The SVG width attribute is set to *width* pixels.
243
244<a name="graphviz_height" href="#graphviz_height">#</a> <i>graphviz</i>.<b>height</b>(<i>height</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/height.js "Source")
245
246The SVG height attribute is set to *height* pixels.
247
248<a name="graphviz_fit" href="#graphviz_fit">#</a> <i>graphviz</i>.<b>fit</b>(<i>fit</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/height.js "Source")
249
250If *fit* is falsey (default), the viewBox attribute of the SVG is set so that the graph size (before scaling with [<i>graphviz</i>.<b>scale</b>](#graphviz_scale)) is its orignal size, i.e. unaffected by a possible SVG size change with [<i>graphviz</i>.<b>width</b>](#graphviz_width) or [<i>graphviz</i>.<b>height</b>](#graphviz_height). If *fit* is truthy, the viewBox attribute of the SVG is unchanged, which causes the graph size (before scaling with [<i>graphviz</i>.<b>scale</b>](#graphviz_scale)) to fit the SVG size. Note that unless the SVG size has been changed, this options has no effect.
251
252<a name="graphviz_scale" href="#graphviz_scale">#</a> <i>graphviz</i>.<b>scale</b>(<i>scale</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/height.js "Source")
253
254The viewBox attribute of the SVG is set so that the graph size (after a possible fit to the SVG size with [<i>graphviz</i>.<b>fit</b>](#graphviz_fit)) is scaled with *scale*. For example: If *scale* is 0.5, then if *fit* is truthy, the graph width and height is half the width and height of the SVG, while if *fit* is falsey, the graph width and height is half of its original width and height.
255
256### Control Flow
257
258For advanced usage, the grahviz renderer provides methods for custom control flow.
259
260<a name="graphviz_on" href="#graphviz_on">#</a> <i>graphviz</i>.<b>on</b>(<i>typenames</i>[, <i>listener</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/on.js "Source")
261
262Adds or removes a *listener* to the graphviz renderer instance for the specified event *typenames*. The *typenames* is one of the following string event types:
263
264* `initEnd` - when the graphviz renderer has finished initialization.¹
265* `start` - when analysis of the DOT source starts.
266* `layoutStart` - when the layout of the DOT source starts.
267* `layoutEnd` - when the layout of the DOT source ends.
268* `dataExtractEnd` - when the extraction of data from the SVG text representation ends.
269* `dataProcessPass1End` - when the first pass of the processing of the extracted data ends.
270* `dataProcessPass2End` - when the second pass of the processing of the extracted data ends.
271* `dataProcessEnd` - when the processing of the extracted data ends.
272* `renderStart` - when the rendering preparation starts, which is just before an eventual transition factory is called.
273* `renderEnd` - when the rendering preparation ends.
274* `transitionStart` - when the anmiated transition starts.
275* `transitionEnd` - when the anmiated transition ends.
276* `restoreEnd` - when possibly converted paths and shapes have been restored after the transition.
277* `end` - when the graphviz renderer has finished all actions.
278
279¹ If a web worker is not used, this event is issued before [d3.graphviz](#d3_graphviz) or [<i>selection</i>.<b>graphviz</b>](#selection_graphviz) returns which means that a *listener* registered with a subsequent [<i>graphviz</i>.<b>on</b>](#graphviz_on) will not be called since it's registered too late.
280
281Note that these are *not* native DOM events as implemented by [*selection*.on](https://github.com/d3/d3-selection#selection_on) and [*selection*.dispatch](https://github.com/d3/d3-selection#selection_dispatch), but graphviz events!
282
283The type may be optionally followed by a period (`.`) and a name; the optional name allows multiple callbacks to be registered to receive events of the same type, such as `start.foo` and `start.bar`. To specify multiple typenames, separate typenames with spaces, such as `interrupt end` or `start.foo start.bar`.
284
285When a specified graphviz event is dispatched, the specified *listener* will be invoked with the `this` context as the graphviz instance.
286
287If an event listener was previously registered for the same *typename* on a selected element, the old listener is removed before the new listener is added. To remove a listener, pass null as the *listener*. To remove all listeners for a given name, pass null as the *listener* and `.foo` as the *typename*, where `foo` is the name; to remove all listeners with no name, specify `.` as the *typename*.
288
289<a name="graphviz_logEvents" href="#graphviz_logEvents">#</a> <i>graphviz</i>.<b>logEvents</b>(<i>enable</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/logEvents.js "Source")
290
291If *enable* is true (default), adds event listeners, uing the name "log", for all available events. When invoked, each listener will print a one-line summary containing the event number and type, the time since the previous event and the time since the "start" event to the console log. For some events, additionally calculated times are printed. This method can be used for debugging or for tuning transition delay and duration. If *enable* is false, removes all event listeners named "log".
292
293### Controlling Fade-In & Fade-Out
294
295<a name="graphviz_fade" href="#graphviz_fade">#</a> <i>graphviz</i>.<b>fade</b>(<i>enable</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/fade.js "Source")
296
297If *enable* is true (default), enables fade-in and fade-out of nodes and shapes, else disables fade-in and fade-out.
298
299### Controlling Animated Growth of Entering Edges
300
301<a name="graphviz_growEnteringEdges" href="#graphviz_growEnteringEdges">#</a> <i>graphviz</i>.<b>growEnteringEdges</b>(<i>enable</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/growEnteringEdges.js "Source")
302
303If *enable* is true (default), enables animated growth of entering edges, else disables animated growth of entering edges.
304
305A demo of animated growth of entering edges can be seen [here](http://bl.ocks.org/magjac/f485e7b915c9699aa181a11e183f8237)
306
307### Controlling Path Tweening
308
309<a name="graphviz_tweenPaths" href="#graphviz_tweenPaths">#</a> <i>graphviz</i>.<b>tweenPaths</b>(<i>enable</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/tweenPaths.js "Source")
310
311If *enable* is true (default), enables path tweening, else disables path tweening.
312
313<a name="graphviz_tweenPrecision" href="#graphviz_tweenPrecision">#</a> <i>graphviz</i>.<b>tweenPrecision</b>(<i>precision</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/tweenPrecision.js "Source")
314
315Sets the precision used during path tweening to *precision* pixels. Default is 1.
316
317### Controlling Shape Tweening
318
319<a name="graphviz_tweenShapes" href="#graphviz_tweenShapes">#</a> <i>graphviz</i>.<b>tweenShapes</b>(<i>enable</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/tweenShapes.js "Source")
320
321If *enable* is true (default), enables shape tweening during transitions, else disables shape tweening. If *enable* is true, also enables path tweening since shape tweening currently is performed by converting SVG ellipses and polygons to SVG paths and do path tweening on them. At the end of the transition the original SVG shape element is restored.
322
323<a name="graphviz_convertEqualSidedPolygons" href="#graphviz_convertEqualSidedPolygons">#</a> <i>graphviz</i>.<b>convertEqualSidedPolygons</b>(<i>enable</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/convertEqualSidedPolygons.js "Source")
324
325If *enable* is true (default), enables conversion of polygons with equal number of sides during shape tweening, else disables conversion. Not applicable when shape tweening is disabled. At the end of the transition the original SVG shape element is restored.
326
327A demo of shape tweening can be seen [here](http://bl.ocks.org/magjac/69dc955a2e2ee085f60369c4a73f92a6).
328
329### Controlling Panning & Zooming
330
331<a name="graphviz_zoom" href="#graphviz_zoom">#</a> <i>graphviz</i>.<b>zoom</b>(<i>enable</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/zoom.js "Source")
332
333If *enable* is true (default), enables panning and zooming, else disables panning and zooming. The zoom behavior is applied to the graph's top level <b>svg</b> element.
334
335<a name="graphviz_resetZoom" href="#graphviz_resetZoom">#</a> <i>graphviz</i>.<b>resetZoom</b>([<i>transition</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/zoom.js "Source")
336
337Restores the original graph by resetting the transformation made by panning and zooming. If *transition* is specified and not null, it is taken to be a transition instance which is applied during zoom reset.
338
339### Maintaining [Object Constancy](https://bost.ocks.org/mike/constancy/)
340
341In order to acheive [meaningful transitions](https://bost.ocks.org/mike/constancy/#when-constancy-matter), the D3 default join-by-index [key function](https://bost.ocks.org/mike/constancy/#key-functions) is not sufficient. Four different key modes are available that may be useful in different situations:
342
343* <b>title</b> (default) - Uses the text of the SVG title element for each node and edge <b>g</b> element as generated by [Graphviz](http://www.graphviz.org). For nodes, this is "[<i>node_id</i>](https://www.graphviz.org/doc/info/lang.html)" (not to be confused with the node attribute [<i>id</i>](http://www.graphviz.org/content/attrs#did)) and for edges it is "[<i>node_id</i>](https://www.graphviz.org/doc/info/lang.html) [<i>edgeop</i>](https://www.graphviz.org/doc/info/lang.html) [<i>node_id</i>](https://www.graphviz.org/doc/info/lang.html)", e.g. "a -> b". For node and edge sub-elements, the <b>tag-index</b> key mode is used, see below.
344* <b>id</b> - Uses the <b>id</b> attribute of the node and edge SVG <b>g</b> elements as generated by [Graphviz](http://www.graphviz.org). Note that unless the graph author specifies [<i>id</i>](http://www.graphviz.org/content/attrs#did) attributes for nodes and edges, [Graphviz](http://www.graphviz.org) generates a unique internal id that is unpredictable by the graph writer, making the <b>id</b> key mode not very useful. For node and edge sub-elements, the <b>tag-index</b> key mode is used, see below.
345* <b>tag-index</b> - Uses a key composed of the [SVG element](https://www.w3.org/TR/SVG/eltindex.html) tag, followed by a dash (-) and the relative index of that element within all sibling elements with the same tag. For example: ellipse-0. Normally not very useful for other than static graphs, since all nodes and edges are siblings and are generated as SVG <b>g</b> elements.
346* <b>index</b> - Uses the D3 default join-by-index key function. Not useful for other than static graphs.
347
348<a name="graphviz_keyMode" href="#graphviz_keyMode">#</a> <i>graphviz</i>.<b>keyMode</b>(<i>mode</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/keyMode.js "Source")
349
350Sets the key mode to the specified *mode* string. If *mode* is not one of the defined key modes above, an error is thrown. The key mode must be set before attaching the [DOT](https://www.graphviz.org/doc/info/lang.html) source. If it is changed after this, an eror is thrown.
351
352### Customizing Graph Attributes
353
354<a name="graphviz_attributer" href="#graphviz_attributer">#</a> <i>graphviz</i>.<b>attributer</b>(<i>function</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/attributer.js "Source")
355
356If the *function* is a function, it is evaluated for each SVG element, before applying attributes and transitions, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). If *function* is null, removes the attributer. For example, to set the fill color of ellipses to yellow and fade to red during transition:
357
358
359```js
360var t = d3.transition()
361 .duration(2000)
362 .ease(d3.easeLinear);
363
364d3.select("#graph").graphviz()
365 .transition(t)
366 .attributer(function(d) {
367 if (d.tag == "ellipse") {
368 d3.select(this)
369 .attr("fill", "yellow");
370 d.attributes.fill = "red";
371 }
372 })
373 .renderDot('digraph {a -> b}');
374```
375
376### Accessing Elements of the Generated Graph
377
378<a name="selection_selectWithoutDataPropagation" href="#selection_selectWithoutDataPropagation">#</a> <i>selection</i>.<b>selectWithoutDataPropagation</b>() [<>](https://github.com/magjac/d3-graphviz/blob/master/src/selection/selectWithoutDataPropagation.js "Source")
379
380For each selected element, selects the first descendant element that matches the specified selector string in the same ways as [*selection*.select](https://github.com/d3/d3-selection#selection_select), but does *not* propagate any associated data from the current element to the corresponding selected element.
381
382### Modifying an Existing Graph and Animating the Changes
383
384This API provides methods draw nodes and edges and inserting them into the graph data. The application can then animate the changes made by providing and updated DOT source and render a new layout. The API also supports removing nodes and edge from the graph and the graph data.
385
386<a name="graphviz_drawEdge" href="#graphviz_drawEdge">#</a> <i>graphviz</i>.<b>drawEdge</b>(<i>x1</i>, <i>y1</i>, <i> x2</i>, <i> y2</i>[, <i> attributes</i>][, <i> options</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/drawEdge.js "Source")
387
388Draws a straight edge from (*x1*, *y1*) to (*x2*, *y2*) using coordinates relative to top level [G container element](https://www.w3.org/TR/SVG/struct.html#Groups) of the graph. Typically these coordinates are obtained with [d3.mouse](https://github.com/d3/d3-selection#mouse). If *attributes* is specified, it is taken to be an object containing [DOT attributes](https://www.graphviz.org/doc/info/attrs.html) as properties to be used when drawing the node. If not specified, the default values of those attributes are used. If *options* is specified, it is taken to be an object containing properties which are used as options when drawing the edge. The currently supported options are:
389
390* <b>shortening</b> - The number of points by which to draw the edge shorter than given by the coordinates. This is useful to avoid that the currently drawn edge is prohibiting mouse events on elements beneath the current mouse position. A typical such value is 2. The default value is 0.
391
392<a name="graphviz_updateDrawnEdge" href="#graphviz_updateDrawnEdge">#</a> <i>graphviz</i>.<b>updateDrawnEdge</b>(<i>x1</i>, <i>y1</i>, <i> x2</i>, <i> y2</i>[, <i> attributes</i>][, <i> options</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/drawEdge.js "Source")
393
394Updates properties and attributes of the edge currently drawn with [<i>graphviz</i>.<b>drawEdge</b>](#graphviz_drawEdge), using the same arguments. This method cannot be used after the edge has been inserted into the graph data with [<i>graphviz</i>.<b>insertDrawnEdge</b>](#graphviz_insertDrawnEdge).
395
396<a name="graphviz_moveDrawnEdgeEndPoint" href="#graphviz_moveDrawnEdgeEndPoint">#</a> <i>graphviz</i>.<b>moveDrawnEdgeEndPoint</b>(<i> x2</i>, <i> y2</i>[, <i> options</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/drawEdge.js "Source")
397
398Updates the end point of the edge currently drawn with [<i>graphviz</i>.<b>drawEdge</b>](#graphviz_drawEdge), accepting the same *options* argument. This method cannot be used after the edge has been inserted into the graph data with [<i>graphviz</i>.<b>insertDrawnEdge</b>](#graphviz_insertDrawnEdge).
399
400<a name="graphviz_insertDrawnEdge" href="#graphviz_insertDrawnEdge">#</a> <i>graphviz</i>.<b>insertDrawnEdge</b>(<i>name</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/drawEdge.js "Source")
401
402Inserts the edge into the graph data, making it available for an animated transition into a subsequent new layout perfomed with [<i>graphviz</i>.<b>render</b>](#graphviz_render) or [<i>graphviz</i>.<b>renderDot</b>](#graphviz_renderDot). *name* is typically [<i>node_id</i>](https://www.graphviz.org/doc/info/lang.html) [<i>edgeop</i>](https://www.graphviz.org/doc/info/lang.html) [<i>node_id</i>](https://www.graphviz.org/doc/info/lang.html) according to the [DOT language](https://www.graphviz.org/doc/info/lang.html), e.g. "a -> b".
403
404<a name="graphviz_removeDrawnEdge" href="#graphviz_removeDrawnEdge">#</a> <i>graphviz</i>.<b>removeDrawnEdge</b>() [<>](https://github.com/magjac/d3-graphviz/blob/master/src/drawEdge.js "Source")
405
406Removes the edge currently drawn with [<i>graphviz</i>.<b>drawEdge</b>](#graphviz_drawEdge). This method cannot be used after the edge has been inserted into the graph data with [<i>graphviz</i>.<b>insertDrawnEdge</b>](#graphviz_insertDrawnEdge).
407
408<a name="graphviz_drawNode" href="#graphviz_drawNode">#</a> <i>graphviz</i>.<b>drawNode</b>(<i>x</i>, <i>y</i>, <i>nodeId</i>[, <i> attributes</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/drawNode.js "Source")
409
410Draws a node with the upper left corner of its bounding box at (*x*, *y*), using coordinates relative to the top level [G container element](https://www.w3.org/TR/SVG/struct.html#Groups) of the graph. Typically these coordinates are obtained with [d3.mouse](https://github.com/d3/d3-selection#mouse). *nodeId* is the [<i>node_id</i>](https://www.graphviz.org/doc/info/lang.html) according to the [DOT language](https://www.graphviz.org/doc/info/lang.html). If *attributes* is specified, it is taken to be an object containing [DOT attributes](https://www.graphviz.org/doc/info/attrs.html) as properties to be used when drawing the node. If not specified, the default values of those attributes are used.
411
412<b>NOTE:</b> User-defined shapes are not supported.
413
414<a name="graphviz_updateDrawnNode" href="#graphviz_updateDrawnNode">#</a> <i>graphviz</i>.<b>updateDrawnNode</b>(<i>x</i>, <i>y</i>, <i>nodeId</i>[, <i> attributes</i>]) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/drawNode.js "Source")
415
416Updates properties and attributes of the node currently drawn with [<i>graphviz</i>.<b>drawNode</b>](#graphviz_drawNode), using the same arguments. This method cannot be used after the node has been inserted into the graph data with [<i>graphviz</i>.<b>insertDrawnNode</b>](#graphviz_insertDrawnNode).
417
418<a name="graphviz_insertDrawnNode" href="#graphviz_insertDrawnNode">#</a> <i>graphviz</i>.<b>insertDrawnNode</b>(<i>nodeId</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/drawNode.js "Source")
419
420Inserts the node into the graph data, making it available for an animated transition into a subsequent new layout perfomed with [<i>graphviz</i>.<b>render</b>](#graphviz_render) or [<i>graphviz</i>.<b>renderDot</b>](#graphviz_renderDot). *nodeId* is the [<i>node_id</i>](https://www.graphviz.org/doc/info/lang.html) according to the [DOT language](https://www.graphviz.org/doc/info/lang.html).
421
422<a name="graphviz_removeDrawnNode" href="#graphviz_removeDrawnNode">#</a> <i>graphviz</i>.<b>removeDrawnNode</b>() [<>](https://github.com/magjac/d3-graphviz/blob/master/src/drawNode.js "Source")
423
424Removes the node currently drawn with [<i>graphviz</i>.<b>drawNode</b>](#graphviz_drawNode). This method cannot be used after the node has been inserted into the graph data with [<i>graphviz</i>.<b>insertDrawnNode</b>](#graphviz_insertDrawnNode).
425
426### Large Graphs
427
428For very large graphs it might be necessary to increase the amount of memory available to [Viz.js](https://github.com/mdaines/viz.js/).
429
430<a name="graphviz_totalMemory" href="#graphviz_totalMemory">#</a> <i>graphviz</i>.<b>totalMemory</b>(<i>size</i>) [<>](https://github.com/magjac/d3-graphviz/blob/master/src/totalMemory.js "Source")
431
432Sets the total memory available to [Viz.js](https://github.com/mdaines/viz.js/) to *size* bytes, which should be a power of 2. See the [Viz.js API](https://github.com/mdaines/viz.js#vizsrc-options-formatsvg-enginedot-scale-images-path-width-height--totalmemory16777216-) for details.
433
434## Examples
435
436* [Basic Example](http://bl.ocks.org/magjac/a23d1f1405c2334f288a9cca4c0ef05b)
437* [Demo](http://bl.ocks.org/magjac/4acffdb3afbc4f71b448a210b5060bca)
438* [Shape Tweening Demo](http://bl.ocks.org/magjac/69dc955a2e2ee085f60369c4a73f92a6)
439* [Delete Nodes and Edge Demo Application](https://bl.ocks.org/magjac/28a70231e2c9dddb84b3b20f450a215f)
440
441## Building Applications with [d3-graphviz](https://github.com/magjac/d3-graphviz)
442### SVG structure
443The generated SVG graph has *exactly* the same structure as the SVG generated by [Viz.js](https://github.com/mdaines/viz.js), so applications utilizing knowledge about this structure should be able to use [d3-graphviz](https://github.com/magjac/d3-graphviz) without adaptations. If [path tweening](#controlling-path-tweening) or [shape tweening](#controlling-path-tweening) is used, some SVG elements may be converted during transitions, but they are restored to the original shape after the transition.
444
445See this [example application](https://bl.ocks.org/magjac/28a70231e2c9dddb84b3b20f450a215f).
446
447### <b>NOTE:</b> avoid [*selection*.select](https://github.com/d3/d3-selection#selection_select)
448When selecting elements within the graph, [*selection*.select](https://github.com/d3/d3-selection#selection_select) *must not be used* if additional rendering is going to be performed on the same graph renderer instance. This is due to the fact that [*selection*.select](https://github.com/d3/d3-selection#selection_select) propagates data from the elements in the selection to the corresponding selected elements, causing already bound data to be overwritten with incorrect data and subsequent errors. Use the [<i>selection</i>.<b>selectWithoutDataPropagation</b>()](#selection_selectWithoutDataPropagation) (a [d3-graphviz](https://github.com/magjac/d3-graphviz) extension of [d3-selection](https://github.com/d3/d3-selection)) or [*selection*.selectAll](https://github.com/d3/d3-selection#selection_selectAll), which do not propagate data or [*selection*.node](https://github.com/d3/d3-selection#selection_node) and [querySelector](https://www.w3.org/TR/selectors-api/#queryselector). For example, to select the first <b>g</b> element within the first <b>svg</b> element within a specified <b>div</b> element:
449
450
451```js
452var div = d3.select("#graph");
453var svg = d3.select(div.node().querySelector("svg"));
454var g = d3.select(svg.node().querySelector("g"));
455 ```
456
457For more, read [this issue](https://github.com/d3/d3/issues/1443) and [this Stack Overflow post](https://stackoverflow.com/questions/17846806/preventing-unwanted-data-inheritance-with-selection-select).
458
459## Data Format
460
461The data bound to each DOM node is an object containing the following fields:
462 * <b>tag</b> - The DOM node tag.
463 * <b>attributes</b> - An object containing attributes as properties.
464 * <b>children</b> - An array of data for the node's children.
465 * <b>key</b> - The key used when binding data to nodes with the [key function](https://github.com/d3/d3-selection#joining-data). See [<i>graphviz</i>.<b>keyMode</b>](#graphviz_keyMode) for more.
466 * <b>text</b> - Contains the text if the DOM node is a [Text node](https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1312295772). A text node has the tag "<b>#text</b>", not to be confused with the tag "<b>text</b>", which is an [SVG <b>'text</b>' element](https://www.w3.org/TR/SVG/text.html#TextElement).
467 * <b>comment</b> - Contains the comment if the DOM node is a [Comment node](https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1728279322). A comment node has the tag "<b>#comment</b>".
468
469Other fields are used internally, but may be subject to change between releases and should not by used an external application.
470
471To inspect data:
472
473```js
474d3.select("#graph").graphviz()
475 .renderDot('digraph {a -> b}');
476console.log(JSON.stringify(d3.select("svg").datum(), null, 4));
477 ```
478
479## Performance
480
481The shape- and path-tweening operations are quite computational intensive and can be disabled with [<i>graphviz</i>.<b>tweenShapes</b>](#graphviz_tweenShapes) and [<i>graphviz</i>.<b>tweenPaths</b>](#graphviz_tweenPaths) to improve performance if they are not needed. Even if enabled, performance gains can be made by turning off conversion of equally sided polygons with [<i>graphviz</i>.<b>convertEqualSidedPolygons</b>](#graphviz_convertEqualSidedPolygons) or by reducing tween precision by setting a larger value with [<i>graphviz</i>.<b>tweenPrecision</b>](#graphviz_tweenPrecision).
482
483In order for animated transitions to be smooth, special considerations has been made to do the computational intensive operations before transitions start. Use [*transition*.delay](#transition_delay) to reserve time for those computations.
484
485Since the author is new to both Javascript and D3, there are probably a lot of things that can be improved. Suggestions are welcome.
486
487## Requirements
488
489[d3-graphviz](https://github.com/magjac/d3-graphviz) transpiles the production build to [ES5](https://www.ecma-international.org/ecma-262/5.1/) before publishing it on [npm](https://www.npmjs.com/), so it should be possible to use it with most build tools and browsers.
490
491## Support
492
493When asking for help, please include a link to a live example that demonstrates the issue, preferably on [JSFiddle](https://jsfiddle.net/). It is often impossible to debug from code snippets alone. Isolate the issue and reduce your code as much as possible before asking for help. The less code you post, the easier it is for someone to debug, and the more likely you are to get a helpful response.
494
495### Be notified of updates
496
497By clicking the **Watch** button, you will stay tuned for updates to the library.
498
499### Getting help
500
501* For specific questions, please use [Stack Overflow tags d3.js & graphviz](https://stackoverflow.com/tags/d3.js+graphviz).
502
503* For general discussions regarding d3-graphviz, please use the [d3-graphviz Slack](https://join.slack.com/t/d3-graphviz/shared_invite/enQtMzMwODQzMDI5MDA5LTExYTgyYThhNzI3YjJlODRiMzQ3MWM3YWI5ZjAyMTI2MmI4YWIwMDM4ZmY5MDQzNjkzMDY4YTRmMTU1YzIzNTY).
504
505### Reporting bugs
506
507If you think you have found a bug in d3-graphviz itself, please [file an issue](https://github.com/magjac/d3-graphviz/issues/new).
508
509## Development
510
511In order to run the tests you need [Node.js](https://nodejs.org/en/download/package-manager/) 6.x or later.
512
513## Credits
514
515* [Mike Daines](https://github.com/mdaines) for [Viz.js](https://github.com/mdaines/viz.js/).
516* [Mike Bostock](https://github.com/mbostock) for the [Path Tween](https://bl.ocks.org/mbostock/3916621) code and [Stroke Dash Interpolation](https://bl.ocks.org/mbostock/5649592) code.
517* [Aaron Bycoffe](https://bl.ocks.org/bycoffe) for the [Element rotation with point-along-path interpolation](http://bl.ocks.org/bycoffe/c3849a0b15234d7e32fc) code.
518* [Marcin Stefaniuk](https://github.com/mstefaniuk) for inspiration and learning through [graph-viz-d3-js](https://github.com/mstefaniuk/graph-viz-d3-js).
519* [Ueyama Satoshi](https://github.com/gyuque) for inspiring growing edges through [livizjs](http://ushiroad.com/jsviz/).
520
\No newline at end of file