作为对 rioV8 出色答案的快速跟进,我能够让他们的代码正常工作,但需要对其进行概括以使用两种以上的颜色。如果其他人有类似的要求,这里是代码:
function pathPoints(path, stepLength, duoProp) {
// get the properties of the path
var props = spp.svgPathProperties(path);
var length = props.getTotalLength();
// build a list of segments to use as approximation points
var tList = d3.range(0, length, stepLength);
tList.push(length);
var tProps = tList.map(function (d) {
return props.getPropertiesAtLength(d);
});
// incorporate the percentage
var pFactor = function pFactor(percent) {
return (percent - 0.5) * duoProp.width;
};
// for each path segment, calculate offset points
tProps.forEach(function (p) {
// create array to store modified points
p.x_arr = [];
p.y_arr = [];
// calculate offset at 0%
p.x_arr.push(p.x - pFactor(0) * p.tangentY);
p.y_arr.push(p.y + pFactor(0) * p.tangentX);
// calculate offset at each specified percent
duoProp.percents.forEach(function(perc) {
p.x_arr.push(p.x - pFactor(perc) * p.tangentY);
p.y_arr.push(p.y + pFactor(perc) * p.tangentX);
});
// calculate offset at 100%
p.x_arr.push(p.x - pFactor(1) * p.tangentY);
p.y_arr.push(p.y + pFactor(1) * p.tangentX);
});
var format1d = d3.format(".1f");
var createPath = function createPath(forward, backward) {
var fp = tProps.map(function (p) {
return forward(p);
});
var bp = tProps.map(function (p) {
return backward(p);
});
bp.reverse();
return 'M' + fp.concat(bp).map(function (p) {
return format1d(p[0]) + "," + format1d(p[1]);
}).join(' ') + 'z';
};
// create a path for each projected point
var paths = [];
for(var i=0; i <= duoProp.percents.length; i++) {
paths.push(createPath(function (p) { return [p.x_arr[i], p.y_arr[i]]; }, function (p) { return [p.x_arr[i+1], p.y_arr[i+1]]; }));
}
return paths;
}
// generate the line
var duoProp = { color: ["red", "blue", "green"], percents: [0.5, 0.7], width: 15 };
var duoPath = pathPoints("M30,30C160,30 150,90 250,90S350,210 250,210", 10, duoProp);
duoPath.forEach( (d, i) => {
svg.append("path")
.attr("d", d)
.attr("fill", duoProp.color[i])
.attr("stroke", "none");
});
请注意,percents 数组指定笔画的累积百分比,而不是宽度的单个百分比。例如。在上面的示例中,红色笔划的宽度为 0% 到 50%,蓝色笔划的宽度为 50% 到 70%,绿色笔划的宽度为 70% 到 100%。