1

I am trying to find a way to have my CircleMarkers resize themselves after zooming in or out so that they scale properly with the map. So far, I have tried firing map.InvalidateSize() on the zoomend event but that does not seem to have any effect. Refreshing the feature layer also does not change the behavior. You can access my map at this link (sorry for the untrusted certificate).

My ultimate goal is for the circle markers to be reduced in size as the user zooms into the map, and then increase in size as the user zooms out.

Below is my code.

    var map = L.map('map',{ zoomControl:false, attributionControl: false, center: [38.980817, -98.760076], zoom: 4});
    L.tileLayer("https://cartodb-basemaps-b.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png", {maxZoom: 20, openLegendOnLoad: false, attribution:''}).addTo(map)
    var featureLayer = new L.featureGroup().addTo(map);
    function getZoomLevel() {
        map.on('zoomend', function() {
            map.invalidateSize();
        });
        return map.getZoom();
    };
    fetch('https://craftfamily.ddns.net/data')
      .then(response => {
        return response.json()
      })
      .then(data => {
        for (var key in data.recordset) {
          //console.log(key, data.recordset[key]);
          var lat = data.recordset[key].LATITUDE;
          var lon = data.recordset[key].LONGITUDE;
          var name = data.recordset[key].NAME;
          var location = data.recordset[key].LOCATION;
          var ticker = data.recordset[key].TICKER;
          var price = data.recordset[key].PRICE;
          var change = parseFloat(data.recordset[key].CHANGE).toFixed(2);
          var marker = L.circle([lat, lon], price*10000/getZoomLevel()).bindPopup("<b>"+name+" ("+ticker+")</b><br>$"+price + " (" + change +")<br>"+location+"<br>"+lat+", "+lon).addTo(map);
        }
      })
      .catch(err => {
      });

1 Answer 1

0

Circle radius is just constant number, not dynamic function. When you are setting circle radius with your formula, radius is calculated and result stored as constant, not formula.

If you want radius of markers to change dynamically with zoom change, you have to iterate through all markers at zoomend event and change their radius with setRadius method. Since marker radius is dependant on price, to have it at hand when calaculating radius, it can be stored as _price property of marker when creating marker.

Code could then look something like this:

var map = L.map('map',{ zoomControl:false, attributionControl: false, center: [38.980817, -98.760076], zoom: 4});
L.tileLayer("https://cartodb-basemaps-b.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png", {maxZoom: 20, openLegendOnLoad: false, attribution:''}).addTo(map)
var myMarkers = L.layerGroup();

function markerRadius(price) {
  return price * 10000 / map.getZoom();
}

fetch('https://craftfamily.ddns.net/data')
  .then(response => {
    return response.json()
  })
  .then(data => {
    for (var key in data.recordset) {
      //console.log(key, data.recordset[key]);
      var lat = data.recordset[key].LATITUDE;
      var lon = data.recordset[key].LONGITUDE;
      var name = data.recordset[key].NAME;
      var location = data.recordset[key].LOCATION;
      var ticker = data.recordset[key].TICKER;
      var price = data.recordset[key].PRICE;
      var change = parseFloat(data.recordset[key].CHANGE).toFixed(2);
      var marker = L.circle([lat, lon], markerRadius(price)).bindPopup("<b>"+name+" ("+ticker+")</b><br>$"+price + " (" + change +")<br>"+location+"<br>"+lat+", "+lon);
      marker._price = price;
      marker.addTo(myMarkers);
    }
  })
  .catch(err => {
  });

myMarkers.addTo(map);

map.on('zoomend', function() {
  myMarkers.eachLayer(function (marker) {
    marker.setRadius(markerRadius(marker._price));
  });
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.