gpt4 book ai didi

javascript - 将 SVG 路径 d 属性转换为点数组

转载 作者:可可西里 更新时间:2023-11-01 01:36:18 28 4
gpt4 key购买 nike

当我可以创建一行时:

var lineData = [{ "x": 50, "y": 50 }, {"x": 100,"y": 100}, {"x": 150,"y": 150}, {"x": 200, "y": 200}];
var lineFunction = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate("basis");
var myLine = lineEnter.append("path")
.attr("d", lineFunction(lineData))

现在我想向此 lineArray 的第二个点添加文本:

lineEnter.append("text").text("Yaprak").attr("y", function(d){ 
console.log(d); // This is null
console.log("MyLine");
console.log(myLine.attr("d")) // This is the string given below, unfortunately as a String
// return lineData[1].x
return 10;

});

console.log(myLine.attr("d")) 行的输出:

M50,50L58.33333333333332,58.33333333333332C66.66666666666666,66.66666666666666,83.33333333333331,83.33333333333331,99.99999999999999,99.99999999999999C116.66666666666666,116.66666666666666,133.33333333333331,133.33333333333331,150,150C166.66666666666666,166.66666666666666,183.33333333333331,183.33333333333331,191.66666666666663,191.66666666666663 L200,200

我可以得到字符串格式的路径数据。我可以将此数据转换回 lineData 数组吗?或者,是否有任何其他简单的方法可以在附加文本时重新生成或获取 lineData?

请引用this JSFiddle .

最佳答案

SVGPathElement API 具有获取此信息的内置方法。您不需要自己解析数据字符串。

由于您将行的选择存储为变量,因此您可以使用 myLine.node() 轻松访问路径元素的 api 以引用 path 元素本身.

例如:

var pathElement = myLine.node();

然后您可以通过访问 pathSegList 属性来访问用于构建路径的命令列表:

var pathSegList = pathElement.pathSegList;

使用此对象的 length 属性,您可以轻松地遍历它以获取与每个路径段关联的坐标:

for (var i = 0; i < pathSegList.length; i++) {
console.log(pathSegList[i]);
}

检查控制台输出,您会发现每个路径段都有 xy 的属性,表示该段的端点。对于贝塞尔曲线、圆弧等,控制点也被指定为x1y1x2y2 根据需要。

在您的情况下,无论您是使用此方法还是选择自己解析字符串,您都会遇到困难,因为您使用了 interpolate('basis') 进行线插值。因此,线生成器输出 6 个命令(在您的特定情况下)而不是 4 个,并且它们的端点并不总是对应于数据中的原始点。如果您使用 interpolate('linear'),您将能够重建原始数据集,因为线性插值与路径数据输出具有一一对应关系。

假设您使用线性插值,可以按如下方式重建原始数据集:

var pathSegList = myLine.node().pathSegList;

var restoredDataset = [];

// loop through segments, adding each endpoint to the restored dataset
for (var i = 0; i < pathSegList.length; i++) {
restoredDataset.push({
"x": pathSegList[i].x,
"y": pathSegList[i].y
})
}

编辑:

至于在附加文本时使用原始数据...我假设您正在寻找将标签附加到点的方法,无需经历重建数据的所有麻烦。事实上,真正的问题是你从来没有首先使用数据绑定(bind)来制作你的折线图。尝试为路径使用 .datum() 方法绑定(bind)数据,为标签使用 .data() 方法。此外,您可能想重命名 lineEnter,因为您没有使用输入选择,它只是代表一个组。例如:

// THIS USED TO BE CALLED `lineEnter`
var lineGroup = svgContainer.append("g");

var myLine = lineGroup.append("path")
// HERE IS WHERE YOU BIND THE DATA FOR THE PATH
.datum(lineData)
// NOW YOU SIMPLY CALL `lineFunction` AND THE BOUND DATA IS USED AUTOMATICALLY
.attr("d", lineFunction)
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");

// FOR THE LABELS, CREATE AN EMPTY SELECTION
var myLabels = lineGroup.selectAll('.label')
// FILTER THE LINE DATA SINCE YOU ONLY WANT THE SECOND POINT
.data(lineData.filter(function(d,i) {return i === 1;})
// APPEND A TEXT ELEMENT FOR EACH ELEMENT IN THE ENTER SELECTION
.enter().append('text')
// NOW YOU CAN USE THE DATA TO SET THE POSITION OF THE TEXT
.attr('x', function(d) {return d.x;})
.attr('y', function(d) {return d.y;})
// FINALLY, ADD THE TEXT ITSELF
.text('Yaprak')

关于javascript - 将 SVG 路径 d 属性转换为点数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25384052/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com