@Holger Will recommended a creative solution for adding arrows to an svg path。基本上,如果您使用 svg textPath 和 startOffset 属性,您可以使用 webfonts 添加文本箭头。这是一个巧妙的解决方案!
就我而言,我需要在 D3 中实现它,这就是我的做法:
import { svgPathProperties } from 'svg-path-properties';
import { Selection } from 'd3';
/**
* Path Arrow Points
* ---
* Create a series of arrows that follow a specified path
* to indicate the direction of movement on the track segment.
* @param mainPath 'd' path value for calculating the length of the svg
* @param numberOfPoints total number of points per length of path: used to calculate distance between points
* @param lengthOfPath used with numberOfPoints to calculate distance between points
* @param d3GroupSelection path group that contains a path onto which we can append arrows
* @param d3PathID path ID from track segment that will have arrows appended onto it
*/
export const PathArrowPoints = (
mainPath: string,
numberOfPoints: number,
lengthOfPath: number,
d3GroupSelection: Selection<any, any, any, any>,
d3PathID: string
): Selection<any, any, any, any> => {
/**
*
*/
// I want lines on 100% of the distance of the path
const totalPercent = 100;
const workingPath = new svgPathProperties(mainPath);
// Defines the length of the svg path
const svgPathLength = workingPath.getTotalLength();
// Finds the distance between two points on the path
const distanceBetweenPoints = Math.floor(lengthOfPath / numberOfPoints);
const totalPoints = Math.floor(svgPathLength / distanceBetweenPoints);
// How many points do I want per length of path.
const pointInterval = totalPercent / totalPoints;
const updatedSelection: Selection<any, any, any, any> = d3GroupSelection;
/**
*
*/
for (let point = pointInterval; point < totalPercent; point += pointInterval) {
updatedSelection
.append('text')
.append('textPath')
.attr('id', `${point}`)
.attr('fill', 'green')
.attr('dominant-baseline', 'central')
.attr('font-size', '10px')
.attr('href', `#${d3PathID}`)
.attr('startOffset', `${point}%`)
.html('➤');
}
/**
*
*/
return updatedSelection;
};
我使用来自 npm 的svgPathProperties library 来访问 svg 路径数据,并计算路径的距离、路径上我想要的点数以及我想要设置这些点的频率。
我传入了一系列参数来定义点数等,但最重要的是,我传入了我想在其上附加箭头的 d3 路径的一部分。
接下来,我创建了一个 for 循环,它将为每个箭头点运行一次,直到我们达到路径距离的 100%。我将text 元素和textPath 元素附加到svg 路径上,并为其赋予一系列属性。其中最重要的属性是 id(每个箭头需要不同的 id)、dominant-baseline:center(告诉文本保持在路径的中心)、href(这些箭头将被附加到的 svg 路径)、startOffset(每个箭头的特定长度定义为路径总距离的百分比),最后是定义文本标记 (➤) 的 .html 文本属性。然后我返回路径的修改值。
感谢 StackOverflow 社区的每一个人。我查看了很多答案来弄清楚这一切,遗憾的是,我无法在这里链接所有人。