57796

How do I process data that is nested multiple levels in D3?

Question:

I have following data structure

{ key: 'a', values: { key: 'a0', values: { key: 'a00', values: {...} }, { key: 'a01', values: {...} } }, { key: 'a1', values: {...} } }, { key: 'b', values: {...} }

I see examples for processing two level nesting and could follow them to process the data. I just need to draw rectangles for each element with key property and determine its color and position based on some other properties of that object. Here is sample code close to what I want to do

var data = [ { key : 'dept1', values : [ { key : 'group-1-1', values : [ { key : 'emp-1-1-1', salary : 10000 }, { key : 'emp-1-1-2', salary : 20000 }, { key : 'emp-1-1-3', salary : 30000 }, { key : 'emp-1-1-4', salary : 40000 } ] }, { key : 'group-1-2', values : [ { key : 'emp-1-2-1', salary : 10000 }, { key : 'emp-1-2-2', salary : 20000 }, { key : 'emp-1-2-3', salary : 30000 }, { key : 'emp-1-2-4', salary : 40000 } ] } ] }, { key : 'dept2', values : [ { key : 'group-2-1', values : [ { key : 'emp-2-1-1', salary : 10000 }, { key : 'emp-2-1-2', salary : 20000 }, { key : 'emp-2-1-3', salary : 30000 }, { key : 'emp-2-1-4', salary : 40000 } ] }, { key : 'group-2-2', values : [ { key : 'emp-2-2-1', salary : 10000 }, { key : 'emp-2-2-2', salary : 20000 }, { key : 'emp-2-2-3', salary : 30000 }, { key : 'emp-2-2-4', salary : 40000 } ] } ] }, { key : 'dept3', values : [ { key : 'group-3-1', values : [ { key : 'emp-3-1-1', salary : 10000 }, { key : 'emp-3-1-2', salary : 20000 }, { key : 'emp-3-1-3', salary : 30000 }, { key : 'emp-3-1-4', salary : 40000 } ] }, { key : 'group-3-2', values : [ { key : 'emp-3-2-1', salary : 10000 }, { key : 'emp-3-2-2', salary : 20000 }, { key : 'emp-3-2-3', salary : 30000 }, { key : 'emp-3-2-4', salary : 40000 } ] } ] } ]; var svg = d3.select("body").append("svg").attr("width", "100%").attr("height", "100%"); var width = 200, height = 20, gap = 4, space = width + 2 * gap; var sel = svg.selectAll("g").data(data).enter() .append("g") .attr("transform", function(d, i) {return 'translate(' + space * i + ', 0)'}); sel.append("rect").attr("x", gap).attr('y', gap).attr('width', width).attr('height', height) .attr('fill', 'green') .append('title').text(function(d) {return d.key}); var width1 = width/2 - gap; var sel1 = sel.selectAll('g').data(function(d) {return d.values}).enter() .append('rect') .attr('x', function(p, i) {return gap + i * (width1+gap)}).attr('y', 2*gap + height) .attr('width', width1).attr('height', height) .attr('fill', 'blue') .append('title').text(function(p) {return p.key}); var width1 = width/4 - 3 * gap; var sel2 = sel1.selectAll('g').data(function(d) {return d.values}).enter() .append('rect').text(function(k) {return k.key}) .attr('x', function(p, i) {return gap + i * width1}).attr('y', 3*gap + 2*height) .attr('width', width1).attr('height', height) .attr('fill', 'cyan') .append('title').text(function(p) {return p.key});

I am expecting to draw three rows of rectangles. In this code first two rows show up correctly but third row does not show up at all. I looked in javascript console and looks like third row rectangles are getting appended to title of the second row rectangles. Hope this helps to show what I am asking here. Is this the way I should be looping here or is there a better way of doing it?

Answer1:

Perhaps you could use a recursive solution similar to the one @nautat posted to answer my question about nested HTML tables with d3? <a href="https://stackoverflow.com/a/13412059/658053" rel="nofollow">https://stackoverflow.com/a/13412059/658053</a> I was able to modify it to fit my actual data and specs once I had the gist of doing recursion.

The trick is that you do a .filter on some condition, and either .call the recursive function on the cells that match the filter, or deal with the base-case on the items that match a different kind of filter.

Good luck!

Recommend

  • Oracle MERGE: only NOT MATCHED is triggered
  • adding a script tag dynamically with document.write
  • Getting the number of satellites using react-native
  • Error trying to download using filnename format
  • Does Firebase provide us all queries like Parse Database for Android?
  • Why is 'gapi.client.youtube' from Youtube Data Api V3 undefined?
  • How to set image in custom rounded corner image view in android
  • ES not listening to external requests
  • gmail does not render html in email
  • Git objects SHA-1 are file contents or file names?
  • What is the function of Spring Session?
  • CORS issue on a Delphi's Datasnap ISAPI Module
  • How to change WebBrowser fullscreen video mode?
  • Forward slash vs backward slash for file path in git bash
  • Can't access web service when connected to the network :: HTTP 407
  • Faces Servlet not parsing .xhtml pages in jsf 2. running on tomcat 7
  • Making query to find nearest multiple(Lat,Long) from the single(Lat,Long)
  • Get max bookings count in range
  • How to manipulate content of a comment with Apache POI
  • Jekyll - How do I create pages in the root directory?
  • Corda: How to implement hierarchical relationships between state data persisted to H2
  • Is possible having two COM STA instances of the same component?
  • Showing image on a acro text field position
  • How to control xtics in gnuplot
  • Splitting ReportLab table across PDF page (side by side)?
  • What is the difference between dynamically creating a script tag and statically embed a script tag?
  • Regex not working in java 1.5
  • Annotate objects in a queryset with next and previous object ids
  • Calculate time from document
  • Using redis as an LRU cache for postgres
  • Bad automatic Triangulation with Mayavi for coloring a surface known only by its corner
  • Computing the discrete fourier transform of audio data with FFTW
  • VLOOKUP in IMPORTRANGE
  • Angular 4: Responsive Grid List
  • Firebase: How to read from external DB?
  • media foundation H264 decoder not working properly