Svg实现树状结构

1,381 阅读1分钟

1.概述

SVG 是一种基于 XML 语法的图像格式,全称是可缩放矢量图(Scalable Vector Graphics)。其他图像格式都是基于像素处理的,SVG 则是属于对图像的形状描述,所以它本质上是文本文件,体积较小,且不管放大多少倍都不会失真。SVG 文件可以直接插入网页,成为 DOM 的一部分,然后用 JavaScript 和 CSS 进行操作。

2.入门

可以查看阮一峰这篇文章
www.ruanyifeng.com/blog/2018/0…

3.实现效果(1对M,M对1的关系)

4. 实现原理

  • 贝塞尔曲线绘制:对称的曲线需要四个点foreignObject来绘制,第一个点为起点的(X,Y),第四个点为终点(EX, EY),第二第三个点可以根据起点和终点计算得出,第二个点为(X, (Y+EY)/2),第三个点为(EX, (Y+EY)/2)。这样就可以绘制出对称平滑的曲线。** parentRowlen 父级行的盒子个数,**
数据格式定义:relationLine: [
        { from: 0, to: 1 },
        { from: 0, to: 2 },
        { from: 0, to: 3 },
        { from: 1, to: 4 },
        { from: 1, to: 5 },
        { from: 2, to: 6 },
        { from: 3, to: 6 },
    ],
    
    startX =halfSize -(parentRowlen - 1) * 0.5 * (boxW + boxSpace) +parentSort * (boxSpace + boxW) -
0.5 * boxW +0.5 * boxW;
    startY = parentLevel * topSpace + boxH * parentLevel + topH;
  • 盒子的绘制:在svg插入DOM元素需要使用 foreignObject 标签。
    最重要是盒子位置的计算,从上图可以看出,盒子的布局是左右对称的,所以我们应该考虑从对称点中点出发,rowlen为当前行的个数, topSpace 是每行的间距,level 表示第几行,从1开始

数据格式定义:key为盒子的ID, relationNode: {
        1: { level: 1, sort: 0 },
        2: { level: 1, sort: 1 },
        3: { level: 1, sort: 2 },
        4: { level: 2, sort: 0 },
        5: { level: 2, sort: 1 },
        6: { level: 2, sort: 2 },
      },
startX = halfSize -(rowlen - 1) * 0.5 * (boxW + boxSpace) +sort * (boxSpace + boxW) -0.5 * boxW;
startY = level * topSpace + boxH * (level - 1) + topH;