Skip to content

Custom polygons on Map Chart

If you are working with Map Chart, you’re probably already familiar with MapPolygonSeries thatr get their geographical data from loaded map file, or “geodata”. However, Map polygons are not limited to this source of data. You can draw any shape and polygon on the map using in-line lat/long coordinates. This tutorial will show how.

In the course of this tutorial we will build a custom polygon, depicting a so called Bermuda triangle.

We’ve already created a map, pre-zoomed on the Caribbean, which we will use as a base.

Open in CodePen

While not exactly necessary, let’s add three map images - one for each corner of our triangle, so that we have some reference points.

let placeSeries = chart.series.push(new am4maps.MapImageSeries());let place = placeSeries.mapImages.template;place.nonScaling = true;place.propertyFields.latitude = "latitude";place.propertyFields.longitude = "longitude";placeSeries.data = [{ latitude: 25.774, longitude: -80.190, name: "Miami", hcenter: "right", vcenter: "middle"}, { latitude: 18.466, longitude: -66.118, name: "San Juan", hcenter: "left", vcenter: "middle"}, { latitude: 32.321, longitude: -64.757, name: "Bermuda", hcenter: "middle", vcenter: "bottom"}];let circle = place.createChild(am4core.Circle);circle.radius = 5;circle.fill = am4core.color("#e33");circle.stroke = am4core.color("#fff");circle.strokeWidth = 2;let label = place.createChild(am4core.Label);label.padding(15, 15, 15, 15);label.propertyFields.text = "name";label.propertyFields.horizontalCenter = "hcenter";label.propertyFields.verticalCenter = "vcenter";
Open in CodePen

Now that we have our reference points, we need to create our Map polygon.

We’re going to create a separate MapImageSeries to hold our custom map polygons.

Differently from the main Map image series for countries, we are not going to set useGeodata because we don’t want it to get polygon data from loaded map file - we will be defining polygon coordinates ourselves.

“Custom” polygon series works identically as regular polygon series, except we also need to provide GeoJSON data for each polygon.

The data property, responsible for holding that data is geoPolygon. Just like in GeoJSON format for multi-polygon objects. In a nutshell it is an array of polygon objects. Each item in the array represents a single polygon, or a chunk of land. If there’s one chunk, there will be one item. If there are more chunks, there will be several items in this array.

Each polygon is another array, that holds objects for each joint in the polygons contours, represented by latitude/longitude coordinates.

let shapeSeries = chart.series.push(new am4maps.MapPolygonSeries());shapeSeries.data = [{ "title": "Bermuda triangle", "geoPolygon": [ [ {latitude: 25.774, longitude: -80.190}, {latitude: 32.321, longitude: -64.757}, {latitude: 18.466, longitude: -66.118}, {latitude: 25.774, longitude: -80.190} ] ]}];let shapeTemplate = shapeSeries.mapPolygons.template;shapeTemplate.stroke = am4core.color("#e33");shapeTemplate.strokeWidth = 2;shapeTemplate.fill = shapeTemplate.stroke;shapeTemplate.fillOpacity = 0.2;shapeTemplate.nonScalingStroke = true;
Open in CodePen

A triangle polygon we just created is not a mere few lines connected and filled.

It’s a full-fledged MapPolygon object, which can be configured just like any other polygon, including setting appearance, property fields, states, events, etc.