//add circles with price data
svgContainer.selectAll("circle")
.data(priceData)
.enter()
.append("svg:circle")
.attr("r", 6)
.style("fill", "none")
.style("stroke", "none")
.attr("cx", function(d, i) {
return x(convertDate(dates[i]));
})
.attr("cy", function(d) { return y1(d); })
//add circles with difficulty data
svgContainer.selectAll("circle")
.data(difficultyData)
.enter()
.append("svg:circle")
.attr("r", 6)
.style("fill", "none")
.style("stroke", "none")
.attr("cx", function(d, i) {
return x(convertDate(dates[i]));
})
.attr("cy", function(d) { return y2(d); })
在上半部分,带有价格数据的圆圈沿图表图表中的相关行添加。现在我想对下半部分做同样的事情,将不同数据的圆圈添加到不同的行。但是,第一个圈子'数据被第二个圆圈覆盖'数据,第二个圆圈永远不会被绘制。
我认为我对这里发生的事情有直觉,但有人可以解释究竟是做了什么以及如何解决问题?
可能的参考:
"键功能还决定了进入和退出选择: 旧数据中没有相应密钥的新数据 成为输入选择,以及没有的旧数据 新数据中的相应键成为退出选择。该 剩余数据成为默认的更新选择。"
答案 0 :(得分:1)
首先,了解selectAll()
,data()
,enter()
从这个伟大的post做了什么。
问题是,由于circle
元素在我们到达下半部分时已存在,因此新提供的数据只会覆盖圆圈而不是创建新圆圈。为防止这种情况发生,您需要在后半部分的key function
函数中指定data()
。然后,第一批圈子不会被覆盖。
//add circles with price data
svgContainer.selectAll("circle")
.data(priceData)
.enter()
.append("svg:circle")
.attr("r", 6)
.style("fill", "none")
.style("stroke", "none")
.attr("cx", function(d, i) {
return x(convertDate(dates[i]));
})
.attr("cy", function(d) { return y1(d); })
//add circles with difficulty data
svgContainer.selectAll("circle")
.data(difficultyData, function(d) { return d; }) // SPECIFY KEY FUNCTION
.enter()
.append("svg:circle")
.attr("r", 6)
.style("fill", "none")
.style("stroke", "none")
.attr("cx", function(d, i) {
return x(convertDate(dates[i]));
})
.attr("cy", function(d) { return y2(d); })
答案 1 :(得分:1)
您可以将圈子添加到两个不同的组中,例如:
//add circles with price data
svgContainer.append("g")
.attr("id", "pricecircles")
.selectAll("circle")
.data(priceData)
.enter()
.append("svg:circle")
.attr("r", 6)
.style("fill", "none")
.style("stroke", "none")
.attr("cx", function(d, i) {
return x(convertDate(dates[i]));
})
.attr("cy", function(d) { return y1(d); })
//add circles with difficulty data
svgContainer.append("g")
.attr("id", "datacircles")
.selectAll("circle")
.data(difficultyData)
.enter()
.append("svg:circle")
.attr("r", 6)
.style("fill", "none")
.style("stroke", "none")
.attr("cx", function(d, i) {
return x(convertDate(dates[i]));
})
.attr("cy", function(d) { return y2(d); })
如果圈子在不同的组中,则不会被覆盖
答案 2 :(得分:0)
发生的事情是你:
在FIRST HALF中:
然后,在第二部分:
__data__
。 / LI>
<强>解决方案吗
我认为关键功能不是你想要的。一个关键的功能是在数据中选择一个唯一字段来连接数据而不是索引,因为索引不关心数据或元素是否重新排序等等。当我想确保selectAll(..).data(..)时,单个数据集已正确映射回自身。
我将用于您的问题的解决方案是将与样式类分组,以便为不同的数据集创建两个完全独立的圆圈组。请参阅下面的我的更改。
//add circles with price data
svgContainer.selectAll("circle.price")
.data(priceData)
.enter()
.append("svg:circle")
.attr("class", "price")
.attr("r", 6)
.style("fill", "none")
.style("stroke", "none")
.attr("cx", function(d, i) {
return x(convertDate(dates[i]));
})
.attr("cy", function(d) { return y2(d); })
//add circles with difficulty data
svgContainer.selectAll("circle.difficulty")
.data(difficultyData)
.enter()
.append("svg:circle")
.attr("class", "difficulty")
.attr("r", 6)
.style("fill", "none")
.style("stroke", "none")
.attr("cx", function(d, i) {
return x(convertDate(dates[i]));
})
.attr("cy", function(d) { return y2(d); })
//add circles with price data
svgContainer.selectAll("circle.price")
.data(priceData)
.enter()
.append("svg:circle")
.attr("class", "price")
.attr("r", 6)
.style("fill", "none")
.style("stroke", "none")
.attr("cx", function(d, i) {
return x(convertDate(dates[i]));
})
.attr("cy", function(d) { return y2(d); })
//add circles with difficulty data
svgContainer.selectAll("circle.difficulty")
.data(difficultyData)
.enter()
.append("svg:circle")
.attr("class", "difficulty")
.attr("r", 6)
.style("fill", "none")
.style("stroke", "none")
.attr("cx", function(d, i) {
return x(convertDate(dates[i]));
})
.attr("cy", function(d) { return y2(d); })
使用此方法,您将始终使用单独数据集的正确圆元素。之后,如果您在数据中拥有比仅使用索引更好的唯一值,您还可以为两个调用添加自定义键功能。
答案 3 :(得分:0)
我和OP有相同的问题。而且,我想出了一种类似于上述tomtomtom的解决方案。简而言之:使用SVG组元素可以对不同数据但元素类型相同的内容进行处理。关于SVG组元素为何在D3.js中如此有用的更多说明,并在此处提供了一个很好的示例:
https://www.dashingd3js.com/svg-group-element-and-d3js
我在这里的答复包括一个示例的jsfiddle,该示例涉及2个不同的数据集,它们在同一SVG上同时可视化但具有不同的属性。如下所示,我创建了两个不同的组元素(circleGroup1和circleGroup2),每个组元素将处理不同的数据集:
var ratData1 = [200, 300, 400, 600];
var ratData2 = [32, 57, 112, 293];
var svg1 = d3.select('body')
.append('svg')
.attr('width', 500)
.attr('height', 400);
var circleGroup1 = svg1.append("g");
var circleGroup2 = svg1.append("g");
circleGroup1.selectAll("circle")
.data(ratData1)
.enter().append("circle")
.attr("cy", 60)
.attr("cx", function(d, i) { return i * 100 + 30; })
.attr("r", function(d) { return Math.sqrt(d); });
circleGroup2.selectAll("circle")
.data(ratData2)
.enter()
.append("circle")
.attr("r", function(d, i){
return i*20 + 5;
})
.attr("cy", 100)
.attr("cx", function(d,i){ return i*100 +30;})
.style('fill', 'red')
.style('fill-opacity', '0.3');