[D3.js advanced series-10.0] Mind Map, d3.js10.0

Source: Internet
Author: User

[D3.js advanced series-10.0] Mind Map, d3.js10.0

The nodes of the Mind Map have hierarchical and affiliation relationships, which are similar to the shapes in which branches stretch from the trunk. As mentioned above, five layout and cluster layout are expanded by hierarchical layout) the layout chart has a "Tree" structure ". Therefore, you can use these two la s to create a mind map.


1. Construction ideas

Tree chart layout, which converts a hierarchical object root into a node array nodes as follows. There is a root object:

{name: "node1",children: [{ name: "node2" },{ name: "node3" }]}
After tree chart layout conversion, the node array nodes is as follows:
[{name: "node1",children: [{ name: "node2" },{ name: "node3" }]},{ name: "node2" },{ name: "node3" }]

Is the array of the above nodes. Because node1 has subnodes, it can be used as a switch. Click node1 to display node2 and node3.

The problem is: how to create a "Switch" so that when you click a node in the tree chart, the tree chart is updated and displays the subnode of the clicked node.

We know that the hierarchy of a tree chart is determined by the children attribute of each object (of course, you can also use the tree. children () modify this). That is to say, if the children value of a node is null, its child nodes will not enter the node array nodes when the layout is used again. For example, change root:

{name: "node1",children: null}

Then, the node arrays nodes do not have node2 and node3 nodes. That is to say, you only need to set the children of the clicked node to null. However, since children nodes may be used in the future, you can set a Temporary Variable _ children to save this value. For example:

{Name: "node1", children: null _ children:/* Temporary Variable */[{name: "node2" },{ name: "node3"}]}

Tree chart layout does not regard _ children as the variable for saving the child node, but stores it as a normal variable. Therefore, there is only one node in the node array nodes. Based on the above idea, write a switch function as follows.

// Switch. d is the node to be clicked. function toggle (d) {if (d. children) {// if there is a subnode d. _ children = d. children; // Save the Child node to _ children d. children = null; // set the subnode to null} else {// if there is no subnode d. children = d. _ children; // retrieve the original subnode d from _ children. _ children = null; // SET _ children to null }}

When switching the switch status, you must re-call the layout to re-calculate the node location. That is to say, a re-drawing function is required to process data updates. This requires the processing template of [select set and data-Chapter 1]. Part of the code of the re-painting function is as follows. Pay special attention to how the function is used.

// Redraw function redraw (source) {// recalculate the node and link var nodes = tree. nodes (root); var links = tree. links (nodes); // obtain the update part of the node var nodeUpdate = svg. selectAll (". node "). data (nodes, function (d) {return d. name;}); // obtain the enter part of the node var nodeEnter = nodeUpdate. enter (); // when you add a new node to the enter part, add a listener and switch the nodeEnter function. append ("g "). on ("click", function (d) {toggle (d); redraw (d );}); ***************/}

Each newly added node responds to the click event. When a node is clicked, if it has a subnode, the root object is modified when the function is switched. After the function is called, the new tree chart will be drawn. As a result, a tree chart can be used as a mind map.


2. Create a Mind Map

First, you must have a hierarchical JSON file. This document uses: learn. json

Next, create a tree chart layout and a diagonal line generator to draw a tree chart.

Then, implement the most critical re-painting function. The function declaration is as follows:

function redraw(source)

There is only one parameter "source", which is the clicked node. If the node is closed, its subnodes will be displayed after the click. If the node is open, its subnodes will be hidden after the click. The implementation of the function body is divided into four steps:

2.1 call layout, computing nodes, and line arrays

Tree. nodes () in the tree chart layout returns the node array, and tree. links () returns the line array. Here, the y coordinate of the node is re-calculated so that it is only related to the depth of the node. Since the x and y coordinates must be reversed during node and line drawing in the future, therefore, here the re-calculation is actually the coordinates in the horizontal direction.

// Application layout, calculation node and line var nodes = tree. nodes (root); var links = tree. links (nodes); // recalculate the y coordinate nodes of the node. forEach (function (d) {d. y = d. depth * 180 ;});

The re-calculation of y coordinates is to ensure that the structure of the tree chart does not change much when data is updated (used to click nodes), so it looks natural.

2.2 process node update, enter, and exit

Select all nodes in svg to bind them to the node array nodes. When binding, set a key function. D. name is directly returned in the key function. When the node array is updated, the new node corresponds to the old node on the name.

