Skip to content

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.

Bullets plugin is available since amCharts 4 version 4.5.7.

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";

There are currently 4 complex bullet types included (with more planned to add in the future) with Bullets plugin:

Class

Example

Comment

FlagBullet

Draws a flag shape with optional text inside it. Flag is configurable down to colors, pole length, flag “waveness”, etc.

PinBullet

Draws a pin shape with optional image and/or text inside it.

PointedCircle

Simple version of PinBullet: same shape but no option to add text or image.

ShapeBullet

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.

Star

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();

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.

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;

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:

Open in CodePen

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 bullet
let bullet = series.bullets.push(new am4plugins_bullets.FlagBullet());
// Setting label to display values from data
bullet.label.text = "{bulletText}\n[bold]{valueY}[/]";
bullet.label.textAlign = "middle";
// Disabling all bullets, except ones that are explicitly enabled via data
bullet.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 data
bullet.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";
Open in CodePen

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.

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";

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;

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"
});

Here’s a complete example:

Open in CodePen

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 series
let 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 bullet
let pin = imageTemplate.createChild(am4plugins_bullets.PinBullet);
// Set what to display on rollover tooltip
pin.tooltipText = "{title}";
imageSeries.tooltip.pointerOrientation = "right";
// Configuring pin appearance
pin.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 data
pin.image = new am4core.Image();
pin.image.propertyFields.href = "imageURL";
// Creating a "heat rule" to modify "radius" of the bullet based
// on value in data
imageSeries.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;

And, here we go:

Open in CodePen

The below tool will help you visually select the best options for one of your bullets.

Open in CodePen