Writing in the front

Before, some friends asked me how to use D3 to draw flowchart in the front end. Today, I would like to share it with you.

To be clear, as long as your data computing power is strong enough, it is absolutely possible to use the native D3 flowchart drawing, but to make it easier for everyone to use, to avoid repeating the wheel, I recommend you to use the DAGre-D3 plugin for flowchart drawing.

Let’s meet Dagre first. Dagre is a javascript library that focuses on directed graph layout. Since Dagre only focuses on graphic layout, you need to use other schemes to actually render graphics based on dagre layout information, and Dagre-D3 is dagre’s D3-based rendering scheme.

Dagre project address

Dagre-d3 project address

The following uses D3 and Dagre-D3 to draw the flow chart of migrant detection during the COVID-19 outbreak, and the old rule is to show the renderings first.

Draw basic flow chart

data

As a kind of directed graph, flow chart is composed of nodes and edges between two points, just like tree graph and network graph.

let dataset ={
  nodes: [{id: 0.label: "Migrants".shape: "rect"},
    {id: 1.label: "Safety screening".shape: "rect"},
    {id: 2.label: "Human body temperature screening by thermal imager".shape: "diamond"},
    {id: 3.label: "Manual retest".shape: "diamond"},
    {id: 4.label: "Quick pass".shape: "rect"},
    {id: 5.label: "Emergency treatment".shape: "rect"}].edges: [{source: 0.target: 1.label: ""},
     {source: 1.target: 2.label: ""},
     {source: 2.target: 4.label: "Normal"},
     {source: 2.target: 3.label: "Abnormal"},
     {source: 3.target: 5.label: "Abnormal"},
     {source: 3.target: 4.label: "Normal"}}]Copy the code

drawing

Flowchart drawing with Dagre-D3 is divided into the following steps

  1. D3. js and dagre-d3.js files are introduced.
  2. Create the Graph object with dagre-d3 and add nodes and edges.
  3. Create the renderer and draw the flowchart in SVG.
/ / in d3 dagre-d3
<script src="./d3.v5.min.js"></script>
<script src="./dagre-d3.min.js"></script> <script> // Create graph objectletg = new dagreD3.graphlib.Graph(); // set the graph g.setgraph ({rankdir:'TB'}); Dataset.nodes.forEach(item => {g.setNode(item.id, {// Node label: item.label, // node shape: item.shape, // node style:"fill:#fff; stroke:#000"})}) dataset.edges. ForEach (item => {g.edge (item.source,item.target, {// edge label: item. edge, // edge style:"fill:#fff; stroke:#333; Stroke - width: 1.5 px"})}) // Create rendererletrender = new dagreD3.render(); // Select SVG and add a G element as the drawing container.let svgGroup = d3.select('svg').append('g'); Render (svgGroup, g); render(svgGroup, g); </script>Copy the code

In this way, the front of the flow chart is drawn out, so simple, quickly start to try!

If you need more than that, you need to understand the basic concepts and configuration items in Dagre, and understand dagre and D3-Dagre in depth to draw a more advanced flowchart.

The basic concept

Dagre is based on the theory of A Technique for Drawing Directed Graphs [1] to achieve graph layout. The theory of this article contains the following five important concepts:

  • Graph, the whole graph, is used to configure the global parameters of the graph.
  • Nodes are vertices. Dagre does not care about the actual shape and style of nodes.
  • Edge, or edge, needs to declare the nodes at each end and its own direction. For example, A -> B represents an edge from A to B.
  • Rank is the core logical unit in flowchart layout. Nodes at both ends of edge must belong to different ranks, and + nodes in the same rank will have the same depth coordinates (for example, in graph with vertical layout, y coordinates are the same). If you don’t understand rank, you’ll get a sense of it.
  • Label, that is, label. Label is not a necessary element, but Dagre adds layout calculation of Edge Label for more scenarios.

Understand the rank

In the following example, we will use an easy-to-understand descriptive language to express A node and edge: A -> B represents both nodes A and B and an edge that points from A to B.

Example 1

A->B; B->C;

+---+       +---+        +---+  
| A |------>| B |------->| C |  
+---+       +---+        +---+
Copy the code

In this example, node A, B, and C belong to three ranks.

Example 2

A->B; A->C;

            +---+
        --> | B |
+---+--/    +---+
| A |
+---+--\    +---+
        --> | C |
            +---+
Copy the code

A is in Rank1, while B and C are both one level below A and belong to RanK2, so B and C have the same X-coordinate (the example graph extends horizontally, so the depth direction is x).

Example 3

A->B; B->C; A->C;

            +---+
         -->| B |---\
+---+---/   +---+    --->+---+  
| A |                    | C |  
+---+------------------->+---+
Copy the code

In this example, we see that the nodes on edge can differ by more than one rank. Since the nodes at both ends of edge cannot belong to the same rank, we cannot make B and C belong to the same rank. Therefore, the optimal drawing result is that A and C are separated by 1 rank. So A is in RANk1, B is in Rank2, and C is in Rank3.

Configuration items

Now that you understand the basic concepts in DRage, let’s look at what configuration items drage provides.

Drage configuration items can be divided into three parts: graph global configuration, Node, and Edge.

Graph configuration

  • rankdir

