Technology selection
In the process of developing mind map library blink-mind-react, there are two technologies to realize the Link between node widgets in mind map:
- Draw using the Canvas API
- Using SVG elements
Since THE layout of mind map is Flex layout, SVG elements can be operated just like ordinary DOM nodes. Using SVG scheme, the Link between each two Nodewidgets can be represented by an SVG element. How many child elements does a NodeWidget have? The children of the NodeWidget contains how many links are represented in SVG. Encapsulating a connection wire into a component is called a LinkWidget. In this way, you only need to pay attention to the location and change of the two nodeWidgets associated with the LinkWidget during the layout of the Link.
However, if canvas scheme is selected,
- Draw all the links in the entire mind map onto the same canvas
- Or draw the links of a node and all its children on the same canvas
Both of these methods result in more than two changes in NodeWidget positions to focus on when drawing links, and the layout algorithm is more complex than the SVG scheme.
With this in mind, I used an SVG solution in my development.
Demand analysis
Specific requirements are as follows:
Mind map layout can be configured to support single-sided layout and two-sided layout. The layout direction of the mind map should be supported in four directions: up, down, left and right, and unilateral layout should be supported in all four directions. In a two-sided layout, you need to support left and right, and up and down.
For example, the following picture shows several layouts supported by a software in the market. Its one-way layout only supports three directions, left, right and down, and two-way layout only supports left and right.
Implementation approach
For details, see linkWidget.tsx
Simple implementation of the idea
First of all, simplify the problem a little bit, to achieve a one-way layout in the right layout
As shown in the figure:
DOM structure is as follows
The SVG element used to draw the Link is placed under the div element class=’ bM-link ‘, and the POSITION of the BM-link element under the same node is set to absolute, with both left and top set to 0. Bm-link and BM-children BoundingRect are the same.
SVG content for a single link:
The path element in SVG can be computed. So how do we do that? Assuming that the key of the Link From NodeWidget is fromNodeKey and the key of the To NodeWidget is toNodeKey, The BoundingRect of the two nodeWidgets can be retrieved from the DOM API, and the Link path can be calculated based on the BoundingRect and the coordinate system of the SVG element itself. See the code for the LinkWidget component in the library for details. I won’t post the specific code here.