美文网首页
svg中文字跟随连线方向的两种解决方案

svg中文字跟随连线方向的两种解决方案

作者: 渴望认清自己 | 来源:发表于2019-05-13 17:33 被阅读0次

前言:

在svg中,文字也是图像,<text>标签显示文字,默认的文字方向是水平方向的。当我们需要使文字跟随连线方向,需要额外的一些设定,目前自己查阅到两种解决方案,适用于两种情况。
建议去MDN或者别处先查阅一下svg<text>的基本属性,本文不再介绍,只说明情况以及解决方案。

情况一:

连线两端的节点不要求拖动,连线和节点都是固定死的,静态的。

情况二:

连线两端的节点要求拖动,连线和节点是动态的,可以拖拽。

方案一:

内嵌于<text>中的<textpath>元素,通过xlink:href属性指向一个<path>元素,可以将其内部字符的baseline设置成指定的path.
<textpath>还有一个[startOffset]属性,用来设置文字在路径上的起始位置(百分比)。


静态效果图 svg结构图

上代码:

        let path =  object.selectAll(".path").data(paths,function (d) {return d.linkKey;});
        //清楚多余的dom element
        path.exit().remove();
        //每条连线的path和text存放在一个g里
        let pathEnter = path.enter().append("g")
          .attr("class", "path") 
       
        // 为每条连线创建text 和 textpath
        pathEnter.append("text")
          .attr("class","path-text")
          .attr('text-anchor','start')
          .style('font-size','12px')
          .style('font-family','Si  mSun')
          .append("textPath")
          .attr("class","textPath")
          .attr("xlink:href", p => { //此行代码,将文字链接到对应的path
            return "#textPath" + p.linkKey;
          })
          .attr('startOffset','70%')//此行代码,决定文字在路径上的起始位置
          .text(p => {return p.linkName})//显示文字内容

方案二:

当面对节点和连线需要动态的时候,我们要根据拖拽的节点控制文字一直可以正常显示。
可以查阅到,<text>有一个x的属性,x指定文字最左侧坐标位置,我们根据计算设置x的值,控制文字最左侧的坐标。x的值就是沿路径方向的path路径的起点-->文字最左侧的距离。此时就无需设置<textPath>的[startOffset]属性。
上代码:

        let path =  object.selectAll(".path").data(paths,function (d) {return d.linkKey;});
        //清楚多余的dom element
        path.exit().remove();
        //每条连线的path和text存放在一个g里
        let pathEnter = path.enter().append("g")
          .attr("class", "path") 

        // 为每条连线创建text 和 textpath
        pathEnter.append("text")
          .attr("class","path-text")
          .style('font-size','12px')
          .style('font-family','Si  mSun')
          .append("textPath")
          .attr("class","textPath")
          .attr("xlink:href", p => {
            return "#textPath" + p.linkKey;
          })

        //合并第一次创建为更新
        path = path.merge(pathEnter);

        //此处更新的是textpath 的属性,使得文字依附在path上
        path.select(".path-text")
          .attr('x',curThis.$options.methods.handleTopologyLinkTextX)//x指定文字最左侧坐标位置,根据连线两端节点的坐标,勾股出连线的长度l,让文字最左侧位于连线的中间,就是让x = l/2;
          .attr('text-anchor','center')
          .attr('rotate',curThis.$options.methods.handleTopologyLinkRotate)
          .select('.textPath')
          .text(curThis.$options.methods.handleTopologyLinkTextDirection);

      /**
       * @Description  :处理拓扑图中连接的文字方向的旋转
       * @author       : yjz
       * @param        :
       * @return       :
       * @exception    :
       * @date         : 2019/05/10
       */
      handleTopologyLinkRotate(p) {
        return p.sourceAxis[0] < p.targetAxis[0] ? 0 : 180
      },

      /**
       * @Description  :处理拓扑图中连接的文字的最左侧坐标的位置
       * @author       : yjz
       * @param        :
       * @return       :
       * @exception    :
       * @date         : 2019/05/10
       */
      handleTopologyLinkTextX(p) {
        //x指定文字最左侧坐标位置,根据连线两端节点的坐标,勾股出连线的长度l,让文字最左侧位于连线的中间,就是让x = l/2;
        let x = p.targetAxis[0] - p.sourceAxis[0],y = p.targetAxis[1] - p.sourceAxis[1];
        let l = Math.sqrt(x * x + y * y)
        return l/2;
      },

      /**
       * @Description  :处理拓扑图中连接的文字的顺序方向,保证文字正常显示
       * @author       : yjz
       * @param        :
       * @return       :
       * @exception    :
       * @date         : 2019/05/10
       */
      handleTopologyLinkTextDirection(p) {
        //为进行旋转的时候,文字方向是正常;当进行旋转之后,文字就反序显示了,需要将文字转换为顺序。
        if (p.sourceAxis[0] < p.targetAxis[0]) {
          return p.linkName
        }
        return p.linkName.split("").reverse().join("");
      },

相关文章

网友评论

      本文标题:svg中文字跟随连线方向的两种解决方案

      本文链接:https://www.haomeiwen.com/subject/kkfraqtx.html