我的D3 js图表未显示数据,请指导我如何正确填充线和面数据,
数据代码-这就是我生成数据的方式
var data = [];
var currentValue = 0;
var random = d3.random.normal(0, 20);
var obj = {};
for (var i = 0; i < 20; i++) {
var currentDate = new Date();
currentDate.setDate(currentDate.getDate() + i);
if (i === 0) {
currentValue = 0;
} else if (i === 1) {
currentValue = 0;
} else if (i === 5) {
currentValue = 0;
} else if (i === 10) {
currentValue = 0;
} else if (i === 19) {
currentValue = 0;
} else {
currentValue = currentValue + random();
}
obj.startTime = currentDate;
obj.magnitude = currentValue;
data.push(obj);
}
console.log(data);
我在这里有一个代码沙箱,请指导我- https://codesandbox.io/s/frosty-tu-18isr
谢谢。我是D3js的新手。
答案 0 :(得分:2)
这里的问题与D3无关,这只是对象引用在Javascript中的工作方式。当您这样做时...
obj.startTime = currentDate;
obj.magnitude = currentValue;
data.push(obj);
...您要更改同一对象,就是这个...
var obj = {};
...,并将其推入data
数组。因此,所有属性都是相同的(最后一次迭代)。我们可以轻松地演示它。看一下这个数组,它有10个对象:
const obj = {foo:42};
const myArray = d3.range(10).map(()=>obj);
console.log(JSON.stringify(myArray))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
现在让我们只更改第三个对象:
myArray[2].foo = 17;
但是,这将改变所有这些:
const obj = {foo:42};
const myArray = d3.range(10).map(()=>obj);
myArray[2].foo = 17;
console.log(JSON.stringify(myArray))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
之所以会发生这种情况,是因为它们都是对同一个对象的引用。
解决方案:最简单的解决方案是在每次迭代时将整个对象(一个新对象)推送:
data.push({startTime : currentDate, magnitude: currentValue});
这是演示:
var data = [];
var currentValue = 0;
var random = d3.random.normal(0, 20);
for (var i = 0; i < 20; i++) {
var currentDate = new Date();
currentDate.setDate(currentDate.getDate() + i);
if (i === 0) {
currentValue = 0;
} else if (i === 1) {
currentValue = 0;
} else if (i === 5) {
currentValue = 0;
} else if (i === 10) {
currentValue = 0;
} else if (i === 19) {
currentValue = 0;
} else {
currentValue = currentValue + random();
}
data.push({
startTime: currentDate,
magnitude: currentValue
});
}
console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>