简体   繁体   中英

d3.pack Multiple hierarchies with a single JSON

I have a JSON file which I need to use to generate three different hierarchy visualisations using d3.pack.

The JSON file contains information for eventA (1 or 0) and eventB (1 or 0). Each leaf also has a unique ID.

I need to show hierarchies as follows. First hierarchy : Total population (if there are 10000 elements, show all 10000). Second hierarchy : eventA (so group all the 1s and all the 0s) Third hierarchy : eventB, subdivided by eventA values.

At the moment, I'm using three different multidimensional JSON files, which is not very efficient, and simply erasing the old data and creating new ones. However, the transitions are important for what I need to do, so it doesn't quiet cut it.

Does anyone have any clue on how I can achieve this?

I'm not looking for code, just suggestions on how I can approach the problem.

Here is an example of what the JSON data looks like.

{
  "name":"Total",
  "children":[
    {
      "name":"POPULATION (n=20)",
      "children":[
        {
          "id":1,
          "eventA":1,
          "eventB":1,
          "size":50
        },
        {
          "id":2,
          "eventA":1,
          "eventB":1,
          "size":49
        },
        {
          "id":3,
          "eventA":1,
          "eventB":1,
          "size":48
        },
        {
          "id":4,
          "eventA":1,
          "eventB":1,
          "size":47
        },
        {
          "id":5,
          "eventA":1,
          "eventB":0,
          "size":46
        },
        {
          "id":6,
          "eventA":0,
          "eventB":1,
          "size":45
        },
        {
          "id":7,
          "eventA":0,
          "eventB":1,
          "size":44
        },
        {
          "id":8,
          "eventA":0,
          "eventB":1,
          "size":43
        },
        {
          "id":9,
          "eventA":0,
          "eventB":1,
          "size":42
        },
        {
          "id":10,
          "eventA":0,
          "eventB":0,
          "size":41
        },
        {
          "id":11,
          "eventA":0,
          "eventB":0,
          "size":40
        },
        {
          "id":12,
          "eventA":0,
          "eventB":0,
          "size":39
        },
        {
          "id":13,
          "eventA":0,
          "eventB":0,
          "size":38
        },
        {
          "id":14,
          "eventA":0,
          "eventB":0,
          "size":37
        },
        {
          "id":15,
          "eventA":0,
          "eventB":0,
          "size":36
        },
        {
          "id":16,
          "eventA":0,
          "eventB":0,
          "size":35
        },
        {
          "id":17,
          "eventA":0,
          "eventB":0,
          "size":34
        },
        {
          "id":18,
          "eventA":0,
          "eventB":0,
          "size":33
        },
        {
          "id":19,
          "eventA":0,
          "eventB":0,
          "size":32
        },
        {
          "id":20,
          "eventA":0,
          "eventB":0,
          "size":31
        }
      ]
    }
  ]
}

Do you know about d3.nest ? That's probably what you want to use for this. In that case, you would load the data as a flat array, like

var flatData = [
  {
    "name1": "Total",
    "name2": "POPULATION (n=20)",
    "id": 1,
    "eventA": 1,
    "eventB": 1,
    "size": 50
  },
  {
    "name1": "Total",
    "name2": "POPULATION (n=20)",
    "id": 2,
    "eventA": 1,
    "eventB": 0,
    "size": 49
  },
  {
    "name1": "Total",
    "name2": "POPULATION (n=20)",
    "id": 3,
    "eventA": 0,
    "eventB": 1,
    "size": 48
  },
  ...
]

(Note, I used name1 and name2 because I didn't know what to meaningfully call those things).

From there, to turn it into the grouping you posted:

d3.nest()
  .key(function(d) { return d.name1 })
  .key(function(d) { return d.name2 })
  .entries(dataset)

And to get it into the 2nd of the 3 grouping you described (ie by the value of eventA ):

d3.nest()
  .key(function(d) { return d.eventA })
  .entries(dataset)

And to get it into the 3rd grouping you described (ie by the value of eventB , then by eventA ):

d3.nest()
  .key(function(d) { return d.eventB })
  .key(function(d) { return d.eventA })
  .entries(dataset)

The results you get will be hierarchically similar to what you're showing with name and children , except that d3.nest will call them key and values , respectively. It's slightly inconvenient, because I believe d3's hierarchical layouts (including pack) use key and children . But you can easily re-map the keys after the nest operation.

The d3.nest object also accepts a rollup function where you can tell it (how) to transform all the values in the lowest-level group into a single values. For example, this would sum all thee sizes for a given eventA group value:

d3.nest()
  .key(function(d) { return d.eventA; })
  .rollup(function(values) { return d3.sum(values, function(d) { return d.size; }) })
  .entries(dataset);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM