我正在尝试制作一个实时更新的分组条形图,并从本示例中进行了修改。我希望图表随着数组大小的变化而反映出我的数据数组的大小,但是在我当前的代码中,d3图表停留在数据数组的初始长度,并且不会随数组的增长而增加。达到一定长度时受到限制。
为什么我可以更新图形中条形的值,却不能随着数据集大小的变化而改变条形数?
我的代码在下面,在这个小提琴中。
<html>
<body>
<div id="disp"></div>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var main = function () {
console.log(dataset.toString())
var a = { a: 'temp', b: 50+Math.floor(Math.random() * 30)}
var b = { a: 'hum', b: 20+Math.floor(Math.random() * 20)}
// add new elements
dataset.push(a);
dataset.push(b);
// limit to 8 elements
if(dataset.length > 8){
dataset.shift();
dataset.shift();
}
//update graph
update(dataset);
}
// dataset below will show 6 bars animating
// var dataset = [{ a: 'temp', b: 5},{ a: 'hum', b: 8},{ a: 'temp', b: 4},
// { a: 'hum', b: 9},{ a: 'temp', b: 15},{ a: 'hum', b: 12}];
var dataset = [{ a: 'temp', b: 5},{ a: 'hum', b: 8}];
var w = 600;
var h = 250;
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, w], 0.1);
var rectw = 20;
var yScale = d3.scale.linear()
.domain([0, 80])
.range([0, h]);
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
var bars = svg.selectAll("g")
.data(dataset);
barsenter = bars.enter()
.append('g')
.attr('class', 'bars');
barsenter
.append("rect")
.attr('class', 'temp')
.filter(function(d){ return d.a == 'temp'})
.attr("x", function(d, i) {
return (rectw+2)*i*2;
})
.attr("y", function(d) {
return h - yScale(d.b);
})
.attr("width", rectw)
.attr("height", function(d) {
return yScale(d.b);
})
.attr("fill", function(d) {
return "rgb(" + (d.b * 4) +",0, 0)";
});
barsenter
.append("rect")
.attr('class', 'hum')
.filter(function(d){ return d.a == 'hum'})
.attr("x", function(d, i) {
return rectw+2+(rectw+2)*i*2;
})
.attr("y", function(d) {
return h - yScale(d.b);
})
.attr("width", rectw)
.attr("height", function(d) {
return yScale(d.b);
})
.attr("fill", function(d) {
return "rgb(0, 0, " + (d.b * 5) + ")";
});
// update function
var update = function(dataset) {
bars.select(".temp")
.data(dataset)
.filter(function(d){ return d.a == 'temp'})
.transition()
.delay(function(d, i) {
return i / dataset.length * 1000;
})
.duration(500)
.attr("y", function(d) {
return h - yScale(d.b);
})
.attr("height", function(d) {
return yScale(d.b);
})
.attr("fill", function(d) {
return "rgb(" + (d.b * 4) +",0, 0)";
});
bars.select(".hum")
.data(dataset)
.filter(function(d){ return d.a == 'hum'})
.transition()
.delay(function(d, i) {
return i / dataset.length * 1000;
})
.duration(500)
.attr("y", function(d) {
return h - yScale(d.b);
})
.attr("height", function(d) {
return yScale(d.b);
})
.attr("fill", function(d) {
return "rgb(0, 0, " + (d.b * 5) + ")";
});
}
main();
window.setInterval(function(){ main() }, 1000);
</script>
</body>
</html>
在阅读了这 两个描述之后,理解d3的enter()和exit()函数似乎是关键。
我编写了此代码片段,以演示带有更新功能的条形图。
//main code
// init data
var dataset = [];
function fillArray(arr){
arr.push({'value' : Math.floor(Math.random()*50)});
}
for (var i = 0; i < 4; i++) {
fillArray(dataset);
}
// add
var btnfunc = function(){
fillArray(dataset);
//update graph
update();
}
// remove
var btnfunc2 = function(){
dataset.pop()
//update graph
update();
}
// randomize
var btnfunc3 = function(){
for (var i = 0; i < dataset.length; i++) {
dataset[i].value = Math.floor(Math.random()*50);
}
//update graph
update();
}
//d3 code
//init graph
var width = 700, height = 120;
var canvas = d3.select('#disp')
.append('svg')
.attr('width', width)
.attr('height', height);
var x = d3.scale.linear()
.domain([0, 10])
.range([0, 700]);
var h = d3.scale.linear()
.domain([0, 110])
.range([0, height]);
var y = d3.scale.linear()
.domain([0, 80])
.range([200, 0]);
//create selection
var bars = canvas.selectAll("rect");
//update function
function update(){
//update selection
bars = canvas.selectAll("rect").data(dataset);
//append new bars
bars.enter().append("rect");
//bar attributes
bars
.attr('width', 20)
.attr('height', function(d){ return h(d.value); })
.attr('y', function(d){ return height - h(d.value); } )
.attr('x', function (d, i) { return i*14*2; })
.style('fill', 'red');
//remove bars
bars.exit().remove();
}
//1st display
update();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="disp"></div>
<button onclick="btnfunc()">add</button>
<button onclick="btnfunc2()">remove</button>
<button onclick="btnfunc3()">random</button>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句