Search code examples
javascriptamcharts

amCharts4 - How to style single link/edge between nodes in Force Directed Tree?


I am using am4Charts and have a Force Directed Tree with a few nodes. I want to change the stroke width of a single link in the graph.

Simple example:

<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>

Javascript:

am4core.useTheme(am4themes_animated);

// Create chart
chart = am4core.create("chartdiv", am4plugins_forceDirected.ForceDirectedTree);

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

// Set data
series.data = [{
  "name": "First",
  "link": ["Second", "Third"],
  "children": [{
    "name": "A1", "value": 100, "link": ["B2"]
  }, {
    "name": "A2", "value": 60
  }, {
    "name": "A3", "value": 30
  }]
}, {
  "name": "Second",
  "children": [{
    "name": "B1", "value": 135
  }, {
    "name": "B2", "value": 98
  }, {
    "name": "B3", "value": 56
  }]
}, {
  "name": "Third",
  "children": [{
    "name": "C1", "value": 1
  }]
}];
series.dataFields.linkWith = "link";
series.dataFields.id = "name";
// Set up data fields
series.dataFields.value = "value";
series.dataFields.name = "name";
series.dataFields.children = "children";

// Add labels
series.nodes.template.label.text = "{name}";
series.fontSize = 10;
series.minRadius = 15;
series.maxRadius = 40;
// series.centerStrength = 50;
// series.manyBodyStrength = 50;
series.links.template.strokeWidth = 5;
series.links.template.strokeOpacity = 1;

series.centerStrength = 0.5;

Codepen example

In the documentation I have found a way to set strokeWidth and strokeOpacity for all links.

I have already tried making a second series and moving the "Third" node to that and setting strokeWidth for that second series only, but the nodes were not connected. Even if it worked that seems like a rather convoluted way of doing this.

How can I set the strokeWidth of a single link between two nodes, for example from node "First" to node "Third" and keep all other links unchanged, preferably without separating nodes into multiple series?


Solution

  • series.links.template.configField = 'configLink'; //maps configLink property of data nodes to the links
    

    and then

    {
        "name": "Second",
        "children": [{
        "name": "B1", "value": 135
        }, {
        "name": "B2", "value": 98
        }, {
        "name": "B3", "value": 56
        }],
        configLink: {
            fill: color,
            stroke: color,
            strokeWidth: 2
        }
    }
    

    You can also add an adapter:

    series.links.template.adapter.add('stroke', (stroke, target) => {
            if (target.dataItem.id === 'somenodesID') {
                return am4core.color();
            }
    
            return am4core.color('#ddd');
        });
    

    Giving id properties to nodes.