d3.js: how to join data from more sources -
gs.csv (data1):
id, name, x_value, y_value 1, fruits, 60, 60 2, vegetables, 70, 70 ...
circles.csv (data2):
id, name, value, cx_value, cy_value 1, fruits, apple, 10, 10 2, fruits, pear, 20, 20 3, fruits, strawberry, 30, 30 4, vegetables, carrot, 40, 40 5, vegetables, celery, 50, 50 ...
i have 2 data files above. gs.csv (data1) contains data g elements , circles.csv (data2) contains data circles , need proper way join them , create following:
<g class="groups" id="fruits" transform="translate(60,90)"> <circle class="some" id="apple" cx="10" cy="10"/> <circle class="some" id="pear" cx="20" cy="20"/> <circle class="some" id="strawberry" cx="30" cy="30"/> ... </g> <g class="groups" id="vegetables" transform="translate(70,70)"> <circle class="some" id="carrot" cx="40" cy="40"> <circle class="some" id="celery" cx="50" cy="50"> ... </g>
i can't join files because more complicated. think code should similar to:
d3.csv("gs.csv", function(data1) { d3.csv("circles.csv", function(data2) { var svg = ... var groups = svg.selectall(".groups") .data(data1) .enter().append("g") .attr("class", "groups") .attr("id", function(d) { return d.name; }) .attr("transform", function(d){return "translate(" + d.x_value + "," + d.y_value + ")"}); groups.selectall(".some") .data(data2, function(d) { return d.id; }) .enter().append("circle") .attr("class", "some") .attr("id", function(d) { return d.value; }) .attr("cx", function(d) { return d.cx_value; }) .attr("cy", function(d) { return d.cy_value; }); }) });
two solutions come mind there catch: first, tried filter lines data2 in second .data() don't know how access attributes of actual group filter circles except same name value. second, tried d3.nest data2 key d.name , enter these groups, overwrite original __ data_. so, tried add key , values _ data__ of each group without success.
the simplest way put data groups in list , operate on them, follows:
groupdata = [data1, data2]; groups = svg.selectall('g') .data(groupdata) .append('g')
now have 2 groups, each of has data appended things want inside group. can make function append circles based on data in group, , call each of groups.
function makecircles(d){ d3.select(this).selectall('circle') .data(d) .append('circle') .attr('rx',function(d){return d.circleradius}) groups.each(makecircles);
this give relevant circles each group. note that, within selectall
we've created within makecircles
, d
refers data associated given circle. use d
instead, it's best avoid variable confusion between group data d
, circle data d
. way can use both in of functions define attributes of circles.
if want first data contain second data, can use same function, filter based on d replacing d itself. code this:
var root = d3.select('body').append('svg'), data1 = [{'name':'foo','value':10},{'name':'foo','value':3},{'name':'foo','value':8},{'name':'bar','value':10},{'name':'bar','value':1},{'name':'bar','value':15}], data2 = [{'name':'foo','color':'green','x':10},{'name':'bar','color':'blue','x':70}]; console.log('foo') var groups = root.selectall('g') .data(data2) .enter() .append('g') .attr('transform',function(d){return 'translate(' + d.x + ',10)'}) .each(addcircles); function addcircles(d){ d3.select(this).selectall('circle') .data(data1.filter(function(d){return d.name == d.name })) .enter() .append('circle') .attr('r',5) .attr('cx', 0) .attr('cy', function(d){return d.value * 30}) .style('fill',d.color) }
i've made fiddle here.
Comments
Post a Comment