[英]D3 horizontal bar chart will not transition to new dataset
我正在研究d3.js水平條形圖( http://bl.ocks.org/juan-cb/ab9a30d0e2ace0d2dc8c ),它會根據用戶選擇來更新/轉換。 目前,我已向圖形添加了標簽,但不再更新。 不知道問題出在哪里。 條形圖應從左側開始,但由於某種原因也已移至右側。 為了在標簽上添加標簽,我添加了“ g”元素來同時容納rect和文本。 任何幫助將不勝感激。
JsFiddle- https: //jsfiddle.net/fewpwqhd/1/
JS
datasetTotal = [{
label: "Category 1",
value: 19
}, {
label: "Category 2",
value: 5
}, {
label: "Category 3",
value: 13
}, {
label: "Category 4",
value: 17
}, {
label: "Category 5",
value: 21
}, {
label: "Category 6",
value: 25
}];
datasetOption1 = [{
label: "Category 1",
value: 22
}, {
label: "Category 2",
value: 33
}, {
label: "Category 3",
value: 4
}, {
label: "Category 4",
value: 15
}, {
label: "Category 5",
value: 36
}, {
label: "Category 6",
value: 0
}];
datasetOption2 = [{
label: "Category 1",
value: 10
}, {
label: "Category 2",
value: 20
}, {
label: "Category 3",
value: 30
}, {
label: "Category 4",
value: 5
}, {
label: "Category 5",
value: 12
}, {
label: "Category 6",
value: 23
}];
d3.selectAll("input").on("change", selectDataset);
function selectDataset() {
var value = this.value;
if (value == "total") {
change(datasetTotal);
} else if (value == "option1") {
change(datasetOption1);
} else if (value == "option2") {
change(datasetOption2);
}
}
var margin = {
top: (parseInt(d3.select('body').style('height'), 10) / 20),
right: (parseInt(d3.select('body').style('width'), 10) / 20),
bottom: (parseInt(d3.select('body').style('height'), 10) / 20),
left: (parseInt(d3.select('body').style('width'), 10) / 5)
},
width = parseInt(d3.select('body').style('width'), 10) - margin.left - margin.right,
height = parseInt(d3.select('body').style('height'), 10) - margin.top - margin.bottom;
var div = d3.select("body").append("div").attr("class", "toolTip");
var formatPercent = d3.format("");
var y = d3.scale.ordinal()
.rangeRoundBands([height, 0], .2, 0.5);
var x = d3.scale.linear()
.range([0, width]);
var xAxis = d3.svg.axis()
.scale(x)
.tickSize(-height)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
//.tickFormat(formatPercent);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
d3.select("input[value=\"total\"]").property("checked", true);
change(datasetTotal);
function change(dataset) {
y.domain(dataset.map(function(d) {
return d.label;
}));
x.domain([0, d3.max(dataset, function(d) {
return d.value;
})]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.select(".y.axis").remove();
svg.select(".x.axis").remove();
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(0)")
.attr("x", 50)
.attr("dx", ".1em")
.style("text-anchor", "end")
.text("Option %");
var bar = svg.selectAll(".bar")
.data(dataset, function(d) {
return d.label;
})
// new data:
.enter().append("g");
bar.append("rect")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.value);
})
.attr("y", function(d) {
return y(d.label);
})
.attr("width", function(d) {
return width - x(d.value);
})
.attr("height", y.rangeBand());
bar.append("text")
.attr("x", function(d) {
return x(d.value) - 3;
})
.attr("text-anchor", "end")
.attr("y", function(d) {
return y(d.label) + y.rangeBand() / 2;
})
.attr("dy", ".35em")
.text(function(d) {
return d.value;
});
var bars = d3.select("svg").selectAll("g.rects").data(dataset);
// removed data:
bars.exit().remove();
// updated data:
bars.transition()
.duration(750)
.attr("x", function(d) {
return 0;
})
.attr("y", function(d) {
return y(d.label);
})
.attr("width", function(d) {
return x(d.value);
})
.attr("height", y.rangeBand());
};
這是我的建議:由於您要將矩形和文本元素都附加到<g>
(組),因此您的enter-update-exit模式應適用於組,而不適用於矩形和文本:
var bar = svg.selectAll(".bar")
.data(dataset, function(d) {
return d.label;
});
var barExit = bar.exit().remove();
var barEnter = bar.enter()
.append("g")
.attr("class", "bar");
實際上,由於您的數據集始終有6個類別,因此您甚至不需要所有這些類別(代碼可能會大大縮短)。
這是您更新的小提琴: https : //jsfiddle.net/2523onr3/
附言:我自由地使標桿從左到右而不是從右到左增長。 如果不正確,只需更改x
和width
屬性。
我會對這種方法的利弊感興趣嗎?
https://jsfiddle.net/sjp700/2523onr3/2/
bar = svg.selectAll(".bar")
.data(dataset)
bar_g = bar.enter()
.append("g")
.attr("class", "bar")
.transition()
.attr("transform", function (d) { return "translate(" + x(0) + "," + y(d.label) + ")"; });
svg.selectAll(".bar")
.append("rect")
.attr("class", "rectband");
svg.selectAll(".bar")
.append("text")
.attr("class", "textband");
bar.selectAll(".textband")
.attr("transform", function (d) { return "translate(" + x(d.value) + "," + 0 + ")"; })
.attr("y", 30)
.attr("dy", ".35em")
.style("fill", "black")
.text(function (d) { return d.value; });
bar.selectAll(".rectband")
.attr("width", function (d) { return x(d.value); })
.attr("height", y.rangeBand());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.