amCharts 4 has built-in capabilities to display information as a Popup or a Modal window. This article will explain how you can use those to display information to users.
Popup or Modal?
Before we begin, let's figure out the difference between the two.
A Popup
is a small (or not) window that displays some kind of information in it. Usually it is displayed over other content, like chart or map, but in general does not obstruct interactivity with it. E.g. you can still interact with the chart around the Popup.
There can be any number of popups displayed at any given time.
A Modal
is much more stricter. If there's a Modal open, you don't get to do anything with the chart until Modal is closed. There can be only one Modal at the same time.
Opening
Opening a Popup
To open a Popup, we'll use chart's openPopup(content, title)
method:
chart.openPopup("Hello there!");
chart.openPopup("Hello there!");
This will create and open a new Popup. The function will also return a Popup
object, which we can use to configure it, as we'll see later on.
Opening a Modal
Opening a modal works in much the same way, except we'll be using openModal(content, title)
.
chart.openModal("OK. Now I'm serious.");
chart.openModal("OK. Now I'm serious.");
Since a chart can have only one and only Modal, opening Modal works a bit differently than opening a Popup.
Calling openModal()
will still return Modal
instance. It will also set chart's property modal
, which you can also use to configure or close Modal.
Popup/Modal content
Popup or Modal itself is an HTML element, which means that content can also be full-fledged HTML. You can use images, tables, iframes, and anything else HTML standard offers.
Unless specified otherwise, the modal will try to size itself to fit your content.
You can also set an optional title (second parameter) which will be displayed above content. Title can also be HTML.
Opening Popup on click
More often than not, we will need to open a Popup whenever user clicks or taps on something.
We can use "hit"
event for that.
For example, the following code will open a Popup whenever user clicks on a country on a World map:
polygonTemplate.events.on("hit", function(ev) { chart.closeAllPopups(); chart.openPopup("We clicked on <strong>" + ev.target.dataItem.dataContext.name + "</strong>"); });
polygonTemplate.events.on("hit", function(ev) { chart.closeAllPopups(); chart.openPopup("We clicked on <strong>" + ev.target.dataItem.dataContext.name + "</strong>"); });
{ // ... "series": [{ // ... "columns": { "events": { "hit": function(ev) { chart.closeAllPopups(); chart.openPopup("We clicked on <strong>" + ev.target.dataItem.dataContext.name + "</strong>"); } } } }] }
MORE INFO To refresh your knowledge on event listeners, head over to "Event Listeners" article.
See the Pen amCharts 4: Popups/Modals (1) by amCharts (@amcharts) on CodePen.
Closing
Closing a Popup
To close a Popup we can call its close()
method.
popup.close();
popup.close();
Closing all open Popups
To close all open Popups at once, we can call chart's closeAllPopups()
method.
chart.closeAllPopups();
chart.closeAllPopups();
Closing a Modal
Similarly, closing a modal is as simple as calling its close()
method.
Since we have a reference for our Modal in chart's object, we don't have to maintain it in a separate variable:
chart.modal.close();
chart.modal.close();
Closing example
This example will show how we can close all open popups/modals on a MapChart
when clicking outside of the map area.
See the Pen amCharts 4: Close popups on body click by amCharts team (@amcharts) on CodePen.
Configuring Popup/Modal
Appearance via CSS
As we mentioned before, a Popup/Modal is an HTML element. Its appearance is configured using CSS.
By default the chart will load a standard piece of CSS that configures appearance of the Popup/Modal.
Your page's CSS can override the built-in one.
Or, you can completely disable loading of built-in CSS by setting Popup/Modal's defaultStyles = false
.
Here's the default CSS for your reference:
.ampopup { overflow: visible; position: absolute; top: 0; left: 0; z-index: 2000 } .ampopup-curtain { width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 2001; background: #fff; opacity: 0.5 } .ampopup-title { font-weight: bold; font-size: 120% } .ampopup-content { padding: 1em 2em; background: rgb(255, 255, 255); background-color: rgba(255, 255, 255, 0.8); display: inline-block; position: absolute; max-width: 90%; max-height: 90%; overflow: auto; z-index: 2002 } .ampopup-close { display: block; position: absolute; top: 0.3em; right: 0.3em; background-color: rgb(100, 100, 100); background: rgba(100, 100, 100, 0.1) url(data:image/svg+xml;charset=utf-8;base64,PHN2ZyBoZWlnaHQ9IjUxMiIgdmVyc2lvbj0iMSIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHdpZHRoPSI1MTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQ0NS4yIDEwOS4ybC00Mi40LTQyLjRMMjU2IDIxMy42IDEwOS4yIDY2LjhsLTQyLjQgNDIuNEwyMTMuNiAyNTYgNjYuOCA0MDIuOGw0Mi40IDQyLjRMMjU2IDI5OC40bDE0Ni44IDE0Ni44IDQyLjQtNDIuNEwyOTguNCAyNTYiLz48L3N2Zz4=) no-repeat center; background-size: 80%; width: 1.2em; height: 1.2em; cursor: pointer }
Class prefixes
The class prefixes are configurable.
The ampopup
part is added by the Popup/Modal itself, and can be configured using popup's classPrefix
.
NOTE If you would like to set classPrefix
for all popups that are opened, without setting it on each of those individually, set it on chart.popups.template.classPrefix
.
Positioning
Popup or Modal can be positioned either relatively or absolutely.
There are two sets of properties that control placement of Popup/Modal.
Positioning by setting horizontal and vertical alignment
There are two properties that control horizontal and vertical alignment of the Popup/Module.
Property | Available values | Comment |
---|---|---|
align |
"left" , "center" (default), "right" , "none" |
Horizontal alignment of Popup. |
verticalAlign |
"top" , "middle" (default), "bottom" , "none" |
Vertical alignment of Popup. |
By default Popup/Modal is displayed in the center of the chart. (align = "center"
and verticalAlign = "middle"
)
If we wanted our Popup to open in the lower/right corner, we'd use align = "right"
and verticalAlign = "bottom"
instead.
Positioning using absolute coordinates
If we don't want Popup/Modal aligned, we can set its position manually using these properties:
Property | Type | Comment |
---|---|---|
bottom |
number (pixels) or Percent |
Distance from the bottom of the chart container. |
left |
number (pixels) or Percent |
Distance from the left edge of the chart container. |
right |
number (pixels) or Percent |
Distance from the right edge of the chart container. |
top |
number (pixels) or Percent |
Distance from the top of the chart container. |
NOTE If we use absolute positioning properties such as left
or top
the alignment settings will be ignored.
Positioning relative to mouse
If rather than specifying fixed position for the popup, we can make it relative to a mouse cursor.
Technically, that will require us to use absolute coordinates. Except, we will extract it from an event that triggered our Popup code.
Building upon our previous example, where we were using "hit"
event, we'll extract exact coordinates where that event occurred at.
For the "hit"
event, we know that, amount other stuff, it also passes in svgPoint
in its parameter object. It's an object that will contain x
and y
coordinates within chart container, where the event occurred.
We can use that to position Popup using its left
and top
properties:
polygonTemplate.events.on("hit", function(ev) { chart.closeAllPopups(); let popup = chart.openPopup("We clicked on <strong>" + ev.target.dataItem.dataContext.name + "</strong>"); popup.left = ev.svgPoint.x + 15; popup.top = ev.svgPoint.y + 15; });
polygonTemplate.events.on("hit", function(ev) { chart.closeAllPopups(); var popup = chart.openPopup("We clicked on <strong>" + ev.target.dataItem.dataContext.name + "</strong>"); popup.left = ev.svgPoint.x + 15; popup.top = ev.svgPoint.y + 15; });
{ // ... "series": [{ // ... "columns": { "events": { "hit": function(ev) { chart.closeAllPopups(); var popup = chart.openPopup("We clicked on <strong>" + ev.target.dataItem.dataContext.name + "</strong>"); popup.left = ev.svgPoint.x + 15; popup.top = ev.svgPoint.y + 15; } } } }] }
Curtain
A "curtain" is a semi-transparent shade put over all of the chart, fading it all out, and making the popup content more prominent.
A Modal will display it by default.
A Popup will not. To enable curtain for a Popup (or to disable one for a Modal) use showCurtain
property:
popup.showCurtain = true;
popup.showCurtain = true;
Controlling closing
By default a Popup/Modal can be closed in a number of ways: hitting ESC key, clicking Close button or the curtain.
You can disable this functionality using closable
property:
popup.closable = false;
popup.closable = false;
A non-closable Popup/Modal can only be closed using its method close()
.
Accessing Popup/Modal elements
In case you'd like to access actual DOM elements that comprise Popup or Modal - to modify them or completely override them - you can use the elements
property, which holds keyed references to each of those elements.
Property | Type | Default classname | Comment |
---|---|---|---|
close |
<a> |
ampopup-close |
Close button. |
content |
<div> |
ampopup-content |
A container that Popup/Modal contents are placed in, including controls like Close button and Title. |
curtain |
<div> |
ampopup-curtain |
A curtain element. |
title |
<div> |
ampopup-title |
A title element. |
wrapper |
<div> |
ampopup |
A wrapper element that all of the Popup/Modal elements are placed in. |
As an example, if we'd want to replace the built-in Close button with some other element, we'd do this:
popup.elements.close = myCustomCloseButton;
popup.elements.close = myCustomCloseButton;
Popup container
Popup/Modal's object holds a reference - container
- to the container it is placed in.
This is the same container the chart is placed in. Modify with caution.
It can also be used to place Popups/Modals in a completely separate container outside chart, or to cover the whole page by setting it to document.body
:
chart.modal.container = document.body;
chart.modal.container = document.body;
{ // ... "modal": { "container": document.body } }
Error Modal
Whenever a critical error occurs in the chart, it opens its Modal to display information about what happened.
You can use chart.modal
to access Modal instance to configure it the way you see fit.
Event handlers
Popups (and Modals) can have event handlers attached to them as well.
For now there are two events: "opened"
and "closed"
. Their meaning is self-explanatory.
You can attach an event to a specific Popup object, or to all popups, using popups.template
. E.g.:
chart.popups.template.events.on("opened", function(ev) { console.log(ev); }); chart.popups.template.events.on("closed", function(ev) { console.log(ev); });
chart.popups.template.events.on("opened", function(ev) { console.log(ev); }); chart.popups.template.events.on("closed", function(ev) { console.log(ev); });
{ // ... "popups": { "events": { "opened": function(ev) { console.log(ev); }, "closed": function(ev) { console.log(ev); } } } }
Or, if you'd like to have those events on a modal:
chart.modal.events.on("opened", function(ev) { console.log(ev); }); chart.modal.events.on("closed", function(ev) { console.log(ev); });
chart.modal.events.on("opened", function(ev) { console.log(ev); }); chart.modal.events.on("closed", function(ev) { console.log(ev); });
{ // ... "modal": { "events": { "opened": function(ev) { console.log(ev); }, "closed": function(ev) { console.log(ev); } } } }
MORE INFO For more information about how event listeners work in amCharts 4, visit "Event Listeners" article.