Skip to content

Using Responsive Features

We can’t imagine today’s web without responsive features. amCharts 4 has a powerful responsive capabilities built into its core.

This tutorial will explain how you can enable, customize and use amCharts 4 responsive features.

Imagine your everyday regularly-boring normal chart like this:

Looks good at full size - 900 pixels wide.

Now, let’s imagine we’ll need to cram it into less space, like 600 pixels:

Columns are kinda crammed together, but the chart is still passable.

Let’s go deeper: 400px.

The chart is now bordering of hardly comprehensible. Suddenly we are aware of wasted white space around the chart, and the legend that takes up whopping third of the available area.

Deeper? Alright: 200px.

OK, this is getting ridiculous, but let’s try to go even deeper: 100px.

Congratulations! We now have a completely useless chart on our hands.

You may argue, that nobody in their right mind would make chart container that small, and you might be right.

However, we’re living in a multi-platform world, where the designer of a website is not in complete control anymore. The web page that looks perfectly fine on desktop, might crumble down like in the above examples when viewed on a phone, that uses much lesser resolution.

Responsive features in amCharts 4 allow overriding and dynamically changing certain settings or features of the chart based on the actual available space.

For example, we could have made our chart look better if we got rid of padding and legend when space is scarce. Axis labels could go inside plot area, further saving us space.

This dynamic transformation is controlled using Responsive Rules. We’re just going to call them “Rules” from now on.

A Rule is basically an object that does two things:

  1. Checks if current chart parameters matches certain conditions, i.e. “chart’s actual width is less than 400 pixels”;
  2. Generates a “State” object which has to be applied if the Rule is relevant.

This allows us to create chart once, and make it automatically adapt to various conditions.

Responsive settings in amCharts 4 are set via responsive property of the chart, which is an object of the type Responsive.

Since those are disabled by default, all we need to do in order to enable them is to set enabled = true:

chart.responsive.enabled = true;

That’s it. Our chart is now responsive-aware. Let’s see how we can use that.

Simply enabling responsive features will make an amCharts-curated set of default rules kick in.

Below table lists generic rules along the size break points when they kick in.

Element

Breakpoint

Comment

Chart itself

width <= 200 / height <= 200

Horizontal / vertical padding reduced to 10px.
Scrollbars are disabled.

width <= 100 / height <= 100

Horizontal / vertical padding set to 0.

Axes

width <= 200 / height <= 200

Horizontal / vertical axis labels are placed inside plot area.
Grid is disabled.

width <= 100 / height <= 100

Horizontal / vertical axis labels are disabled.

XY Series

width <= 200 and height <= 200

Bullets are disabled.

Percent Series (Pie, Funnel, Pyramid)

width <= 200 or height <= 200

Labels and ticks are disabled.

Legend

width <= 200

Move legend to bottom.

height <= 200

Move legend to right.

width <= 200 and height <= 200

Disable legend.

If you don’t want any default rules applied, simply set useDefault = false.

chart.responsive object has a property rules which is a list of Rules. A Rule is an object that corresponds to the IResponsiveRule interface, which means it has to have at least two methods:

  • relevant(target) - it is called so the rule can do its own calculations to determine whether it is relevant for the current situation;
  • state(target, stateId) - it is called when Responsive asks the Rule to generate a State that needs to be applied to the object if the Rule is currently relevant. (as determined by relevant() call)

REQUIRED READING Responsive works by applying states to various objects of the chart. States is a concept of temporarily applying set of property values to an object. For more information, please read our “Sates” article.

To create a new Rule, we create a new object, with two methods: relevant and state, then push() it into chart.responsive.rules:

