Я сделал простую гистограмму. Я хочу обновить бары («на лету»), переключая разные подмножества моих данных. Из того, что я видел, существует, по-видимому, два подхода:Обновление гистограммы с .update, .enter и .exit?
- Нарисуйте диаграмму и нажмите кнопку (или что-то еще), чтобы удалить весь график и перерисовать его.
- Используйте разные данные для «обновления», «введите» и «выйдите» из графика с помощью кнопки.
Я пытаюсь вариант 2. Вот мой код:
// set dimensions
var margin = {top: 10, right: 20, bottom: 50, left: 100};
var height = 600 -margin.top - margin.bottom;
var width = 600 - margin.left - margin.right;
// set ranges
var x = d3.scale.linear().range([width, 0]);
var y = d3.scale.ordinal().rangeRoundBands([0, height], .05);
// define y axis
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
// add svg container
var svg = d3.select("#chart")
.append("svg")
.attr("height", height + margin.top + margin.bottom)
.attr("width", width + margin.left + margin.right)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// load data
d3.json("data.json", function(data) {
// format data
data.forEach(function(d) {
d.enrols = +d.enrols;
});
// register click event
d3.selectAll(".toggle").on("click", function() {
render(this.id);
});
// initialise
render("group-1");
function render(selection) {
// filter data
var subset = data.filter(function(d) { return d.group === selection});
// scale range of data
x.domain([0, d3.max(subset, function(d) { return d.enrols; })]);
y.domain(subset.map(function(d) { return d.month; }));
// update selection
var bars = svg.selectAll(".bars")
.data(subset, function(d) { return d.month; });
// add bars
bars.enter()
.append("g")
.attr("class", "bar")
.attr("transform", function (d, i) {
return "translate(0," + y(d.month) + ")";
});
bars.append("rect")
.attr("height", y.rangeBand())
.attr("width", function (d) {
return width - x(d.enrols);
});
bars.append("text")
.attr("x", function (d) {
return width - x(d.enrols) - 15;
})
.attr("y", y.rangeBand()/2)
.attr("dy", ".35em")
.text(function (d) {
return d.enrols;
});
bars.exit().remove();
// add y axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
}
});
Проблема мои старые данные никогда не получает вышли, новые бары добавляются, но старые остаются. Я читал теорию выбора d3, но я нахожу их трудно реализовывать на практике.
'SelectAll («») бары' неправильно, поскольку нет никаких элементов с классом 'bars', есть только элементы с классом' bar'. Вы создаете несколько осей. И вы также добавляете несколько баров к одному и тому же элементу группы 'g'. Посмотрите на SVG, сгенерированный в кодексе. – Ashitaka
Вы имеете в виду вот так: http://codepen.io/24ma13wg/pen/jVOgRj? Кажется, не помогает? – 24ma13wg
Очень хорошо! Вы решили почти все проблемы в кодеде. Вы все равно добавляете новую ось в свою диаграмму каждый раз, когда вызывается функция «render». Вы должны это исправить. В любом случае, теперь я могу объяснить вам, что данные d3 объединяются. – Ashitaka