Search code examples
javascriptamcharts4

AmCharts - How to expand only first level children on a Force Directed Tree


I'm working on a force directed tree with 3 levels, and currently when I click to expand the second level childrens, the third level is expanded at the same time.

Is there a way to display only the 2nd level children when clicking the 1st level bubbles and display the 3rd level children only when clicking the second level bubbles ?

am4core.useTheme(am4themes_animated);

var chart = am4core.create("chartdiv", am4plugins_forceDirected.ForceDirectedTree);
chart.legend = new am4charts.Legend();

var series = chart.series.push(new am4plugins_forceDirected.ForceDirectedSeries());

series.data = [

  {
    name: 'One',
    color: ("#6ab8da"),
    children: [{
        name: '1',

        children: [{

            name: 'Blackberry',
            value: 1
          },
          {
            name: 'Raspberry',
            value: 1
          },
          {
            name: 'Blueberry',
            value: 1
          },
          {
            name: 'Strawberry',
            value: 1
          }
        ]
      },

      {
        name: '2',
        children: [{
            name: 'Raisin',
            value: 1
          },
          {
            name: 'Prune',
            value: 1
          }
        ]
      },

      {
        name: '3',
        children: [{
            name: 'Coconut',
            value: 1
          },
          {
            name: 'Cherry',
            value: 1
          },
          {
            name: 'Pomegranate',
            value: 1
          },
          {
            name: 'Pineapple',
            value: 1
          },
          {
            name: 'Grape',
            value: 1
          },
          {
            name: 'Apple',
            value: 1
          },
          {
            name: 'Peach',
            value: 1
          },
          {
            name: 'Pear',
            value: 1
          }
        ]
      },

      {
        name: '4',
        children: [{
            name: 'Grapefruit',
            value: 1
          },
          {
            name: 'Orange',
            value: 1
          },
          {
            name: 'Lemon',
            value: 1
          },
          {
            name: 'Lime',
            value: 1
          }
        ]
      }
    ]
  },


  {
    name: 'Two',
    color: ("#6872d9"),
    children: [{
        name: 'Visites vistuelles'
      },

      {
        name: 'Lorem ipsum'
      }
    ]
  },

  {
    name: 'Three',
    color: ("#a267d9"),
    children: [{
        name: 'Papery/Musty',
        children: [{
            name: 'Stale',
            value: 1
          },
          {
            name: 'Cardboard',
            value: 1
          },
          {
            name: 'Papery',
            value: 1
          },
          {
            name: 'Woody',
            value: 1
          },
          {
            name: 'Moldy/Damp',
            value: 1
          },
          {
            name: 'Musty/Dusty',
            value: 1
          },
          {
            name: 'Musty/Earthy',
            value: 1
          },
          {
            name: 'Animalic',
            value: 1
          },
          {
            name: 'Meaty Brothy',
            value: 1
          },
          {
            name: 'Phenolic',
            value: 1
          }
        ]
      },

      {
        name: 'Chemical',
        children: [{
            name: 'Bitter',
            value: 1
          },
          {
            name: 'Salty',
            value: 1
          },
          {
            name: 'Medicinal',
            value: 1
          },
          {
            name: 'Petroleum',
            value: 1
          },
          {
            name: 'Skunky',
            value: 1
          },
          {
            name: 'Rubber',
            value: 1
          }
        ]
      }
    ]
  },


  {
    name: 'Four',
    color: ("#da66cc"),
    children: [{
        name: 'Pipe Tobacco',
        value: 1
      },
      {
        name: 'Tobacco',
        value: 1
      },
      {
        name: 'Burnt',
        children: [{
            name: 'Acrid',
            value: 1
          },
          {
            name: 'Ashy',
            value: 1
          },
          {
            name: 'Smoky',
            value: 1
          },
          {
            name: 'Brown, Roast',
            value: 1
          }
        ]
      },

      {
        name: 'Cereal',
        children: [{
            name: 'Grain',
            value: 1
          },
          {
            name: 'Malt',
            value: 1
          }
        ]
      }
    ]
  }
];



series.dataFields.linkWith = "linkWith";
series.dataFields.name = "name";
series.dataFields.id = "name";
series.dataFields.value = "value";
series.dataFields.children = "children";
series.dataFields.color = "color";
series.dataFields.collapsed = "on";

series.manyBodyStrength = -30;
series.links.template.distance = 1;
series.links.template.strength = 1;

series.centerStrength = 1.2;
/*series.manyBodyStrength = -50;*/

series.links.template.strength = 1;
series.nodes.template.tooltipText = "{name}";
series.nodes.template.fillOpacity = 1;
series.nodes.template.togglable = true;

series.nodes.template.label.text = "{name}";
series.fontSize = 14;
series.minRadius = 50;
series.maxRadius = 80;
series.maxLevels = 1;
series.nodes.template.label.hideOversized = true;
series.nodes.template.label.truncate = true;
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

#chartdiv {
  width: 100%;
  height: 600px;
}
<body>
  <script src="//www.amcharts.com/lib/4/core.js"></script>
  <script src="//www.amcharts.com/lib/4/charts.js"></script>
  <script src="//www.amcharts.com/lib/4/themes/animated.js"></script>
  <script src="//www.amcharts.com/lib/4/plugins/forceDirected.js"></script>
  <div id="chartdiv"></div>
</body>

JSFiddle here


