Estoy tratando de crear flechas direccionales en una ruta svg que se está procesando usando d3 . Obtengo los puntos de inicio usando la cadena de ruta y el paquete npm svg-path-properties . Luego empujo estos puntos a una matriz y, en otra función, mapeo estos puntos en la ruta svg original con la lógica d3 para crear triángulos en cada punto.
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)'); }); } Ahora, cuando reviso el navegador, puedo ver mi ruta principal, pero no triángulos. Puedo inspeccionar el DOM y ver el svg , el defs , el marker y la path en la que se supone que deben agregarse. También puedo seleccionar la ruta del marcador y ver dónde debería mostrarse (un cuadro azul muestra dónde debería estar el triángulo). No puedo entender por qué no se muestran los triángulos. Cualquier ayuda será muy apreciada. Creé un ejemplo de stackblitz para experimentar con soluciones.
Además del hecho de que tiene muchos elementos de marcador con la misma identificación, su marcador tiene un viewBox que hace que el triángulo quede fuera del cuadro de marcador. Un viewBox adecuado para la ruta que tiene con un trazo de 3 unidades sería más grande que su cuadro delimitador, por lo que usaría 'viewBox = "18 5 14 14"'. Es posible que desee elegir un viewBox diferente.
Aquí puede ver la ruta que desea usar como marcador:
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>Una vez que tenga este wiewBox para el marcador, verá el marcador pero queda fuera de la ruta. Esto se debe a que el marcador tiene atributos refX y refY que hacen referencia al punto donde el marcador se une a la ruta. Por defecto, este punto es {0,0}. Usaré refX="18.5" refY="9". Elijo 9 porque la punta del triángulo tiene y=9 (d="M20,7L28, 9 L20,15Z")
En el siguiente ejemplo estoy marcando este punto con un círculo dorado. Es posible que desee elegir uno diferente.
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>Y así es como se vería el camino con el marcador:
<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>