// Obtain the update part of the node var nodeUpdate = svg. selectAll (". node "). data (nodes, function (d) {return d. name;}); // obtain the enter part of the node var nodeEnter = nodeUpdate. enter (); // obtain the exit part of the node var nodeExit = nodeUpdate. exit ();

First, process the "enter" section, that is, add a node. Nodes are composed of a circle in the group element indicating the node, and a text element indicating the node name. The element structure is as follows:

In this example, each newly added node will slowly transition to its own position, which is more friendly. Therefore, the initial position of the new node is set at the source node. Specifically, the coordinates are stored in source. x0 and source. y0. In addition, for each new node, the radius is set to 0 and the setting is completely transparent. Then, when processing the update part, the new nodes will be transitioned to the normal state. It shows how to determine and transition when processing the enter and update parts.

The following code processes the enter part.
// 1. how to deal with the "Enter" section of the node var enterNodes = nodeEnter. append ("g "). attr ("class", "node "). attr ("transform", function (d) {return "translate (" + source. y0 + "," + source. x0 + ")";}). on ("click", function (d) {toggle (d); redraw (d) ;}); // omit adding the circle and text

Then, process the update part, and slowly transition all nodes (including the newly added nodes in the enter part) to the new position. Because the new node array is bound with the node selection set, the new coordinate values are saved in d. x and d. y.

// 2. how to deal with node Update: var updateNodes = nodeUpdate. transition (). duration (1, 500 ). attr ("transform", function (d) {return "translate (" + d. y + "," + d. x + ")";});
Finally, in the exit section, the location of the node to be deleted is slowly transitioned to its parent node.
// 3. how to deal with the Exit part of the node var exitNodes = nodeExit. transition (). duration (1, 500 ). attr ("transform", function (d) {return "translate (" + source. y + "," + source. x + ")";}). remove ();
2.3 process the update, enter, and exit parts of the link respectively.

In svg, select all connections and bind the links array to obtain the update, enter, and exit parts of the connections.

// Obtain the link update part var linkUpdate = svg. selectAll (". link "). data (links, function (d) {return d.tar get. name;}); // obtain the link's enter part var linkEnter = linkUpdate. enter (); // obtain the exit part of The Link var linkExit = linkUpdate. exit ();

For the enter part of the link, the path element path is inserted. The path is obtained by the diagonal line generator. The start and end coordinates of the diagonal lines are (source. x0, source. y0 ).

For the update part of the link, update the positions of all connections (starting and ending points of the diagonal line) to the new position, that is, the locations saved in the currently bound array links.

For the exit part of the line, it will slowly transition to the current source point and then remove it.

// 1. how to deal with the Enter part of The Link linkEnter. insert ("path ",". node "). attr ("class", "link "). attr ("d", function (d) {var o = {x: source. x0, y: source. y0}; return diagonal ({source: o, target: o });}). transition (). duration (1, 500 ). attr ("d", diagonal); // 2. link Update. transition (). duration (1, 500 ). attr ("d", diagonal); // 3. how to deal with the Exit part of The Link linkExit. transition (). duration (1, 500 ). attr ("d", function (d) {var o = {x: source. x, y: source. y}; return diagonal ({source: o, target: o });}). remove ();

2.4 Save the current node coordinates

When you click a node, the data is updated, that is, the coordinates of each node are updated. However, you need to use the data before the update (source. x0 and source. y0) when performing the transition operation on the nodes and connections ). Therefore, the current node location must be saved every time you call the redraw function.

nodes.forEach(function(d) {      d.x0 = d.x;      d.y0 = d.y;});

X and y coordinates are stored in x0 and y0 respectively. When redraw (source) is called, The clicked node is passed as a parameter to the redraw function, so source. x0 and source. in y0, the coordinates of the nodes before being clicked are saved.

3. Results

The result is shown in. Click a node to expand the subnode.

Click the following link to view the source code by email:

Http://www.ourd3js.com/demo/G-10.0/mind.html

Thank you for reading.

Document Information
  • Copyright Disclaimer: BY-non-commercial (NC)-deduction prohibited (ND)
  • Published on: February 1, June 27, 2015
  • More content: OUR D3.JS-data visualization special site and CSDN personal blog
  • Note: This article is published in OUR D3.JS. For more information, see the source. Thank you.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Contact Us

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.