Я работаю с воссозданием this population pyramid by Mike Bostock. У меня есть основной вопрос о том, как работает .data()
.d3js: Сопряжение CSV строк в элементах «g»
У меня есть данные в CSV файл следующим образом:
Итак, у меня есть количество мужчин и женщин в каждой region
(Dodoma, Аруша и т.д.). Следуя примеру Майка, я хочу создать гистограмму, где мужчины и женщины занимают разные rects
, которые перекрываются с 80% opacity
. Я хочу, чтобы region
была моей осью x, а число людей - моей осью y. Вот мои x- и у-оси шкалы:
var x = d3.scale.ordinal()
.rangeRoundBands([0, w], 0.05);
var y = d3.scale.linear()
.range([0, h-padding]);
И вот моя попытка перегруппировать мужчины + женщины по каждому региону:
var regions = svg.append("g")
.classed("regions", true);
var region = regions.selectAll(".region")
.data(dataset)
.enter()
.append("g")
.attr("class", "region")
.attr("transform", function(region) { return "translate(" + x(region) + ",0)"; });
region.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return x(i);
})
.attr("y", function(d) { return h - y(d.people_0); })
.attr("width", barWidth)
.attr("height", function(d) { return y(d.people_0); });
Я в конечном итоге с этим:
То есть, у меня есть 50 g
элементов, которые имеют все данных, и просто создают полную гистограмму fo г каждой пары гендерных регионов (мужчины из Додомы, женщины из Додомы; мужчины из Танги, женщины из Танги и т. д.). Таким образом, полная диаграмма перерисовывается 50 раз. У меня 25 регионов, поэтому я хочу 25 g
элементов с только номера мужчин и женщин для этого региона.
Я думаю, что все это можно было бы связать в .data()
. Но я не знаю, как сообщить d3, что я хочу группировать свои наблюдения по регионам, и в итоге получается 2 rects
за g
.
Here's my JSFiddle (хотя я не знаю, как загрузить мои внешние данные, поэтому ничего не появляется, любые намеки на это будут оценены).
Edited добавить:
Я попытался с помощью .nest
, дал комментарий Беньямина. Так что у меня есть:
dataset = d3.nest()
.key(function(d) { return d.round; })
.key(function(d) { return d.region; })
.rollup(function(v) { return v.map(function(d) { return d.people_0; }); })
.map(dataset);
И я теперь зовет меня rects
вот так:
region.selectAll("rect")
.data(function(region) { return data[round][region]; })
.enter()
.append("rect")
.attr("x", function(d, i) {
return x(i);
})
.attr("y", function(d) { return h - y(d.people_0); })
.attr("width", barWidth)
.attr("height", function(d) { return y(d.people_0); });
Нет удачи. FWIW, console.log(dataset)
показывает мне, что данные действительно были свернуты. Но мне все еще сложно позвонить и связать его с моими g.region
элементами.
Может кто-нибудь объяснить, что делает data[round][region]
? Я не понимаю, как d3 интерпретирует это.
вы делали в «гнездо()', как в примере ? Это группирует данные в «год» и «возраст» в примере, который вы связали. вам придется сделать то же самое для региона. –
@BenjaminUdinktenCate - Спасибо. Пробовал '.nest', но он все еще не работает. Теперь ни один из прямых не появляется, и элементы 'g.region' теряются. Я обновил свой вопрос с дополнительной информацией, следуя этому предложению. Я думаю, что моя основная путаница заключается в том, как следует называть '.data()' по желанию. –
'data [round] [region]' обращается к 2D-массиву. Вы связываете свои данные дважды; попробуйте 'region.append (« rect »)'. Вы можете поместить '.each (function (d) {console.log (d)})' next в цепочке, чтобы гарантировать, что 'rect' имеют свои родительские данные 'g'. – mgold