我正在使用d3.js水平条形图(http://bl.ocks.org/juan-cb/ab9a30d0e2ace0d2dc8c),根据用户选择更新/转换。目前,我已经向图表添加了标签,但它不再更新。不确定问题出在哪里。条形应从左侧开始,但由于某种原因也向右移动。为了向酒吧添加标签,我添加了#34; g"用于保存矩形和文本的元素。任何帮助将不胜感激。
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());
};
答案 0 :(得分:2)
以下是我的建议:由于您要将矩形和文本元素附加到<g>
(组),因此您的输入更新退出模式应该应用于组,而不是矩形和文本:
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/
PS 我冒昧地让酒吧从从左到右,而不是从右到左。如果这不正确,只需更改x
和width
属性。
答案 1 :(得分:1)
我对这种方法的利弊感兴趣吗?
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());