问题描述
我不知道这是一个d3错误,或者如果我做错了。请查看以下内容:
I'm not sure if this is a d3 bug or if I'm doing something wrong. Take a look at the following:
var data = [
{ value: 20, color: 'red' },
{ value: 30, color: 'blue' },
{ value: 30, color: 'purple' } // Same value as 2nd object
];
var w = 140,
h = d3.max(data, function(d){ return d.value; }) + 30,
barPadding = 4,
topPadding = 1,
bottomPadding = 20;
var svg = d3.select('#chart')
.append('svg:svg')
.attr('width', w)
.attr('height', h);
var rects = svg.selectAll('rect')
.data(data, function(d){ console.log(d); return d.value; }) // All 3 objects found here
.enter()
.append('rect')
.attr('x', function(d,i){ console.log(i); return i * w / data.length + 1; }) // Last data object ignored, not placed at all
.attr('y', function(d){ return h - d.value - topPadding - bottomPadding })
.attr('width', w / data.length - barPadding - 3 )
.attr('height', function(d) { return d.value })
.attr('fill', function(d) { return d.color })
.attr('stroke', '#333')
.attr('stroke-width', 2);
text = svg.selectAll('text')
.data(data, function(d){ return d.value; })
.enter()
.append('text')
.text(function(d){ return d.value; })
.attr('x', function(d,i){ return i * w / data.length + 20; })
.attr('y', function(d,i){ return h - 0; })
.attr("text-anchor", "middle")
.attr("font-size", "20px")
.attr("fill", "#333");
您可以在我的数据对象中看到第二个和第三个对象具有相同的值。
You can see in my data objects, the 2nd and 3rd objects have the same "value".
当创建svg rect时,第三个数据对象将被忽略,因此不会放置在图表中。如果将第三个对象的值从30更改为31或其他值,则可以看到条显示出来。但由于它与第二个对象的值相同,因此它不会显示。
When the svg rects are being created, the 3rd data object is ignored and as a result, not placed in the chart. If you change the value of the 3rd object from 30 to 31 or something else, you can see the bar does show up then. But since it's the same as the 2nd object's value, it doesn't show up.
为什么是这样?如何防止这种情况?它在这里的代码是什么会导致这? rects.data()
函数查看所有三个对象,你可以看到 console.log()
I
Why is this? How do you prevent this? What is it in the code here that would cause this? the rects.data()
function see's all three objects, as you can see with the console.log()
I added into the function.
推荐答案
将数据与现有数据进行匹配的方式会导致问题,特别是
The way in which you are matching the data to existing data is causing the problem, in particular the line
.data(data, function(d){ return d.value; })
这告诉d3,如果两个数据对象的 value
属性一样。这是你的第二和第三个对象的情况,因此只有第一个被添加。如果你想要这两个,你可以省略告诉d3如何比较数据对象的函数(因此依赖于数组索引匹配的默认行为),或者改变函数。 color
。
This tells d3 that you consider two data objects the same if their value
attribute is the same. And this is the case for your second and third objects, hence only the first is added. If you want both, you can either omit the function that tells d3 how to compare data objects (and thus rely on the default behaviour of matching by array index), or change that function to take e.g. color
into account as well.
只是为了总结,你看到的不是一个错误, :)这个行为是完全预期和想要的。
Just to summarise, what you are seeing is not a bug, but a feature :) This behaviour is entirely expected and wanted.
这篇关于具有重复“values”的复杂数据对象=缺少图表条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!