Plugin: Bullets
“Bullets” is a collection of configurable shapes (stars, pins, flags, etc.) that you can use as chart bullets, map markers, and anywhere else.
Availability
Section titled “Availability”Bullets plugin is available since amCharts 4 version 4.5.7.
Including the module
Section titled “Including the module”Before you can use this plugin you need to make sure you include it.
If you are using it in a TypeScript/ES6 application, you can import it as module. For pure JavaScript applications you’ll need to include a .js vesion
import * as am4plugins_bullets from "@amcharts/amcharts4/plugins/bullets";<script src="//cdn.amcharts.com/lib/4/plugins/bullets.js"></script>Bullet types
Section titled “Bullet types”There are currently 4 complex bullet types included (with more planned to add in the future) with Bullets plugin:
Class | Example | Comment |
|
| Draws a flag shape with optional text inside it. Flag is configurable down to colors, pole length, flag “waveness”, etc. |
|
| Draws a pin shape with optional image and/or text inside it. |
|
| Simple version of |
| A universal bullet that can take a few basic shapes as circle, diamond, square, etc. It’s useful when you need to connect shape of a bullet to data or simplify your bullet code. | |
|
| Draws a star shape with configurable number of parameters, including number of points, radius, rounding, etc. |
You can click on the link for each class for a reference of all available properties. Or you can continue reading and we’ll look at some of those later in the article, as well as present you with a bullet configurator.
In a nutshell, a bullet from Bullets plugin is an advanced shape that can be used virtually anywhere, even as a standalone element.
We’re going to look into few common usage cases shortly. But first, let’s see how we instantiate a bullet shape.
Just like any other visual class that derives from Sprite, we can instantiate it using new syntax. The name scope for items in this plugin is as follows: am4plugins_bullets.****. E.g.:
new am4plugins_bullets.FlagBullet();new am4plugins_bullets.FlagBullet();As series bullets
Section titled “As series bullets”The most common usage of bullets is enhancing Series - mostly LineSeries.
In the course of this chapter we’ll add and configure advanced bullets to a LineSeries, tied them to data, and even make them react to heat rules.
Adding a bullet to series
Section titled “Adding a bullet to series”Let’s add a Star bullet to a simple LineSeries:
let bullet = series.bullets.push(new am4plugins_bullets.Star());bullet.radius = 20;bullet.pointCount = 8;var bullet = series.bullets.push(new am4plugins_bullets.Star());bullet.radius = 20;bullet.pointCount = 8;{ // ... "series": [{ // ... "bullets": [{ "type": "Star", "radius": 20, "pointCount": 8 }] }]}As you can see, we are not just creating a bullet instance. We’re also setting some shape-specific settings, like in this instance we’re making our star have 20 pixel radius, and 8 points.
Let’s see how it turned out:
Tying to data
Section titled “Tying to data”For purpose of this task, let’s use a more complicated shape - a flag.
As it happens we have a FlagBullet in our Bullets plugin.
It’s not just a shape, though. It can also contain text label.
To make it more interesting, let’s selectively put flag bullets on only a few data points with unique text in them.
Here’s the code (follow comments in code for breakdown):
// Creating a bulletlet bullet = series.bullets.push(new am4plugins_bullets.FlagBullet());
// Setting label to display values from databullet.label.text = "{bulletText}\n[bold]{valueY}[/]";bullet.label.textAlign = "middle";
// Disabling all bullets, except ones that are explicitly enabled via databullet.disabled = true;bullet.propertyFields.disabled = "hideBullet";
// Allowing controlling pole height via data (negative height means upside down flag)// We also instruct pole to draw its color from "bulletColor" in databullet.propertyFields.poleHeight = "height";bullet.pole.propertyFields.stroke = "bulletColor";
// Background is a WavedRectangle, which we configure, as well as instruct// it to get its fill and border color from data field "bulletColor"bullet.background.waveLength = 15;bullet.background.fillOpacity = 0.5;bullet.background.propertyFields.fill = "bulletColor";bullet.background.propertyFields.stroke = "bulletColor";
// Add a circle to pole base.// Bullet is a Container, so we can add there anything.let circle = bullet.createChild(am4core.Circle);circle.radius = 4;circle.strokeWidth = 2;circle.stroke = am4core.color("#fff");circle.propertyFields.fill = "bulletColor";// Creating a bulletvar bullet = series.bullets.push(new am4plugins_bullets.FlagBullet());
// Setting label to display values from databullet.label.text = "{bulletText}\n[bold]{valueY}[/]";bullet.label.textAlign = "middle";
// Disabling all bullets, except ones that are explicitly enabled via databullet.disabled = true;bullet.propertyFields.disabled = "hideBullet";
// Allowing controlling pole height via data (negative height means upside down flag)// We also instruct pole to draw its color from "bulletColor" in databullet.propertyFields.poleHeight = "height";bullet.pole.propertyFields.stroke = "bulletColor";
// Background is a WavedRectangle, which we configure, as well as instruct// it to get its fill and border color from data field "bulletColor"bullet.background.waveLength = 15;bullet.background.fillOpacity = 0.5;bullet.background.propertyFields.fill = "bulletColor";bullet.background.propertyFields.stroke = "bulletColor";
// Add a circle to pole base.// Bullet is a Container, so we can add there anything.var circle = bullet.createChild(am4core.Circle);circle.radius = 4;circle.strokeWidth = 2;circle.stroke = am4core.color("#fff");circle.propertyFields.fill = "bulletColor";{ // ... "series": [{ // ... "bullets": [{ "type": "FlagBullet",
// Setting label to display values from data "label": { "text": "{bulletText}\n[bold]{valueY}[/]", "textAlign": "middle" },
// Disabling all bullets, except ones that are explicitly enabled via data "disabled": true, "propertyFields": { "disabled": "hideBullet" },
// Allowing controlling pole height via data (negative height means upside down flag) // We also instruct pole to draw its color from "bulletColor" in data "background": { "waveLength": 15, "fillOpacity": 0.5, "propertyFields": { "fill": "bulletColor", "stroke": "bulletColor" } },
// Add a circle to pole base. // Bullet is a Container, so we can add there anything. "children": [{ "type": "Circle", "radius": 4, "strokeWidth": 2, "stroke": "#fff", "propertyFields": { "fill": "bulletColor" } }] }] }]}Using ShapeBullet
Section titled “Using ShapeBullet”This type of bullet deserves a special mention.
It’s unique feature is that it can take multiple basic shapes, e.g. circle, diamond, triangle, etc.
Creating a shape bullet
Section titled “Creating a shape bullet”The shape type is set via string-based parameter shape.
For example, if we’d like to add diamond-shaped bullets to a LineSeries we could do this:
let bullet = series.bullets.push(new am4plugins_bullets.ShapeBullet());bullet.shape = "diamond";var bullet = series.bullets.push(new am4plugins_bullets.ShapeBullet());bullet.shape = "diamond";{ // ... "series": [{ // ... "bullets": [{ "type": "ShapeBullet", "shape": "diamond" }] }]}Setting size of the ShapeBullet
Section titled “Setting size of the ShapeBullet”Another convenient aspect of a ShapeBullet is that we don’t have to care about a number of different size-related settings like width, height, scale, radius, etc.
There’s a single property for that: size. Its value is in pixels.
Setting a size for such bullet is as easy as it sounds:
let bullet = series.bullets.push(new am4plugins_bullets.ShapeBullet());bullet.shape = "diamond";bullet.size = 20;var bullet = series.bullets.push(new am4plugins_bullets.ShapeBullet());bullet.shape = "diamond";bullet.size = 20;{ // ... "series": [{ // ... "bullets": [{ "type": "ShapeBullet", "shape": "diamond", "size": 20 }] }]}Binding shape and size to data
Section titled “Binding shape and size to data”Having both shape and size as basic properties allows us to easily bind them to data via property fields and even heat rules.
let bullet = series.bullets.push(new am4plugins_bullets.ShapeBullet());bullet.propertyFields.shape = "bullet";
series.heatRules.push({ "target": bullet, "property": "size", "min": 15, "max": 30, "dataField": "valueY"});var bullet = series.bullets.push(new am4plugins_bullets.ShapeBullet());bullet.propertyFields.shape = "bullet";
series.heatRules.push({ "target": bullet, "property": "size", "min": 15, "max": 30, "dataField": "valueY"});{ // ... "series": [{ // ... "heatRules": [{ "target": "bullets[0]", "property": "size", "min": 15, "max": 30, "dataField": "valueY" }], "bullets": [{ "type": "ShapeBullet", "shape": "diamond", "size": 20 }] }]}Here’s a complete example:
As map markers
Section titled “As map markers”Now, let’s try these out on a Map, but go even deeper.
We are going to use PinBullet here. We’ll also display an image URL for which we’ll feed from data.
We’ll also use “heat rules” to dynamically set radius of the bullet to indicate value set in data. Again, please follow commends in code for pointers on what we are doing.
// Image serieslet imageSeries = chart.series.push(new am4maps.MapImageSeries());let imageTemplate = imageSeries.mapImages.template;imageTemplate.propertyFields.longitude = "longitude";imageTemplate.propertyFields.latitude = "latitude";imageTemplate.nonScaling = true;
// Creating a pin bulletlet pin = imageTemplate.createChild(am4plugins_bullets.PinBullet);
// Set what to display on rollover tooltippin.tooltipText = "{title}";imageSeries.tooltip.pointerOrientation = "right";
// Configuring pin appearancepin.background.fill = chart.colors.getIndex(0);pin.background.fillOpacity = 0.7;pin.background.pointerAngle = 120;pin.background.pointerBaseWidth = 10;
// Adding an image with its "href" attribute tied to values in datapin.image = new am4core.Image();pin.image.propertyFields.href = "imageURL";
// Creating a "heat rule" to modify "radius" of the bullet based// on value in dataimageSeries.heatRules.push({ "target": pin.background, "property": "radius", "min": 20, "max": 40, "dataField": "value"});
// Add a circle to pin base.// Bullet is a Container, so we can add there anything.let circle = pin.createChild(am4core.Ellipse);circle.radius = 6;circle.radiusY = 3;circle.strokeWidth = 0;circle.fillOpacity = 0.1;circle.zIndex = -1;// Image seriesvar imageSeries = chart.series.push(new am4maps.MapImageSeries());var imageTemplate = imageSeries.mapImages.template;imageTemplate.propertyFields.longitude = "longitude";imageTemplate.propertyFields.latitude = "latitude";imageTemplate.nonScaling = true;
// Creating a pin bulletvar pin = imageTemplate.createChild(am4plugins_bullets.PinBullet);
// Set what to display on rollover tooltippin.tooltipText = "{title}";imageSeries.tooltip.pointerOrientation = "right";
// Configuring pin appearancepin.background.fill = chart.colors.getIndex(0);pin.background.fillOpacity = 0.7;pin.background.pointerAngle = 120;pin.background.pointerBaseWidth = 10;
// Adding an image with its "href" attribute tied to values in datapin.image = new am4core.Image();pin.image.propertyFields.href = "imageURL";
// Creating a "heat rule" to modify "radius" of the bullet based// on value in dataimageSeries.heatRules.push({ "target": pin.background, "property": "radius", "min": 20, "max": 40, "dataField": "value"});
// Add a circle to pin base.// Bullet is a Container, so we can add there anything.var circle = pin.createChild(am4core.Ellipse);circle.radius = 6;circle.radiusY = 3;circle.strokeWidth = 0;circle.fillOpacity = 0.1;circle.zIndex = -1;{ // ... "series": [{ // Image series "type": "MapImageSeries",
// Set what to display on rollover tooltip "tooltipText": "{title}", "tooltip": { "pointerOrientation": "right" },
// Creating a "heat rule" to modify "radius" of the bullet based // on value in data "heatRules": [{ "target": "children[0].background", "property": "radius", "min": 20, "max": 40, "dataField": "value" }],
"mapImages": [{ "propertyFields": { "longitude": "longitude", "latitude": "latitude" }, "nonScaling": true
"children": [{ // Creating a pin bullet "type": "PinBullet",
// Configuring pin appearance "background": { "fill": "#c00", "fillOpacity": 0.7, "pointerAngle": 120, "pointerBaseWidth": 10, },
// Adding an image with its "href" attribute tied to values in data "image": { "type": "Image", "propertyFields":{ "href": "imageURL" } },
// Add a circle to pole base. // Bullet is a Container, so we can add there anything. "children": [{ "type": "Ellipse", "radius": 6, "radiusY": 3, "strokeWidth": 0, "fillOpacity": 0.1, "zIndex": -1 }] }] }] }]}And, here we go:
Bullet configuration tool
Section titled “Bullet configuration tool”The below tool will help you visually select the best options for one of your bullets.



