# "D3.js Data Visualization Combat"--(3) Drawing of Sankitu (Sankey)

Source: Internet
Author: User

• What is a Sankey diagram?
• Draw a simple Sankey diagram with D3
• Circular node

• Note: This article without the author's permission is forbidden reprint and deduction
1 What is a Sankey diagram?

Sankey diagram is `流图` `flow diagram` a kind of (), used to describe the flow of energy, population, economy and so on. First proposed by the Irish Matthew Henry Phineas Riall Sankey. Sankey , a captain and an engineer, first introduced the first energy flow in an article on the energy efficiency of a steam engine in 1898, in the Journal of the Institute of Civil Engineers (Sankey), which was later named the Sankey map, and the Chinese transliteration of the Sankey chart.

The Sankey chart focuses on the flow and transfer of energy, material, or capital within the system. The starting and ending traffic are the same, and in the interior, different lines represent different traffic flows, and its width shows the traffic in proportion to this branch, and the different widths of the nodes represent the traffic size in a particular state.

2 drawing a simple Sankey diagram with D3

D3 provides a Sankey plug-in that can be used to convert the data from the input node-connection to the intermediate data used by the Sankey diagram layout. These intermediate data can be easily combined with the SVG rectangle element ( `rect` ) to draw the node, combined with the path element ( `path` ) to draw the link. makes it convenient to draw Sankey diagram with D3. Figure 1 shows the drawing effect.

Figure 1 Drawing a simple Sankey diagram

Let's take a detailed description of what to do if the Sankey diagram is implemented:

First, drawing the Sankey diagram requires the introduction of the D3 Library and the Sankey plugin library:

``<script src="../d3.js" charset="utf-8"></script ><script src="../sankey.js"></script>``
Then we need to prepare the data needed for the Sankey diagram, which describes the node-link relationships in the network in a certain format:
``//node and connection datavardata = {' nodes ': [{name:"0"}, {name:"1"}, {name:"2"}, {name:"3"}, {name:"4"}, {name:"5"}, {name:"6"}, {name:"7"}, {name:"8"}  ],' Links ': [{Source:0, Target:3, Value:Ten}, {Source:1, Target:4, Value:Ten}, {Source:2, Target:4, Value:5}, {Source:1, Target:5, Value:5}, {Source:3, Target:6, Value:5}, {Source:3, Target:7, Value:5}, {Source:4, Target:7, Value:Ten}, {Source:4, Target:8, Value:5}, {Source:5, Target:8, Value:5}  ]};``
The data here is defined as variables in JavaScript scripts, and of course can be converted by other forms of data, such as loading JSON data files. But the final form after conversion must be as shown above, which contains an array of nodes and an array of links. Each element in the node array is an object that contains a ' name ' attribute representing the name of the node, and each object in the linked array contains ' source ', ' target ', and ' value ' three attributes, representing the index of the source node (starting at 0), the index of the target node, and the traffic. Next, we can configure the property values for the Sankey layout:
``// 定义桑基布局var sankey = d3.sankey()        .nodeWidth(80)         .nodePadding(40)         .size([width, height])         .nodes(data.nodes)          .links(data.links)        .layout(3);``
The functions are interpreted as follows: * ' Nodewidth ' indicates the horizontal width of the node, this property can be used to set the width of the rectangle, etc. * ' nodepadding ' indicates the vertical spacing of the rectangle; * ' Size ' indicates the amount of space occupied by the entire Sankey graph; * ' nodes ' Load the array of nodes as described above; * the same as ' links ' function loads the linked array; * The parameters in ' layout ' indicate when the Sankey layout is used to optimize the flow layout. After defining the Sankey layout, the most important thing is to get a link path generator:
``// 路径数据生成器var path = sankey.link();``

Figure 2 The transformed node and connection data by the Sankey layout

Finally, you can bind the data to draw the rectangle nodes and paths:

