Vue-Tree-Chart
A recent project had a front-end requirement to draw a family tree, something like this:
Click the node, and the operation menu will pop up, realizing the operation of adding, deleting, modifying and checking. After checking online materials, WE find that the existing cases are basically realized based on the jQuery plug-in orgchart. Our project is based on Vue, so we don’t want to introduce jQuery because of this function. Therefore, based on Vue, a simple version of the Tree/organization Chart component is implemented: VUe-tree-chart.
Vue-tree-chart realizes the core dynamic drawing of organizational Chart and click node callback. Based on these two points, it can meet most relevant requirements. For example, dynamic addition, deletion and modification of front-end is nothing more than editing component data, and the interface will be automatically updated by using the data-driven features of Vue. Add, delete and change the server side is more simple, the front end just request operation interface, after the operation is over, pull the latest data synchronization to the component on the line; The default interface of the component is very simple, introducing only a few styles necessary for chart rendering, making it very easy to customize styles later; Less common requirements like dragging, zooming, and exporting are not built into the component, but it is relatively easy to implement these extensions on a source code basis.
How to draw the structure diagram
Unreliable ideas
After I got this requirement, the first idea THAT came to my mind was to use DIV layout +JS dynamic calculation to achieve this. If the node connection is not considered, this idea can barely cope with it, which can be roughly divided into three steps:
First, split the data by generation
The raw data format can only be a layered JSON object:
{
name: 'root',
children: [{
name: 'child',
children: [{
name: 'grandchild',
...
}]
}]
}
Copy the code
Split by generation, it looks like this:
[
[{
id: 0,
name: 'root
}],
[{
id: 1,
name: 'child',
pid: 0
}],
[{
id: 2
name: 'grandchild',
pid: 1
}]
]
Copy the code
To visualize, what I really want is this structure:
2. Draw nodes by generation
With the data from the previous step, it is not too easy to generate each generation of nodes from top to bottom, and then center it, the tree structure is basically out:
At this point, the node spacing is the same, we need to calculate and update the node spacing in the next step, so that they present the correct ownership relationship.
Calculate the distance between nodes
What we need is something like this:
Graphics, in addition to the original node is always centered, space should be equal to the offspring of other node of space, so we need to start from the last generation node traversal, in turn, get the parent node should occupy the space up, and about the need to marin is calculated values, apply all contain child nodes of the node after the right margin, You should get the image above.
In addition, the family tree also needs to be connected between nodes. If we still follow this idea, it is ok to draw a line with div simulation, but the complexity of the calculation logic will be relatively large. At this time, we obviously feel that the idea is wrong, so we must change the direction.
The Table of the use
Later, referring to the implementation of OrgChart, I opened the debugging tool and saw that there were a lot of
Here to supplement the background knowledge of Table, DIV+CSS in the era of just popular, Table layout due to slow rendering and code redundancy by all front-end collective, Table layout rendering slow reason is, TD is the only first into the document may be later into the document to affect the size of the tag, If the entire Table is loaded according to the common page rendering logic, the page will be redrawn frequently with the LOADING of TD tags. To avoid this situation, the browser adopts special drawing logic for the Table, that is, after the whole Table tags are loaded, the Table will be drawn on the page again. The result is that when the page uses Table layout completely, the whole page loading process is blank, and the page will suddenly appear once and for all after loading, which is very poor user experience in the case of weak network. Therefore, not using Table layout has become the most basic requirement for front-end development.
This feature is not suitable for layout, but it makes Table the “most powerful” tag in HTML. For example, the tree plugin is actually a poor example of the Table feature. A multi-generation organizational structure can be perfectly implemented using only the Table tag, even without CSS:
<table>
<tr>
<td colspan="2">
root
</td/>
</tr>
<tr>
<td>
<table>
<tr>
<td>
children1
</td>
<td>
<table>
<tr>
<td colspan="2">
children2
</td>
</tr>
<tr>
<td>
grandchild1
</td>
<td>
grandchild2
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
Copy the code
Although the structure is verbose, it does fulfill the requirements.
The implementation of node connections also takes advantage of Table’s adaptability, but the implementation is more subtle:
This attachment is divided into two lines (TR), the first line to achieve a connecting the middle vertical bar the parent node, the second line connection and vertical and horizontal connections every child nodes, the first line is simply not to mention here, the second row is very interesting, painting red box part of the above is to realize the effect and the label structure respectively.
First generate TD labels by X2 number of child nodes, then add classes to “rightLine” and “leftLine” alternately for each TD, with “rightLine” showing 1px rightLine and “leftLine” showing 1px leftLine. Six lines, one right and one left, are combined in pairs to form exactly three 2px vertical lines connecting the center of each child node; Then add a “topLine” class to all but the first and last TD tags. Add a 2px top edge to each of them. This will create a horizontal line that connects the three vertical lines.
Seeing this score, I felt my IQ was crushed anyway.
Based on this idea with Vue to achieve again, independent into a component after the entire file code but about 100 lines.
In addition to the knowledge of live learning and use is really very important, the knowledge point here is an entry front-end should master, but the development of the time did not think of this idea, may be with a large number of work in recent years to rely on JS, sensitivity to HTML and CSS reduced. It’s common for people to always solve problems in a familiar way, but this is definitely not a good habit for developers and needs to be reflected on.
Secondary development
Vue-tree-chart has been published to NPM and can be added to the project by default using package management tools:
npm i vue-tree-chart --save
Copy the code
But NPM is compiled version of the installation, if you want more flexibility in the project to do secondary development, can be directly to the ‘lib/components/TreeChart vue’ download file to project components directory (‘ SRC/components/’), You can modify the Treechart. vue file directly.
Vue-cli 3.0 build library
Finally, vuE-CLI 3.0 builds for the convenience of component developers. Vue-cli 3.0 separately provides two build modes for libraries and Web Components in addition to the normal build mode. Now there is no need to manually modify the WebPack configuration to develop VUE plug-ins/Components. By passing in target\name\entry for the build command, you can automatically compile the entry file into a library and output a list of files required by the CommonJS, browser environment.
For example, vue-tree-chart’s package.json file:
"main": "./dist/TreeChart.common.js",
"scripts": {
"build-bundle": "vue-cli-service build --target lib --name TreeChart ./lib/index.js",
...
Copy the code
NPM run build-bundle generates a series of output files in the ‘/dist’ directory, where “treechart.common.js” is the CommonJS package required in the webpack environment. Configure this file as ‘main’ and use it in your project like this:
import TreeChart from "vue-tree-chart";
Copy the code
The imported TreeChart object is a Vue Component that can be mounted as a global or local Component.
The attached
Vue-tree-chart project address: github.com/tower1229/V…
Front-end road original technical article, reproduced please indicate the source: refined-x.com/2018/08/03/…