Bart Driessen
Bart Driessen

Reputation: 48

How to plot clients geolocation on a Amcharts map (and deal with the asynchronous provision of the HTML5 geolocation)

I have a world map in my web application, powered by Amcharts4. I want to add a marker on the map, displaying the user's geolocation (using the HTML5 getCurrentPosition function. But the map is already generated while the coordinates are retrieved, how to push a new marker to the map after it has been drawn?

I have working versions of both the Amcharts map, including markers on the map, and of the geolocation function. Geolocation works asynchronously, the script continues while the location is retrieved, so the map is generated in the meantime. I'm not a big fan of waiting for the coordinates to be found before continuing, as this might imply a multiple seconds delay.

Essentially I am looking for functionality to push marker data to my Amcharts object after that object is displayed. This is my js for the map:

// Themes begin
am4core.useTheme(am4themes_animated);

// Create map instance
var chart = am4core.create("chartdiv", am4maps.MapChart);

// Set map definition
chart.geodata = am4geodata_worldLow;

// Set projection
chart.projection = new am4maps.projections.Miller();

// Series for World map
var worldSeries = chart.series.push(new am4maps.MapPolygonSeries());
worldSeries.exclude = ["AQ"];
worldSeries.useGeodata = true;

worldSeries.data = mapdata;

var polygonTemplate = worldSeries.mapPolygons.template;
polygonTemplate.tooltipText = "{text}";
polygonTemplate.adapter.add("tooltipText", function(text, ev) {
  if (!ev.dataItem.dataContext.text) {
    return "{name}";
  }
  return text;
})

polygonTemplate.fill = chart.colors.getIndex(0);
polygonTemplate.nonScalingStroke = true;
polygonTemplate.propertyFields.fill = "fill";
polygonTemplate.properties.fill = am4core.color("#dddddd");

chart.zoomControl = new am4maps.ZoomControl();

// Hover state
var hs = polygonTemplate.states.create("hover");
hs.properties.fill = am4core.color("#333");

// Create image series
var imageSeries = chart.series.push(new am4maps.MapImageSeries());

// Create a circle image in image series template so it gets replicated to all new images
var imageSeriesTemplate = imageSeries.mapImages.template;
var circle = imageSeriesTemplate.createChild(am4core.Circle);
circle.radius = 4;
circle.fill = am4core.color("#000");
circle.stroke = am4core.color("#FFFFFF");
circle.strokeWidth = 2;
circle.nonScaling = true;
circle.tooltipText = "{title}";

// Set property fields
imageSeriesTemplate.propertyFields.latitude = "latitude";
imageSeriesTemplate.propertyFields.longitude = "longitude";

// Add data for the three cities
imageSeries.data = [{
  "latitude": 51.561678, 
  "longitude": 5.049685,
  "title": "Rural Spark HQ"
}];

if(navigator.geolocation) { navigator.geolocation.getCurrentPosition(showPosition); } 
function showPosition(position) {
    clientlocation = ({"latitude": position.coords.latitude, "longitude": position.coords.longitude, "title": "I am here!"});
    console.log(clientlocation)
    //push this clientlocation data to the map somehow?
}

I can see the client location in the console, but I didn't find any method to get it on the map.

Upvotes: 1

Views: 318

Answers (1)

Samuel Philipp
Samuel Philipp

Reputation: 11040

You just can add the new object (clientlocation) to imageSeries.data:

imageSeries.addData(clientlocation);

Or you can just add the data by reassigning the data field:

imageSeries.data = [...imageSeries.data, clientlocation];

Here is a code pen as reference.

Upvotes: 1

Related Questions