Colin
Colin

Reputation: 940

nesting JSON with d3v4 .stratify()

I am retrieving records from mongodb .find() and trying to nest them with d3v4 .stratify(). Unfortunately, I'm getting the error

Error: ambiguous: Product Line 1

I'm presuming I'm misunderstanding the API documentation.

While the problem seems close to this post, I don't think it's quite the same. However, the result I'm trying to get to IS something like this.

Can someone help me understand how to use .stratify() properly? Or suggest an easier way to do this?

My result set (mongodb_data) is not large (maybe ~2500 products).

My flat mongodb_data looks like this,

[
  {
   "name": "Product Line 1",
   "reference": "product 1.A identifier"
  },
  {
   "name": "Product Line 1",
   "reference": "product 1.B identifier"
  },
  {
   "name": "Product Line 2",
   "reference": "product 2.A identifier"
  },
  {
   "name": "Product Line 2",
   "reference": "product 2.B identifier"
  }
];

The desired hierarchical/nested data needs to look like this,

{
 "name": "Master Product Catalog",
 "children": [
             { 
              "name": "Product Line 1",
              "children": [
                           { "name": "product 1.A identifier" },
                           { "name": "product 1.B identifier" }
                          ]
             },
             { "name": "Product Line 2",
               "children": [
                            { "name": "product 2.A identifier" },
                            { "name": "product 2.B identifier" }
                           ]
             }
             ]
}

I have been using the example from the API documentation as follows,

var stratdata = d3.stratify() 
                  .id(function(d) { return d.name; }) 
                  .parentId(function(d) { return d.name; }) 
                  (mongodb_data);

Upvotes: 2

Views: 1240

Answers (1)

Mark
Mark

Reputation: 108512

Your flat data doesn't represent a hierarchical structure. It doesn't answer the question who does "Product Line 1" or "Product Line 2" parent to? Also, your name property doesn't hold both the parent and the child information (reference is the parent, name is the child). Your data before d3.stratify() should look like this:

[{
  "reference": "Master Product Catalog",
  "name": "" //<-- has no parent
}, {
  "reference": "Product Line 1", 
  "name": "Master Product Catalog" //<-- parent is master
}, {
  "reference": "Product Line 2",
  "name": "Master Product Catalog"
}, {
  "name": "Product Line 1",
  "reference": "product 1.A identifier"
}, {
  "name": "Product Line 1",
  "reference": "product 1.B identifier"
}, {
  "name": "Product Line 2",
  "reference": "product 2.A identifier"
}, {
  "name": "Product Line 2",
  "reference": "product 2.B identifier"
}];

Running code:

<!DOCTYPE html>
<html>

<head>
  <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
  <script>
    var json = [{
      "reference": "Master Product Catalog",
      "name": ""
    }, {
      "reference": "Product Line 1",
      "name": "Master Product Catalog"
    }, {
      "reference": "Product Line 2",
      "name": "Master Product Catalog"
    }, {
      "name": "Product Line 1",
      "reference": "product 1.A identifier"
    }, {
      "name": "Product Line 1",
      "reference": "product 1.B identifier"
    }, {
      "name": "Product Line 2",
      "reference": "product 2.A identifier"
    }, {
      "name": "Product Line 2",
      "reference": "product 2.B identifier"
    }];

    var root = d3.stratify()
      .id(function(d) {
        return d.reference;
      })
      .parentId(function(d) {
        return d.name;
      })
      (json);

    console.log(root)
  </script>
</body>

</html>

Upvotes: 2

Related Questions