我有一个相对简单的条形图。我想在.transition()
事件的数据集之间.on("click")
。我得到的是完全重绘附加到DOM ID的附加图表,而不是删除原始图表并转换或替换它。我想我误解了如何正确.remove()
。
d3.json("data/cfilt-steps.json", function(d) {
d.forEach(function(d) {
parseDate = d3.time.format("%Y-%m-%d").parse;
d.date = parseDate(d.date); d.value = +d.value;
});
margin = {top:5, right:5, bottom: 40, left:5},
height = 150 - margin.top - margin.bottom,
width = 500 - margin.left - margin.right,
barPadding = 1;
steps = crossfilter(d),
monthdim = steps.dimension(function(d){ thisDate = new Date(d.date); return thisDate.getMonth(); }),
monthgrp = monthdim.group().reduceSum(function(d){ return d.value; });
daydim = steps.dimension(function(d){ thisDate = new Date(d.date); return thisDate.getDay(); }),
daygrp = daydim.group().reduceSum( function(d) { return d.value; });
stepColor = d3.scale.threshold()
.domain([100, 150, 200, 250, 300, 400, 500])
.range(["#E3E3E3", "#D0DFD2", "#C3DABC", "#BDCB87", "#CAB44E", "#E29517", "#FF6600"]);
d3.select("#monthly-steps-previous-selector")
.on("click", function(d) {reDraw(monthgrp.all()) })
d3.select("#monthly-steps-next-selector")
.on("click", function(d) {reDraw(daygrp.all()); })
function reDraw(data) {
xScale = d3.scale.ordinal().domain(monthdim).range(0, width);
yScale = d3.scale.linear().domain([0, d3.max(data, function(d){return d.value;})]).range([height, 5]);
var stepbars = d3.select("#steps-bar")
.append("svg:svg")
.attr("width", width)
.attr("height", height)
stepbars.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d,i){ return i * width/data.length; })
.attr("y", function(d){ return yScale(d.value); })
.attr("width", width/data.length - barPadding)
.attr("height", function(d) { return height-yScale(d.value); })
.attr("fill", function(d){ return stepColor(d.value/2000); })
}
reDraw(monthgrp.all());
});
有人能告诉我这应该是什么样的,或告诉我我做错了什么?
答案 0 :(得分:1)
你的reDraw函数附加了svg,这意味着每次调用redraw时都会附加一个新的svg,因此是双图表。我建议把行
var stepbars = d3.select("#steps-bar")
.append("svg:svg")
.attr("width", width)
.attr("height", height)
在reDraw函数上方。
此外,您的重绘功能不会调用删除。我会做类似的事情:
//Select and bind to data
var selection = stepbars.selectAll("rect")
.data(data);
//Enter and create new rectangles
selection.enter()
.append("rect");
//Update all rectangles
selection.attr("x", function(d,i){ return i * width/data.length; })
.attr("y", function(d){ return yScale(d.value); })
.attr("width", width/data.length - barPadding)
.attr("height", function(d) { return height-yScale(d.value); })
.attr("fill", function(d){ return stepColor(d.value/2000); });
//Remove unused rectangles
selection.exit().remove();