3
我有一個垂直堆疊條形圖,並且想要動態刪除rect
元素。爲此,我遵循基本的輸入/更新/退出程序。儘管如此,即使它們的寬度= 0,它們似乎也會被添加;D3更新垂直堆疊條形圖
var drawBars = function(data) {
var margin = {top: 5, right: 20, bottom: 5, left: 170},
width = 1020 - margin.left - margin.right,
height = 1820 - margin.top - margin.bottom,
scope = this;
var x = d3.scale.linear()
.rangeRound([0, width-150]);
var y = d3.scale.ordinal()
.rangeBands([0,height], .2, 3);
var color = d3.scale.category20c();
var xAxis = d3.svg.axis()
.scale(x)
.orient("top")
.tickSize(0)
.tickFormat(d3.format("s"));
var yAxis = d3.svg.axis()
.scale(y)
.tickSize(0)
.orient("left");
var svg = d3.select('#barchart svg')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var createData = function(filter) {
var data = d3.nest()
.key(function(d) { return d.org; })
.key(function(d){ return d.taskforce_id })
.rollup(function(v){ return v.length })
.entries(scope.rawData['participants']);
_.each(data, d => {
_.extend(d, _.object(_.map(d.values, c => {
if (typeof filter !== 'undefined') {
if (c.key == filter) {
return [c.key, c.values];
}
return [c.key, 0];
}
return [c.key, c.values];
})));
delete d.values;
});
data.forEach(function(d) {
var y0 = 0;
d.orgs = ["A", "B", "C"].map(function(org) {
if (d[org] === undefined) {
return {name: org, y0: 0, y1: 0};
} else {
return {name: org, y0: y0, y1: y0 += +d[org]};
}
});
d.total = d3.max(d.orgs, d => { return d.y1; });
});
data.sort(function(x, y){
return d3.descending(x.total, y.total);
});
return data;
};
var redrawChart = function(filter) {
var data = createData(filter);
console.log(data);
x.domain([0, d3.max(data, function(d) { return d.total; })]);
y.domain(data.map(function(d) { return d.key; }));
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "key"; }));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + 15 + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end");
/////////
//ENTER//
/////////
var chartRow = svg.selectAll("g.chartRow")
.data(data);
var newRow = chartRow
.enter()
.append("g")
.attr("class", "chartRow")
.attr("transform", function(d) { return "translate(0, " + y(d.key) + ")"; });
var rectRow = newRow.selectAll(".bar")
.data(function(d) { return d.orgs; });
rectRow
.enter()
.append("rect")
.attr("class", function(d) { return "bar t_"+ d.name; })
.attr("height", y.rangeBand())
.on('click', function(d){
redrawChart(d.name);
})
.style("fill", function(d) { return color(d.name); });
//////////
//UPDATE//
//////////
chartRow.selectAll('rect').transition()
.duration(300)
.attr("width", function(d) { return x(d.y1) - x(d.y0); })
.attr("x", function(d) { return x(d.y0); })
.attr("opacity",1);
////////
//EXIT//
////////
chartRow.exit().selectAll("rect.bar").transition()
.style("opacity","0")
.attr("transform", "translate(0," + (height + margin.top + margin.bottom) + ")")
.remove();
};
redrawChart();
var legend = svg.selectAll(".legend")
.data(color.domain().slice().reverse());
var legends = legend.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 25 + ")"; });
legend.exit().remove();
legends.append("rect")
.attr("x", width - 28)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legends.append("text")
.attr("x", width - 34)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
legends.append("text")
.attr("x", width + 14)
.attr("y", 9)
.attr("class", "numbers")
.attr("dy", ".35em")
.style("text-anchor", "end");
};
當我console.log
的data
一切似乎確定,所以過濾的工作原理。但是,rect
元素的寬度似乎使用舊數據集。同樣,傳說和軸被複制
小提琴這裏:https://jsfiddle.net/4nm44fgt/
任何見解?
我們不知道數據如何變化,但是從根本代碼,rectRow選擇從d.orgs獲取其數據。你應該對update chartRow的選擇做同樣的事 – Marcelo
你發佈了很多代碼,但是我們不得不猜測從scale到函數調用的很多事情。你爲什麼不發佈一個MCVE?例如,小提琴/鋼筆/蹲跳者? –
好點,只是加了一個小提琴 –