d3.js D3js使用SVG路径沿着的形状自定义线条样式

gkl3eglg  于 2022-11-12  发布在  其他
关注(0)|答案(3)|浏览(167)

SVG图形中得标准线条允许将基本属性(如描边宽度,颜色,线帽与虚线)更改为创建得虚线或点线.
是否可以将更复杂的特征添加到线中?
例如,是否可以沿着预先存在的线复制形状?类似于虚线,但带有星形或十字形?
用例可能是打印的白色线条图,其中线条的颜色编码不容易辨认。
使用D3绘制的简单路径可能使用如下函数:

const drawLine = d3.line()
        .y(d => y(d.y))
        .x(d => x(d.x))

带输出

<path class="line" d="M530,116.2995087503838L454.28571428571433,122.98894688363525L227.14285714285717,102.0018421860608L151.42857142857142,65.41142155357693L75.71428571428571,50.420632483880865L0,0"></path>

是否可以沿着此路径均匀间隔形状?“点”与数据中的任何内容都无关。
编辑:一些聪明的CSS技巧来创建自定义线条模式也是一个有效的解决方案。

gt0wga4j

gt0wga4j1#

是否可以沿着此路径均匀分布形状?
这些“点”与数据中的任何内容都无关。

使用<marker>

一个将处理
<path marker="mark1" markers="5" d="...path..." />
并为每个标记添加<animateMotion>就可以完成这项工作。
dur=0.0001设置为显示“instant”(您不能将其设置为0)

<svg-path-markers>
  <svg viewBox="0 0 200 70" style="background:pink">
    <defs>
      <g id="mark1">
        <circle cx="0" cy="0" r="5"/>
        <rect x="-2" y="-2" width="4" height="4" fill="gold" />
      </g>
      <use id="mark2" href="#mark1" y="10" fill="green" transform="scale(.5)"/>
    </defs>
    <g fill="blue">
      <path marker="mark1" markers="5" fill="none" stroke="teal"
            d="m10,6c20,0,25,25,180,25" />
    </g>
    <path marker="mark2" markers="10" fill="none" 
          stroke="red" d="m10,15c40,0,45,35,180,35" />
  </svg>
</svg-path-markers>
<script>
  customElements.define("svg-path-markers", class extends HTMLElement {
    connectedCallback() {
      setTimeout(() => this.querySelectorAll("[marker]")
                           .forEach(p=>this.markPath(p)));
    }
    markPath(path,steps = ~~path.getAttribute("markers") ){
      let id = path.id || (path.id = this.localName + Math.random()*1e18); // a unique id
      const marker = dist => `<use href="#${path.getAttribute("marker")}">
                               <animateMotion dur="1s" keyPoints="0;${dist}" 
                                 keyTimes="0;1" fill="freeze" calcMode="linear">
                               <mpath href="#${id}"/></animateMotion></use>`;
      path.insertAdjacentHTML("afterend", Array(steps)
                                           .fill(0)
                                           .map((_,i) => marker(i*(1/(steps-1))))
                                           .join(""));
    }
  })
</script>
m1m5dgzv

m1m5dgzv2#

这是一个d3的解决方案。请仔细阅读我在代码中的注解。
第一个

qaxu7uf2

qaxu7uf23#

您也可以使用css offset-path来模仿自订笔画样式。
类似于svg的<mpath>,你可以定义一个路径来对齐元素。
主要区别:我们可以使用offset-distance沿着路径分布多个元素-因此我们不需要通过停止/延迟动画来模拟偏移。

更新:正如@Danny '365 CSI' Engelman指出的,Safari目前(2022年)不支持offset-distanceoffset-path

卡尼乌斯offset-distanceoffset-path.

示例1:无动画

第一个

示例2:动画;使用起点与终点偏移

第一个

相关问题