Set the extension direction of node nodes. It has 4 values: TB, BT, LR, or RL. The default is ‘TB’ (top to bottom). Where T = top, B = bottom, L = left, and R = right

  • align

Set the alignment of nodes in the same rank. It can also have 4 values: UL (top left), UR (top right), DL (bottom left), or DR (bottom right). Default is undefined. Where U = up, D = down, L = left, and R = right.

  • Nodesep is the distance between nodes in the same rank. The default 50
  • The edgesep is the distance between the edges. The default 10
  • Ranksep is the spacing between adjacent levels, such as the spacing between A and B and the spacing between B and C in Example 1. The default 50
  • Marginx is the left and right distance between the whole image and the canvas. The default 0
  • Marginy is the space between the whole of the image and the canvas. The default is 0. If these distances are a little confusing, it doesn’t matter. I’m sure this picture will help you understand.

To make sense of these properties, I’ll continue with the picture above, because a picture is worth a thousand words.

g.setGraph({
   rankdir:'LR'/ / by default'TB'
   align:'DL',
   nodesep: 100,
   edgesep:100,
   ranksep: 50,
   marginx:50,
   marginy:100
});
Copy the code
  • Rankdir set to ‘LR’ means that the diagram layout extends from left to right.

  • Align set to ‘DR’ means same-level lower-right alignment.
  • Nodesep Ranksep Edgesep set style.

The node configuration

  • LabelType Node label format, you can set text and HTML format, default text format.
  • Label Indicates the text to be displayed on the node. When the HTML format is set, label is an HTML label.
  • Shape node shape, can set the rect, circle, ellipse, four diamond shape, you can also use the render. The shapes () the custom shape.
  • Style node style, you can set the node color fill, node border, such as style: “fill:# FFF; stroke:#faf”
  • LabelStyle node tag style, you can set the text style of the node tag (color, thickness, size), such as style: “fill:#afa; font-weight:bold”
  • Width indicates the node width.
  • Height is the height of the node. Configure Nodes to see what our flowchart looks like.
G. setNode(item.id, {// node label label: item.label, // node shape shape: item.shape, // node style style:"fill:#faf; stroke:#faf", // Node tag style labelStyle:"fill:#afa"
})
Copy the code

Edge configuration

  • LabelType Node label format, you can set text and HTML format, default text format.
  • Label Indicates the text to be displayed on the node. When the HTML format is set, label is an HTML label.
  • Style: “fill:# FFF; stroke:#faf”
  • LabelStyle Side tag style, you can set the text style of the side tag (color, thickness, size), such as labelStyle: “Fill :# AFA; font-weight:bold”
  • Arrowhead arrow shape, can be set to Normal, Vee,undirected, default to Normal.
  • ArrowheadStyle Arrow style, you can set arrow color, such as arrowheadStyle:”fill:#f66″ Configure the edges and see what our flow chart looks like?
G.edge (item.source,item.target, {// edge label: item.label, // edge style:"fill:#fff; stroke:#afa; stroke-width:2px",
   labelStyle: "fill:#1890ff",
   arrowhead:"vee",
   arrowheadStyle:"fill:#f66"
})

Copy the code

interaction

To add interactive functionality, use D3 functionality. In the following example, drag and zoom and hover over a tooltip.

Drag the zoom

let svg = d3.select('svg'// Create drag-and-zoomlet zoom = d3.zoom()
    .on("zoom".function () {
        svgGroup.attr("transform", d3.event.transform);
     });
svg.call(zoom);
Copy the code

Hover over tootip

  • Js code
// Create a prompt boxfunction createTooltip() {
   return d3.select('body')
          .append('div')
          .classed('tooltip'.true)
          .style('opacity', 0)
          .style('display'.'none');
    };
lettooltip = createTooltip(); / / tooltip displayfunction tipVisible(textContent) {
    tooltip.transition()
           .duration(400)
           .style('opacity', 0.9). The style ('display'.'block');
     tooltip.html(textContent)
            .style('left', (d3.event.pageX + 15) + 'px')
            .style('top', (d3.event.pageY + 15) + 'px'); } / / hidden tooltipfunction tipHidden() {
     tooltip.transition()
            .duration(400)
            .style('opacity', 0)
            .style('display'.'none'); } // Hide tooltip svggroup.selectAll ("g.node")
    .on("mouseover".function (v) {
       tipVisible(g.node(v).label);
     })
    .on("mouseout".function (v) {
        tipHidden();
     })
Copy the code
  • CSS styles
.tooltip {
     position: absolute;
     font-size: 12px;
     text-align: center;
     background-color: white;
     border-radius: 3px;
     box-shadow: rgb(174, 174, 174) 0px 0px 10px;
     cursor: pointer;
     display: inline-block;
     padding:10px;
 }

.tooltip>div {
     padding: 10px;
 }
Copy the code

The section of this article about Dagre refers to Graph data visualization: JS automatic layout directed Acyclic Graph [2].

Finally, paste the source address of this article:

D3 Drawing Flow Chart

References

[1] “A Technique for Drawing Directed Graphs” : www.graphviz.org/Documentati…

[2] Graph data Visualization: JS automatic layout directed acyclic Graph

Pay attention to data visualization technology wechat subscription number