我有一个D3条形图,最初绘制了一些数据。我将每2秒获得一次新数据。此新数据可能是新项目或现有项目的新计数。我想相应地更新图表。
这就是我的尝试:
https://jsfiddle.net/rutwick/an1d95h1/2/
var sales = [
{ product: 'Hoodie', count: 7 },
{ product: 'Jacket', count: 6 },
{ product: 'Snuggie', count: 9 },
{ product: 'Beanie', count: 8 }
];
var startTimer = false;
function drawGraph() {
//select the svg
var svg = d3.select('svg');
//Select all the rect elements and assign the data to them
var rects = svg.selectAll('rect')
.data(sales);
//This will access the rect element for creating new rect elements
var newRects = rects.enter();
// recall that scales are functions that map from
// data space to screen space
// Max limit for Y axis
var maxCount = d3.max(sales, function(d, i) {
return d.count;
});
//X axis will have bars, hence ordinal scale used
//domain - data - Product values
//Rangebound specifies max limit and the padding around the bands
var x = d3.scale.ordinal()
.domain(sales.map(function(d) {
return d.product;
}))
.rangeRoundBands([0, 500], 0.10); //300 = Total width of all bars, 0.10 = Factor of space between the bars
//Y axis is linear, hence linear scale used
var y = d3.scale.linear()
.range([400, 0])
.domain([0, maxCount]);
newRects.append('rect')
.attr('x', function(d) {
return x(d.product);
})
.attr('y', function(d, i) {
return y(d.count);
})
.attr('width', x.rangeBand())
.attr('height', function(d, i) {
return 400 - y(d.count);
});
startTimer = true;
rects.exit().remove();
}
function updateGraph(){
if(!startTimer) {
return;
}
var rand = Math.floor(Math.random() * sales.length);
/*if(sales[rand].count % 2 === 0) {
sales[rand].count += 2;
console.log(sales[rand].count);
}*/
sales.push({ product: 'Denim', count: 1 });
sales.push({ product: 'Sweatshirt', count: 12 });
drawGraph();
}
setInterval(updateGraph, 2000);
drawGraph();
它会更新,但不会重绘图表。只需在旧的栏上添加新栏。我目前的计划包括使用jQuery删除所有rect元素,但我不知道它是否可行。
在x轴和y轴上更新整个图表究竟需要做些什么?
答案 0 :(得分:2)
你可以这样做:
首先,你需要像这样定义对象:
var rects = svg.selectAll('rect')
.data(sales, function(d){/*Unique ID of a record*/ return d.product;});
现在创建这样的矩形:
newRects.append('rect');
现在用新的宽度和高度更新所有的矩形。
//do update
d3.selectAll("rect")
.attr('class', "rects")
.attr('x', function(d) {
console.log(d)
return x(d.product);
})
.attr('y', function(d, i) {
return y(d.count);
})
.attr('width', x.rangeBand())
.attr('height', function(d, i) {
return 400 - y(d.count);
});
最后删除已删除数据的栏:
//remove not there
rects.exit().remove()
您的代码未更新的问题:
执行此操作时,属性仅在create
上更新newRects.append('rect')
.attr('x', function(d) {
return x(d.product);
})
.attr('y', function(d, i) {
return y(d.count);
})
.attr('width', x.rangeBand())
.attr('height', function(d, i) {
return 400 - y(d.count);
});
工作代码here
希望这有帮助!
答案 1 :(得分:0)
您可以使用setInterval()函数在给定时间段内调用特定函数。因此,您刚刚编写了一个更新函数来更新图形并将其设置为setInterval函数的参数。
例如:
<!DOCTYPE HTML>
<html>
<head>
<script>
window.onload = function () {
var dps1 = []; // dataPoints
var dps2 = []; // dataPoints
var dps3 = []; // dataPoints
var dps4= []; // dataPoints
var chart = new CanvasJS.Chart("chartContainer", {
title :{
text: "Dynamic Data"
},
axisY: {
includeZero: false
},
data: [{
type: "spline",
dataPoints: dps1
},{
type: "spline",
dataPoints: dps2
},{
type: "spline",
dataPoints: dps3
},{
type: "spline",
dataPoints: dps4
}
]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 1000;
var dataLength = 20; // number of dataPoints visible at any point
var updateChart = function (count) {
count = count || 1;
for (var j = 0; j < count; j++) {
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps1.push({
x: xVal,
y: yVal
});
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps2.push({
x: xVal,
y: yVal
});
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps3.push({
x: xVal,
y: yVal
});
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps4.push({
x: xVal,
y: yVal
});
xVal++;
}
if (dps1.length > dataLength) {
dps1.shift();
}
if (dps2.length > dataLength) {
dps2.shift();
}
if (dps3.length > dataLength) {
dps3.shift();
}
if (dps4.length > dataLength) {
dps4.shift();
}
chart.render();
};
updateChart(dataLength);
setInterval(function(){updateChart()}, updateInterval);
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 370px; max-width: 920px; margin: 0px auto;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</body>
</html>
在这里,我每隔一秒钟更新一次图表。