在我试图掌握这一点的时候已经好几天了。到目前为止,我也在研究类似的问题而没有任何进展。
我有一个简单的分组条形图。我能够第一次绘制它,但没有成功更新它。如果我尝试让图表更新自己,它只会添加新数据。
我认为问题出在内部选择组的数据推导中。
代码:
// .chart -> .group -> .bar
// each group has 2 bars: one for data 'in' and another for 'out'
var data = [
{ "in" : 0, "out" : 40 },
{ "in" : 10, "out" : 39 },
{ "in" : 20, "out" : 40 }
];
var chart = d3.select('.chart');
var groupsSelection = chart.selectAll('.group');
var xScale = d3.scaleLinear().range([0, 666]);
function draw(data) {
// make data flat array of numbers to find max value for xScale domain
var dataValues = data.reduce(
(result, currentVal) => result.concat([currentVal.in, currentVal.out]),
[]
);
// set x axis domain
xScale.domain([0, d3.max(dataValues)]);
var groupsUpdate = groupsSelection.data(data);
// groups
var groups = groupsUpdate.enter()
.append('div')
.attr('class', 'group')
.merge(groupsUpdate);
// derive data from parent group
var barsUpdate = groups.selectAll('.bar')
.data(d => [d.in, d.out]);
var bars = barsUpdate.enter()
.append('div')
.attr('class', 'bar')
.merge(barsUpdate)
.text(d => d)
.style('background', 'pink')
.style('width', d => xScale(d) + 'px');
barsUpdate.exit().remove();
// groups exit
groupsUpdate.exit().remove();
}
// 1st time draw
draw(data)
// delayed data update (2nd draw)
setTimeout(() => {
var newData = [
{ "in" : 0, "out" : 40 },
{ "in" : 20, "out" : 40 }
];
draw(newData);
}, 1000);
JSFiddle:https://jsfiddle.net/0d7665nc/10/
答案 0 :(得分:1)
在draw
功能中,而不是:
var groupsUpdate = groupsSelection.data(data);
应该是:
var groupsUpdate = chart.selectAll('.group').data(data);
或者,移动变量赋值...
var groupsSelection = chart.selectAll('.group');
...到draw
内。
这样做的原因是groupsSelection
在被追加任何组之前被定义,并且它是一个空的选择。
以下是仅包含此更改的代码:
// .chart -> .group -> .bar
// each group has 2 bars: one for data 'in' and another for 'out'
var data = [{
"in": 0,
"out": 40
}, {
"in": 10,
"out": 39
}, {
"in": 20,
"out": 40
}];
var chart = d3.select('.chart');
var groupsSelection = chart.selectAll('.group');
var xScale = d3.scaleLinear().range([0, 666]);
function draw(data) {
// make data flat array of numbers to find max value for xScale domain
var dataValues = data.reduce(
(result, currentVal) => result.concat([currentVal.in, currentVal.out]), []
);
// set x axis domain
xScale.domain([0, d3.max(dataValues)]);
var groupsUpdate = chart.selectAll('.group').data(data);
// groups
var groups = groupsUpdate.enter()
.append('div')
.attr('class', 'group')
.merge(groupsUpdate);
// derive data from parent group
var barsUpdate = groups.selectAll('.bar')
.data(d => [d.in, d.out]);
var bars = barsUpdate.enter()
.append('div')
.attr('class', 'bar')
.merge(barsUpdate)
.text(d => d)
.style('background', 'pink')
.style('width', d => xScale(d) + 'px');
barsUpdate.exit().remove();
// groups exit
groupsUpdate.exit().remove();
}
// 1st time draw
draw(data)
// delayed data update (2nd draw)
setTimeout(() => {
var newData = [{
"in": 0,
"out": 40
}, {
"in": 20,
"out": 40
}];
draw(newData);
}, 1000);
.chart {
background: #fff;
width: 686px;
padding: 20px;
}
.group {
background: grey;
padding: 10px;
border: solid 1px #000;
margin: 10px 0;
}
.bar {
background: white;
margin: 5px 0;
height: 20px;
border: solid 1px yellow;
font-size: 16px;
line-height: 20px;
text-indent: 10px;
color: white;
font-weight: bold;
text-shadow: 0 1px 1px #000;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="chart"></div>