SVG 标记方向箭头出现在 DOM 中,但标记本身不可见

SVG marker direction arrows appear in DOM, but the marker itself isn't visible

我正在尝试在使用 d3 呈现的 svg 路径上创建方向箭头。我使用路径字符串和 svg-path-properties npm 包获取起点。然后我将这些点推送到一个数组,在另一个函数中,我将这些点映射到原始 svg 路径,并使用 d3 逻辑来创建三角形在每个点。

  public mapArrowPoints(): void {
    this.arrowPoints.forEach((point: ArrowPointObject) => {
      const path = d3.path();
      path.moveTo(parseInt(point.x, 10), parseInt(point.y, 10));
      path.lineTo(parseInt(point.x, 10) + 8, parseInt(point.y, 10) + 2);
      path.lineTo(parseInt(point.x, 10) + 0, parseInt(point.y, 10) + 8);
      path.closePath();

      const svg = d3.select('svg#topLevel');
      const defs = svg.insert('defs', '#curve');
      const marker = defs.append('marker');

      marker
        .attr('id', 'triangle')
        .attr('viewBox', '0 -5 10 10')
        .attr('markerWidth', 4)
        .attr('markerHeight', 4)
        .attr('orient', 'auto')
        .append('path')
        .attr('d', path.toString())
        .attr('fill', 'red')
        .attr('stroke', 'black')
        .attr('stroke-width', '3px');

      svg
        .select('#curve')
        .attr('marker-start', 'url(#triangle)')
        .attr('marker-mid', 'url(#triangle)')
        .attr('marker-end', 'url(#triangle)');
    });
  }

现在,当我检查浏览器时,我能够看到我的主路径,但看不到三角形。我可以检查 DOM,并看到 svgdefsmarkerpath 它们应该被附加到。我还可以 select 标记路径本身,并查看它应该渲染的位置(蓝色框显示三角形应该在哪里)。我不太明白为什么没有显示三角形。任何帮助都感激不尽。我创建了一个 stackblitz example 用于试验解决方案。

除了您有许多具有相同 ID 的标记元素这一事实之外,您的标记还有一个 viewBox,它使三角形落在标记框之外。具有 3 个单位笔划的路径的适当 viewBox 会比它的边界框大,所以我会使用 'viewBox="18 5 14 14"'。您可能想要选择不同的 viewBox。

在这里你可以看到你想要用作标记的路径:

svg{border: solid}
<svg viewBox="18 5 14 14" width="300" >
      <path  d="M20,7L28,9L20,15Z" fill="red" stroke="black" stroke-width="3"></path>
    </svg>

一旦你有了这个标记的 wiewBox,你就会看到标记,但它落在路径之外。这是因为标记有一个 refX 和一个 refY 属性,它们引用标记将自身附加到路径的点。默认情况下,此点为 {0,0}。我正在使用 refX="18.5" refY="9"。我选择 9 因为三角形的尖端有 y=9 (d="M20,7L28,9L20,15Z")

在下一个示例中,我用金色圆圈标记了这一点。您可能想选择一个不同的。

svg{border: solid}
<svg viewBox="18 5 14 14" width="300" >
      <path  d="M20,7L28,9L20,15Z" fill="red" stroke="black" stroke-width="3"></path>
      
      <circle cx="18.5" cy="9" r=".5" fill="gold"/>
    </svg>

这就是带有标记的路径的样子:

<svg viewBox="0 0 700 800" >
  <defs>
    <marker id="triangle" viewBox="18 5 14 14" markerWidth="8" markerHeight="8" orient="auto" refX="18.5" refY="9">
      <path  d="M20,7L28,9L20,15Z" fill="red" stroke="black" stroke-width="3px"></path>
    </marker>
  </defs>
 

  <path fill="none"  stroke="black"  id="curve" d="M 0.05965662,9.8756182 C 665.77394,-70.124378 654.96347,387.98451 654.96347,387.98451 L 45.773941,621.3042 650.91307,783.4508" marker-start="url(#triangle)" marker-mid="url(#triangle)" marker-end="url(#triangle)"></path>
</svg>