This tutorial looks at various ways we can control coloring of hierarchy nodes.
Auto-assigned colors
A series will automatically assign a unique color to each root node as well as all the first-level nodes from its own color set.
Deeper level nodes will inherit their colors from parent nodes.
Should we want to, we can override the whole list of colors by either setting it directly on series color set, creating a quick theme, or a reusable full theme, e.g.:
series.get("colors").set("colors", [ am5.color(0x095256), am5.color(0x087f8c), am5.color(0x5aaa95), am5.color(0x86a873), am5.color(0xbb9f06) ]);
series.get("colors").set("colors", [ am5.color(0x095256), am5.color(0x087f8c), am5.color(0x5aaa95), am5.color(0x86a873), am5.color(0xbb9f06) ]);
MORE INFO A "Color sets" section of our color tutorial has more details and code samples.
Manual colors
Note about data
Before we explore the dynamic node coloring options, and important note.
Series data needs to be set after all the other configuration options for the series.
Setting data before adapters or template fields, will cause the those to be ignored.
Via adapters
It's possible to use custom functions (adapters) to determine color for each node's elements, like circles or rectangles.
Adapters are functions that are run whenever color (or any other setting) is requested for an element. They have a chance of modifying the value.
We can use them to apply custom colors for series elements:
Hierarchy type | Visual elements |
---|---|
ForceDirected | circles , outerCircles , links |
Pack | circles |
Partition | rectangles |
Sunburst | slices |
Tree | circles , outerCircles , links |
Treemap | rectangles |
For example, the following will change fill color for node circles, and outline to outer circles on a force-directed series to red:
series.circles.template.adapters.add("fill", function(fill, target) { return am5.color(0xff0000); }); series.outerCircles.template.adapters.add("stroke", function(fill, target) { return am5.color(0xff0000); });
series.circles.template.adapters.add("fill", function(fill, target) { return am5.color(0xff0000); }); series.outerCircles.template.adapters.add("stroke", function(fill, target) { return am5.color(0xff0000); });
Adapters can also contain custom code to selectively return values according to some logic.
E.g. the following will color treemap node rectangles red if value is lower than 100, and green if it's 100 or above:
series.rectangles.template.adapters.add("fill", function(fill, target) { if (target.dataItem.get("value") > 100) { return am5.color(0xb30000); } else { return am5.color(0x50b300); } });
series.rectangles.template.adapters.add("fill", function(fill, target) { if (target.dataItem.get("value") > 100) { return am5.color(0xb30000); } else { return am5.color(0x50b300); } });
In the above code we are accessing data item of the node (passed in via target
parameter) to determine its value.
See the Pen
Force-directed chart with topDepth by amCharts team (@amcharts)
on CodePen.0
Via data
We can also specify fill and other colors, as well as any other setting value, via data using template fields.
In short, template field allows specifying field in data that holds setting values for the node.
Using it we can bind fill
and stroke
settings of an element to data:
series.circles.template.setAll({ templateField: "nodeSettings" }); series.data.setAll([{ name: "Root", value: 0, children: [{ name: "A", value: 89, nodeSettings: { fill: am5.color(0x297373) } }, { name: "B", value: 55, nodeSettings: { fill: am5.color(0x946B49) } }, { name: "C", value: 66, nodeSettings: { fill: am5.color(0xFF621F) } }] }]);
series.circles.template.setAll({ templateField: "nodeSettings" }); series.data.setAll([{ name: "Root", value: 0, children: [{ name: "A", value: 89, nodeSettings: { fill: am5.color(0x297373) } }, { name: "B", value: 55, nodeSettings: { fill: am5.color(0x946B49) } }, { name: "C", value: 66, nodeSettings: { fill: am5.color(0xFF621F) } }] }]);
See the Pen
Force-directed chart with topDepth by amCharts team (@amcharts)
on CodePen.0