gpt4 book ai didi

javascript - 在 D3.js 中使用嵌套数据

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:09:40 24 4
gpt4 key购买 nike

我正在尝试使用 D3 显示漂亮的折线图。我遇到的问题是数据格式。

我有以下数据(作为示例):

var data = [
{
label: "name",
data: [[14444123, 0.012321312],
[14444123, 0.012321312],
[14444123, 0.012321312], ...]
},{
label: "another name",
data: [[14444123, 0.012321312],
[14444123, 0.012321312],
[14444123, 0.012321312], ...]
}
];

每个条目都包含它的名称以及带有点数组的数据属性(每个点都表示为一个数组,其中 item[0] 是 x 时间戳,item[1] 是值)。

我的问题是它无法正常工作。

这是我目前拥有的 D3 代码:

var w = options.width,
h = options.height,
p = options.padding,
x = d3.scale.linear()
.domain([0, 1])
.range([0, w]),
y = d3.scale.linear()
.domain([options.ydomainstart, options.ydomainend])
.range([h, 0]);

var vis = d3.select(options.element)
.data(data)
.append("svg:svg")
.attr("width", w + p * 2)
.attr("height", h + p * 2)
.append("svg:g");

vis.append("svg:line")
.attr("stroke", '#808080')
.attr("x1", p)
.attr("x2", p)
.attr("y1", 0)
.attr("y2", h - p);

vis.append("svg:line")
.attr("stroke", '#808080')
.attr("x1", p)
.attr("x2", w)
.attr("y1", h - p)
.attr("y2", h - p);

var rules = vis.selectAll("g.rule")
.data(data)
.enter()
.append("svg:text")
.attr("x", w - p)
.attr("y", function(d, i) { return 15 + i*12; })
.attr("text-anchor", "end")
.attr("font-size", 12)
.attr("fill", function(d, i) { return defaultColors[i % 5]; })
.text(function(d) { return d.label;});

var lines = rules.data(function(d, i) {
return d.data;
})
.append("svg:path")
.attr("stroke", function(d, i) { return defaultColors[i % 5]; })
.attr("d", d3.svg.line()
.x(function(d) {
return x(d[0]);
})
.y(function(d) {
return y(d[1]);
}));

我遇到的问题出现在这部分代码中:

.x(function(d) {
return x(d[0]);
})
.y(function(d) {
return y(d[1]);
}));

“d”中的数据不是点数组 [x, y],而是每个数组中的每个值。

意思是,在第一项上,d 包含 x 坐标,在第二项上,它包含 y 坐标,在第三项上,它包含下一个点的 x 坐标,依此类推。

这就像递归地进入数组,然后对里面的每个值再次进行。

我不知道如何解决这个问题。

最佳答案

这里有一些问题。

首先,您要将 svg:path 元素附加到 svg:text 元素。在我看来,您正在尝试创建一个带有“规则”类的 svg:g 元素,但是您的代码将选择 rules 定义为一组 svg:text 元素。首先创建 svg:g 元素,然后附加 svg:text 元素:

var rules = vis.selectAll("g.rule")
.data(data)
.enter().append("svg:g")
.attr("class", "rule");

rules.append("svg:text")

第二个问题是数据运算符每组计算一次,而不是每个元素计算一次。请参阅 "Operating on Selections" 部分在 API 引用中获取更多详细信息。你在 vis 中有一个 svg:svg 元素,所以你在 rules 中有一个组,所以你的数据函数只被调用一次:

function(d, i) {
return d.data;
}

然后,生成的数据元素被映射到 rules 选择中……它已经从之前的 selectAll 中定义了数据,并在创建时追加。

简单的解决方法是使用 map运算符而不是数据运算符,每个元素计算一次而不是每个组计算一次。

rules.append("svg:path")
.map(function(d) { return d.data; })
.attr("d", d3.svg.line()

或者,您可以将数据直接传递给线生成器,但这需要您提前声明线生成器而不是内联它:

var line = d3.svg.line()
.x(function(d) { return x(d[0]); })
.y(function(d) { return y(d[1]); });

rules.append("svg:path")
.attr("d", function(d) { return line(d.data); })

希望这对您有所帮助!

关于javascript - 在 D3.js 中使用嵌套数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7111584/

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