D3 - how to deal with JSON data structures?

后端 未结 2 867
时光取名叫无心
时光取名叫无心 2020-11-30 19:34

I\'m new to D3, and spent already a few hours to find out anything about dealing with structured data, but without positive result. I want to create a bar chart using data s

2条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-30 19:46

    This may clarify the nested aspect, in addition to mbostock's fine answer.

    Your data has 2 degrees of nesting. You have an array of 2 objects, each has an array of ints. If you want your final image to reflect these differences, you need to do a join for each.

    Here's one solution: Each user is represented by a group g element, with each score represented by a rect. You can do this a couple of ways: Either use datum on the svg, then an identity function on each g, or you can directly join the data on the g. Using data on the g is more typical, but here are both ways:

    Using datum on the svg:

    var chart = d3.select('body').append('svg')
      .datum(data)             // <---- datum
      .attr('width',800)
      .attr('height',350)
      .selectAll('g')
      .data(function(d){ return d; })  // <----- identity function
      .enter().append('g')
        .attr('class', function(d) { return d.user; })
        .attr('transform', function(d, i) { return 'translate(0, ' + i * 140 + ')'; })
        .selectAll('rect')
        .data(function(d) { return d.scores; })
        .enter().append('rect')
          .attr('y', function(d, i) { return i * 20; })
          .attr('width', function(d) { return d; })
          .attr('height', 20);
    

    Using data on the group (g) element:

    var chart = d3.select('body').append('svg')
      .attr('width',800)
      .attr('height',350)
      .selectAll('g')
      .data(data)          // <--- attach directly to the g
      .enter().append('g')
        .attr('class', function(d) { return d.user; })
        .attr('transform', function(d, i) { return 'translate(0, ' + i * 140 + ')'; })
        .selectAll('rect')
        .data(function(d) { return d.scores; })
        .enter().append('rect')
          .attr('y', function(d, i) { return i * 20; })
          .attr('width', function(d) { return d; })
          .attr('height', 20);
    

    Again, you don't have to create these g elements, but by doing so I can now represent the user scores differently (they have different y from the transform) and I can also give them different styles, like this:

    .jim {
      fill: red;
    }
    .ray {
      fill: blue;
    }
    

提交回复
热议问题