``//Draw connection DatavarLinks = Svg.append ("G"). SelectAll ("Path"). Data (Data.links). Enter ()//Bind node datavarnodes = Svg.append ("G"). SelectAll (". Node"). Data (Data.nodes). Enter ();//Draw a connection lineLinks.append ("Path"). attr ({fill:"None",//Fill ColorStroke function(d,i){ returnColor (i); },//Stroke color        "Stroke-opacity":0.5,//Stroke TransparencyD:path,//Path dataId: function(d,i){ return ' link '+i}//id}). Style ("Stroke-width", function (d) {  //width of the connection          return Math. Max (1, D.dy); });//Draw circular nodesNodes.append ("Circle"). attr ("Transform", function (d) {          return "Translate ("+ d.x +","+ D.y +")"; }). attr ("R", function(d) { returnD.dy/2; }). attr ("CX", function(d) { returnd.dx/2; }). attr ("Cy", function(d) { returnD.dy/2; }). Style ("Fill","Tomato"). Style ("Stroke","Gray");``

To facilitate understanding of the flow of traffic to the Sankey graph, we can also add text hints to nodes and links,
Adding text to a node is simple, `nodes` adding `text` elements and setting text content and coordinates directly to an object that has previously bound the data and added placeholders:

``// 绘制节点文本  nodes.append("text")        .attr({            function (d) {return2; },            function (d) {return2; }        })        .text(function (d) {return``

Adding text to a link is a little more complicated, you need to add a textpath child element to the text element, and associate it with the Xlink:href property and the corresponding link path, using the Startoffset property to set the position of the text relative to the link path, for example, where 50% indicates the center display.

``// 绘制连接文本  links.append(‘text‘)        .append(‘textPath‘)        .attr(‘xlink:href‘function (d,i) {return‘#link‘ + i; })        .attr(‘startOffset‘,‘50%‘)        .text(function (d) {return‘流量:‘ + d.value; })``

After adding text, you can clearly show traffic changes, as shown in 3:

Figure 3 Adding a text hint to a Sankey chart

4 Circular nodes

Of course, you can also change the rectangle in the Sankey diagram to a circle. The key is that the specified node width cannot be too large when defining the Sankey layout, for example, this example specifies 1 pixels:

``.nodeWidth(1)``

You can then pan the circle to the calculated node coordinates of the Sankey layout and specify the center coordinate and radius of the circle with the offset of the node.

``//Draw circular nodesNodes.append ("Circle"). attr ("Transform", function (d) {            return "Translate ("+ d.x +","+ D.y +")"; }). attr ("R", function(d) { returnD.dy/2; }). attr ("CX", function(d) { returnD.DX/2; }). attr ("Cy", function(d) { returnD.dy/2; }). Style ("Fill","Tomato");``

You also need to adjust the size of the display accordingly, as shown in the final drawing effect 4:

Figure 4 Drawing a Sankey diagram of a circular node

Sometimes in order to increase the usability of the Sankey diagram, you may need to add some interactivity to the nodes and connectors. The following describes adding a mouse hover event to a connector and adding a drag event to a node.

Use CSS to control the hover style so that the connector is highlighted when the mouse hovers over it:

``<style type="text/css">    path:hover{        stroke-opacity: 0.9;    }</style>``

The effect 5 shows:

Figure 5 Connecting wires highlighted when hovering over the mouse

Adds drag behavior to the node when the node is drawn, and binds the drag event listener.

``//Draw Rectangle nodeNodes.append ("Rect"). attr ({x: function (d) { returnd.x; }, Y: function (d) { returnD.y; }, Height: function (d) { returnD.dy; }, Width:sankey.nodeWidth (), fill:"Tomato"}). Call (D3.behavior.drag (). Origin ( function(d) { returnD }). On ("Drag", DragMove));``

This `.origin(function(d) { return d; })` is to prevent jumps when dragging, the corresponding drag event listener is:

``// 拖动事件响应函数function dragmove(d) {     d3.select(this).attr({        "x"Math.max(0Math.min(width - d.dx, d3.event.x))),        "y"Math.max(0Math.min(height - d.dy, d3.event.y)))     });     sankey.relayout();     paths.attr(‘d‘,path);}``

That is, the coordinate position of the rectangle is recalculated during the drag process, the Sankey layout is restarted, and the path element is bound to the new path data. This is left to the reader as an exercise when dragging the text, as shown in the final effect 6:

Figure 6 A Sankey diagram that can be dragged

All right! Sankitu introduced to this, thank you for your attention!

"D3.js Data Visualization Combat"--(3) Drawing of Sankitu (Sankey)

Related Keywords:
Related Article

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

## A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

• #### Sales Support

1 on 1 presale consultation

• #### After-Sales Support

24/7 Technical Support 6 Free Tickets per Quarter Faster Response

• Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.