How do I associate SVG elements generated by graphviz to elements in the DOT source code

后端 未结 2 1500
野的像风
野的像风 2021-02-09 17:00

So, I\'ve generated an svg graph from the dot file, using viz.js.
Now, it\'s easy to select it\'s elements, using javascript, but I don\'t see any association to the origi

2条回答
  •  清酒与你
    2021-02-09 17:37

    In cases simpler that yours, the SVG </code> element can be used to refer back to nodes and edges. For nodes, the title is the "node_id" (not to be confused with the node attribute id) and for edges it is "node_id edgeop node_id", e.g. <code>a -> b</code>. From your SVG code:</p> <p><code><g id="node1" class="node"> <title>person

    person can be used to refer back to the DOT source line: person [....

    In the general case, the Graphviz id attribute is your friend:

    id

    Allows the graph author to provide an id for graph objects which is to be included in the output. Normal "\N", "\E", "\G" substitutions are applied. If provided, it is the responsibility of the provider to keep its values sufficiently unique for its intended downstream use. Note, in particular, that "\E" does not provide a unique id for multi-edges. If no id attribute is provided, then a unique internal id is used. However, this value is unpredictable by the graph writer. An externally provided id is not used internally.

    If the graph provides an id attribute, this will be used as a prefix for internally generated attributes. By making these distinct, the user can include multiple image maps in the same document.

    In your case, you want to reference not only nodes, but also individual fields of record-based nodes.

    Although the fields of record labels are defined with fieldId's, they do not seem to be intended to propagate to the generated SVG:

    The first string in fieldId assigns a portname to the field and can be combined with the node name to indicate where to attach an edge to the node. (See portPos.)

    To your rescue comes HTML-like labels:

    The record-based shape has largely been superseded and greatly generalized by HTML-like labels. That is, instead of using shape=record, one might consider using shape=none, margin=0 and an HTML-like label.

    With them you can create a node that is a table with rows and columns where you can use the ID attribute:

    ID="value"

    allows the user to specify a unique ID for a table or cell. See the id attribute for more information. Note that the "value" is treated as an escString similarly to the id attribute.

    Unfortunately there is a bug in Graphviz (better described here) that causes this attribute to be ignored in the SVG output. Fortunately, there's a workaround.

    Below is a solution which is based on d3-graphviz, which uses viz.js internally. You don't need to use d3-graphviz, though. You can achieve the same thing with viz.js directly.

    If you keep your id's sufficiently unique and you have control of the formatting of the DOT source, you can use simple pattern replacement as in the presented solution.

    If you don't have control over the formatting of the DOT source, you are probably better off feeding back the information to the application that generates it. An alternative, to avoid writing a full-fledged DOT parser, is to normalize the DOT source with viz.js by using 'dot' as output format and try to parse that.

    
    
    
    
    
    
    

提交回复
热议问题