我是D3的新手,我正在开发可重复使用的条形图,可以发送新数据,它会根据收到的新数据更新现有图表。
目前,它正确地绘制了图表,但是当数据发生变化时,它会在新图表上覆盖新数据的图表,而不是更新它。
我认为问题必须与我的bars
变量以及我如何绑定我的数据但我无法确定。数据只是reddit JSON API中reddit帖子的分数。
实施例:
我的图表代码是:
d3.namespace.barChart = function() {
var data, group, height, margin = {top: 0, right: 0, bottom: 0, left: 0}, width;
function chart(container) {
group = container;
// Determine the max score and timestamps from the Reddit data for use in our scales
var maxScore = d3.max(data, function(d) { return d.data.score; });
data.forEach(function(d) {
d.data.created *= 1000;
});
// Create the scales to ensure data fits in the graphs
var xScale = d3.scale.ordinal()
.domain(d3.range(data.length))
.rangeBands([0, width], 0.25);
var yScale = d3.scale.linear()
.domain([0, maxScore])
.range([0, height]); // .range(starting, )
var yScaleLine = d3.scale.linear()
.domain([0, maxScore])
.range([height, 0]);
var colorScale = d3.scale.linear()
.domain(d3.extent(data, function(d) { return d.data.score; }))
.range(['#DA4453', '#A0D468'])
.interpolate(d3.interpolateRgb);
// Create the Y-Axis function. yScaleLine is used as the scale to ensure
// that the data goes from 0 at the bottom left to max score in the top left
var yAxis = d3.svg.axis()
.scale(yScaleLine)
.orient('left');
// Setup our chart using our width, height and margins.
group.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom);
// Add a group element for the primary graphic that is moved
// using the margins. Left and top are used since 0,0 is top left corner
var graph = group.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Append our yAxis to the SVG canvas and move it according to the margins
group.append('g')
.attr('class', 'y axis')
.call(yAxis)
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Inside of our group, we need to make a 'rect' for each item in the dataset
// We link the data, and append one rect for each piece of data.
var bars = graph.selectAll('rect')
.data(data, function(d) { return d.data.id; });
bars.enter()
.append('rect');
// We begin with the height of each bar as 0 allowing us to transition to their full height
bars.attr({
x: function(d, i) { return xScale(i); },
y: function() { return height; },
height: 0,
width: xScale.rangeBand(),
fill: function(d) { return colorScale(d.data.score); }
});
// Events must be linked before a transition to function
bars.on('mouseover', function() {
d3.select(this).attr('fill', '#000');
})
.on('mouseleave', function() {
d3.select(this).attr('fill', function(d) { return colorScale(d.data.score); });
});
bars.transition().duration(150)
.attr({
x: function(d, i) { return xScale(i); },
y: function(d) { return height - yScale(d.data.score); },
height: function(d) { return yScale(d.data.score); },
width: xScale.rangeBand()
});
bars.exit().transition().duration(150).attr({ height: 0.0001 }).remove();
}
修改
在深入研究创建的源代码后,它似乎没有更新,而只是继续为所有g
创建一个新的svg rect
元素。删除group.append('g')
链会修复图表不更新但图表不再存在于组中并使SVG非常混乱。