Solution

  • Yes, there is a way to change the behavior from expanding all nodes to just the next, immediate level of the node that was clicked.

    By default, the expandAll property of ForceDirectedNodes is set to true.

    You can set this to false on all of them via

    series.nodes.template.expandAll = false;
    

    And that will give you the behavior you're looking for:

    am4core.useTheme(am4themes_animated);
    
    var chart = am4core.create("chartdiv", am4plugins_forceDirected.ForceDirectedTree);
    chart.legend = new am4charts.Legend();
    
    var series = chart.series.push(new am4plugins_forceDirected.ForceDirectedSeries());
    
    series.nodes.template.expandAll = false;
    
    series.data = [
    
      {
        name: 'One',
        color: ("#6ab8da"),
        children: [{
            name: '1',
    
            children: [{
    
                name: 'Blackberry',
                value: 1
              },
              {
                name: 'Raspberry',
                value: 1
              },
              {
                name: 'Blueberry',
                value: 1
              },
              {
                name: 'Strawberry',
                value: 1
              }
            ]
          },
    
          {
            name: '2',
            children: [{
                name: 'Raisin',
                value: 1
              },
              {
                name: 'Prune',
                value: 1
              }
            ]
          },
    
          {
            name: '3',
            children: [{
                name: 'Coconut',
                value: 1
              },
              {
                name: 'Cherry',
                value: 1
              },
              {
                name: 'Pomegranate',
                value: 1
              },
              {
                name: 'Pineapple',
                value: 1
              },
              {
                name: 'Grape',
                value: 1
              },
              {
                name: 'Apple',
                value: 1
              },
              {
                name: 'Peach',
                value: 1
              },
              {
                name: 'Pear',
                value: 1
              }
            ]
          },
    
          {
            name: '4',
            children: [{
                name: 'Grapefruit',
                value: 1
              },
              {
                name: 'Orange',
                value: 1
              },
              {
                name: 'Lemon',
                value: 1
              },
              {
                name: 'Lime',
                value: 1
              }
            ]
          }
        ]
      },
    
    
      {
        name: 'Two',
        color: ("#6872d9"),
        children: [{
            name: 'Visites vistuelles'
          },
    
          {
            name: 'Lorem ipsum'
          }
        ]
      },
    
      {
        name: 'Three',
        color: ("#a267d9"),
        children: [{
            name: 'Papery/Musty',
            children: [{
                name: 'Stale',
                value: 1
              },
              {
                name: 'Cardboard',
                value: 1
              },
              {
                name: 'Papery',
                value: 1
              },
              {
                name: 'Woody',
                value: 1
              },
              {
                name: 'Moldy/Damp',
                value: 1
              },
              {
                name: 'Musty/Dusty',
                value: 1
              },
              {
                name: 'Musty/Earthy',
                value: 1
              },
              {
                name: 'Animalic',
                value: 1
              },
              {
                name: 'Meaty Brothy',
                value: 1
              },
              {
                name: 'Phenolic',
                value: 1
              }
            ]
          },
    
          {
            name: 'Chemical',
            children: [{
                name: 'Bitter',
                value: 1
              },
              {
                name: 'Salty',
                value: 1
              },
              {
                name: 'Medicinal',
                value: 1
              },
              {
                name: 'Petroleum',
                value: 1
              },
              {
                name: 'Skunky',
                value: 1
              },
              {
                name: 'Rubber',
                value: 1
              }
            ]
          }
        ]
      },
    
    
      {
        name: 'Four',
        color: ("#da66cc"),
        children: [{
            name: 'Pipe Tobacco',
            value: 1
          },
          {
            name: 'Tobacco',
            value: 1
          },
          {
            name: 'Burnt',
            children: [{
                name: 'Acrid',
                value: 1
              },
              {
                name: 'Ashy',
                value: 1
              },
              {
                name: 'Smoky',
                value: 1
              },
              {
                name: 'Brown, Roast',
                value: 1
              }
            ]
          },
    
          {
            name: 'Cereal',
            children: [{
                name: 'Grain',
                value: 1
              },
              {
                name: 'Malt',
                value: 1
              }
            ]
          }
        ]
      }
    ];
    
    
    
    series.dataFields.linkWith = "linkWith";
    series.dataFields.name = "name";
    series.dataFields.id = "name";
    series.dataFields.value = "value";
    series.dataFields.children = "children";
    series.dataFields.color = "color";
    series.dataFields.collapsed = "on";
    
    series.manyBodyStrength = -30;
    series.links.template.distance = 1;
    series.links.template.strength = 1;
    
    series.centerStrength = 1.2;
    /*series.manyBodyStrength = -50;*/
    
    series.links.template.strength = 1;
    series.nodes.template.tooltipText = "{name}";
    series.nodes.template.fillOpacity = 1;
    series.nodes.template.togglable = true;
    
    series.nodes.template.label.text = "{name}";
    series.fontSize = 14;
    series.minRadius = 50;
    series.maxRadius = 80;
    series.maxLevels = 1;
    series.nodes.template.label.hideOversized = true;
    series.nodes.template.label.truncate = true;
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    }
    
    #chartdiv {
      width: 100%;
      height: 600px;
    }
    <body>
      <script src="//www.amcharts.com/lib/4/core.js"></script>
      <script src="//www.amcharts.com/lib/4/charts.js"></script>
      <script src="//www.amcharts.com/lib/4/themes/animated.js"></script>
      <script src="//www.amcharts.com/lib/4/plugins/forceDirected.js"></script>
      <div id="chartdiv"></div>
    </body>

    jsfiddle fork:

    https://jsfiddle.net/notacouch/4wfc2duj/

    Hope this helps.