chart.responsive.rules.push({ relevant: function(target) { // Code that determines if rule is currently relevant // and returns true or false return false; }, state: function(target, stateId) { // Code that creates a new SpriteState object to be // applied to target if Rule is "relevant" return; }});

Right now, the Rule above, does nothing. Let’s try tackling issues with our chart above, one by one.

Let’s start with a base chart at 400 by 400 px:

Open in CodePen

Technically, it’s still usable, however the space is not used efficiently.

First, we need to add code which checks whether the Rule is relevant under current chart conditions.

As we explained earlier, Rule’s relevant method is responsible for just that.

Let’s add a check whether chart is 400 pixel wide or less:

relevant: function(target) { if (target.pixelWidth <= 400) { return true; } return false;}

A relevant() method will receive a reference to object our responsive object is attached to - the chart.

We are using chart’s pixelWidth property (which returns current chart in pixels) to check whether it is 400px wide or less.

Instead of specifying pixel values and defining functions, you can use built-in pre-defined breakpoints, accessible via am4core.ResponsiveBreakpoints static class.

You can use its static pixel values:

Accessible via Value
am4core.ResponsiveBreakpoints.XXS 100
am4core.ResponsiveBreakpoints.XS 200
am4core.ResponsiveBreakpoints.S 300
am4core.ResponsiveBreakpoints.M 400
am4core.ResponsiveBreakpoints.L 600
am4core.ResponsiveBreakpoints.XL 800
am4core.ResponsiveBreakpoints.XXL 1000

Or via “relevant”-compatible functions:

Accessible via

Check

am4core.ResponsiveBreakpoints.widthXXS

width <= 100

am4core.ResponsiveBreakpoints.widthXS

width <= 200

am4core.ResponsiveBreakpoints.widthS

width <= 300

am4core.ResponsiveBreakpoints.widthM

width <= 400

am4core.ResponsiveBreakpoints.widthL

width <= 600

am4core.ResponsiveBreakpoints.widthXL

width <= 800

am4core.ResponsiveBreakpoints.widthXXL

width <= 1000

am4core.ResponsiveBreakpoints.heightXXS

height <= 100

am4core.ResponsiveBreakpoints.heightXS

height <= 200

am4core.ResponsiveBreakpoints.heightS

height <= 300

am4core.ResponsiveBreakpoints.heightM

height <= 400

am4core.ResponsiveBreakpoints.heightL

height <= 600

am4core.ResponsiveBreakpoints.heightXL

height <= 800

am4core.ResponsiveBreakpoints.heightXXL

height <= 1000

am4core.ResponsiveBreakpoints.maybeXXS

width <= 100 || height <= 100

am4core.ResponsiveBreakpoints.maybeXS

width <= 200 || height <= 200

am4core.ResponsiveBreakpoints.maybeS

width <= 300 || height <= 300

am4core.ResponsiveBreakpoints.maybeM

width <= 400 || height <= 400

am4core.ResponsiveBreakpoints.maybeL

width <= 600 || height <= 600

am4core.ResponsiveBreakpoints.maybeXL

width <= 800 || height <= 800

am4core.ResponsiveBreakpoints.maybeXXL

width <= 1000 || height <= 1000

am4core.ResponsiveBreakpoints.isXXS

width <= 100 && height <= 100

am4core.ResponsiveBreakpoints.isXS

width <= 200 && height <= 200

am4core.ResponsiveBreakpoints.isS

width <= 300 && height <= 300

am4core.ResponsiveBreakpoints.isM

width <= 400 && height <= 400

am4core.ResponsiveBreakpoints.isL

width <= 600 && height <= 600

am4core.ResponsiveBreakpoints.isXL

width <= 800 && height <= 800

am4core.ResponsiveBreakpoints.isXXL

width <= 1000 && height <= 1000

The “relevant” function we had before can be simplified using breakpoints:

relevant: am4core.ResponsiveBreakpoints.widthS

Defining a state to apply when the Rule is “relevant”

Section titled “Defining a state to apply when the Rule is “relevant””

Since our chart IS 400px or less, responsive will try to call Rule’s state() method expecting to receive a SpriteState object which it can then apply to chart.

For starters, let’s try to shave off margins, that are way to generous at this size:

state: function(target, stateId) { if (target instanceof am4charts.Chart) { let state = target.states.create(stateId); state.properties.paddingTop = 0; state.properties.paddingRight = 15; state.properties.paddingBottom = 5; state.properties.paddingLeft = 15; return state; } return null;}

Let’s see how our chart looks now:

Open in CodePen

Better already. But let’s not stop there. Let’s also make the following space-saving adjustments:

  • Tweak the legend to fit into a single line;
  • Put value axis labels inside plot area so they don’t take up so much space on the left;
  • Remove spacing between Scrollbar and plot area.

You can have more than one rule. The chart will check each rule if it’s relevant() and will apply it as it is, in the same order as you have rules set.

Let’s say we have three rules set:

  1. The first rule checks whether chart width is 400 pixels or less;
  2. The second rule checks whether the chart width is 300 pixels or less;
  3. The third rule checks if the width is 200 pixels or less.

And, we have a chart that is currently 300 pixels wide. What will happen is this:

  1. The first rule will be applied;
  2. The second rule will be applied;
  3. The third rule will not be applied.

This allows for very powerful combinations and setups to be created with rules overriding all or some of the settings set by other rules, and so on.

Open in CodePen

The following demo adds a custom rule on a PieChart.

Open in CodePen