Root element

All charts and their controls are created in a root element. This tutorial examines some of its functionality and configuration options.

What is root element?

A root element is a kind of "wrapper" for everything else - charts, legend, labels, etc.- as well as repository for some chart-wide configuration options, such as locale, formatting options, themes, and others.

Whenever we create a new object in amCharts 5, we also pass in its root element, so that it correctly inherits themes and other settings.

Creating

We instantiate a root element by calling new method of Root class:

const root = am5.Root.new("chartdiv");
var root = am5.Root.new("chartdiv");

The parameter we pass into new() call is the id or reference of the DOM container we will want to place our chart in.

Using

As we already mentioned, root element will need to be passed into any other element we will create for the chart.

This is a requirement, so that the system knows which root element is being created for, as parent-child relation is not always apparent.

A reference to the root element is always the first parameter to the new() method call on any element being created, other than root itself.

For example, here's how root element is passed into an PieChart that is being newly created:

const chart = root.container.children.push(
  am5pie.PieChart.new(root, {})
);
var chart = root.container.children.push(
  am5pie.PieChart.new(root, {})
);

Configuring root

Formatters

Root element holds instances of the three formatters used throughout the charts and their elements:

PropertyClass
numberFormatterNumberFormatter
dateFormatterDateFormatter
durationFormatterDurationFormatter

Those are global formatters that define formats and related options used in formatting numbers, date/time, and duration.

MORE INFOFor more information, please refer to "Formatters: Global formatters".

Performance

amCharts 5 rendering engine will try to render charts and animations as smoothly as possible, cramming as many frames per second as possible.

The more frames per second animation plays, the smoother it looks.

However, if smoothness is not as important as resource usage, or chart-heavy page is suffering from performance-related issues, we can limit number of frames-per-second using root elements fps property:

root.fps = 30;
root.fps = 30;

The smaller the number, the less resources charts will use, at the expense of smoothness of animations.

Time zone

Normally, chart's date/time-related functionality will display date and time in user's local time zone.

If we need to force displaying of the information in a specific time zone, we can use root element's timezone property.

It needs to be set with an instance of Timezone object, e.g.:

root.timezone = am5.Timezone.new("America/Vancouver");
root.timezone = am5.Timezone.new("America/Vancouver");

As per example above, Timezone takes string-based time zone identifier as a constructor parameter.

A few examples: "UTC", "Asia/Tokyo", "America/New_York", "Europe/Lisbon".

For a full list of officially supported time zone identifiers, please refer to this IANA page.

NOTEPlease note that if you are using "UTC" it's better to use root.utc = true. It will work faster than via named root.timezone = "UTC".

Settings

It's possible to pass in a root element settings object as a second parameter to its new() call.

For now, there's only one setting: useSafeResolution: boolean (default: true).

The setting means that chart will automatically choose resolution of the chart that is "safe" for the given device.

For example, in iOS 15 and up, there were memory limits imposed on canvas rendering, which means that with large charts, on big tablets, and even larger Apple phones, that limit might get hit, effectively breaking the charts.

For those devices, "safe resolution" will be reduced, to minimize the chance of the issue hitting actual chart setup.

To disable such resolution reduction, we can use root element's settings:

const root = am5.Root.new("chartdiv", {
  useSafeResolution: false
});
var root = am5.Root.new("chartdiv", {
  useSafeResolution: false
});

Other configuration options

Root element contains some other global options, too:

Reusing

If we need to completely replace contents of the chart, we can dispose them, but keep root element for new chart.

To remove all elements from the root, simply clear children of its container:

root.container.children.clear();
root.container.children.clear();

Root element is now empty (as newly created) and can be used to add any other charts to it.

Reusing root element can be faster than completely destroying it and creating a new element.

Disposing

If we don't need root element anymore, we can dispose it, by calling its dispose() method:

root.dispose();
root.dispose();

Disposing root element will automatically dispose all its children charts as well. No need to dispose them separately.

NOTETrying to create a new root element in a container before disposing the old one that is currently residing there, will result in an error.

If we do not have reference to a previously created root element, we can find it among am5.registry.rootElements, which is an array that holds all root elements.

am5.array.each(am5.registry.rootElements, function(root) {
  if (root.dom.id == divId) {
    root.dispose();
  }
});
am5.array.each(am5.registry.rootElements, function(root) {
  if (root.dom.id == divId) {
    root.dispose();
  }
});

See the Pen
Disposing previously created Root element
by amCharts team (@amcharts)
on CodePen.0

Controlling auto-resize

The root element will automatically resize itself if the size of its parent <div> element changes.

It can be disabled using autoResize property:

root.autoResize = false;
root.autoResize = false;

If set that way, root element will ignore any size changes in its parent and will remain at the same size it was first initialized with.

To manually trigger a resize for new dimensions, use resize() method:

root.resize();
root.resize();

Chart ready event

In some cases we may need to know when the chart is ready and all initial animations have played out.

While there's no such event built-in, we can utilize root element's frameended event with debounced handler to catch precise moment when chart is done painting and animating.

let timeout;

root.events.on("frameended", exportChart);

function exportChart() {
  if (timeout) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(function() {
    root.events.off("frameended", exportChart);
    console.log("Chart ready!");
  }, 100)
}
var timeout;

root.events.on("frameended", exportChart);

function exportChart() {
  if (timeout) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(function() {
    root.events.off("frameended", exportChart);
    console.log("Chart ready!");
  }, 100)
}

Each time something is updated on the chart and some elements are repainted, its root element's frameended event kicks in.

Our code waits until there's an idle moment of at least 100ms, before "deciding" the chart is fully functional and initial animations are played out.