Search code examples
javascriptdjangodictionarycolorsleaflet

How display circleMarker data using several colors?


How display circleMarker data using several colors according to magnitude value. For example this map (https://cartonumerique.blogspot.com/2023/02/seismes-en-Turquie-et-Syrie.html)? Here is my map function and my map script.

#views.py
def data(request):
   all_evens = Even.objects.all()
   _data = [[obj.name, obj.date, obj.latitude, obj.longitude, obj.magnitude] for obj in all_evens]
   return JsonResponse (_data, safe=False)



#evenmap.html
<!DOCTYPE html>
{% load static %}
<html lang ="en">
    <body>

    </body>

    {% block js %}
        <script>
            var even = L.layerGroup()
            $.ajax({
                url:"{% url 'even:data' %}",
                type:"GET"
                success: function(response){
                    response.forEach(obj =>{
                        L.circleMarker([obj[2], obj[3]], {
                            radius: obj[4] * 3,
                            fillColor: "#ff7800",
                            color: "#000",
                            weight: 1,
                            opacity: 1,
                            fillOpacity: 0.6
                            }).bindPopup('Name: ' + obj[0] + '</br>' + 'Date: ' + 
                            obj[1] + '</br>' + 'Latitude: ' + obj[2] + '</br>' + 
                            'Longitude: ' + obj[3] + '</br>' + 'Magnitude: ' + obj[4] 
                            ).addTo(even)
                           });
                          },
                        error: function(response){
                            alert(response.statusText);
                        }
                   });
               </script>
           {% end block js %}
    </html>

Solution

  • To display circle markers with different colors based on magnitude value data, you need to define a color scale first. You can define a color ramp like below:

    var color_scale = d3.scaleLinear()
      .domain([2, 5, 8])
      .range(['green', 'yellow', 'red']);
    

    Note: This color scale maps magnitude values between 2 and 5 to green, values between 5 and 8 to yellow, and values greater than 8 to red. You can modify it as needed.

    Now, You can use these color scale values to set the fill color of each circle marker in your JavaScript code like below:

    L.circleMarker([obj[2], obj[3]], {
      radius: obj[4] * 3,
      fillColor: color_scale(obj[4]),
      color: "#000",
      weight: 1,
      opacity: 1,
      fillOpacity: 0.6
    }).bindPopup('Name: ' + obj[0] + '</br>' + 'Date: ' + 
      obj[1] + '</br>' + 'Latitude: ' + obj[2] + '</br>' + 
      'Longitude: ' + obj[3] + '</br>' + 'Magnitude: ' + obj[4] 
    ).addTo(even);
    

    Make sure you include the D3 library in your HTML file in order to use the d3.scaleLinear() function.

    You can check this codepen link I created as an example: https://codepen.io/gd17/pen/rNZwWPv

    Also, to add color using logically you can use if/else statements like below:

    L.circleMarker([obj[2], obj[3]], {
                                radius: obj[4] * 3,
                                fillColor: (function() {
                                    if (obj[4] >= 7) {
                                        return "#ff0000";
                                    } else if (obj[4] >= 5 && obj[4] < 7) {
                                        return "#ffa500";
                                    } else if (obj[4] >= 3 && obj[4] < 5) {
                                        return "#ffff00";
                                    } else {
                                        return "#00ff00";
                                    }
                                })(),
    color: "#000",
      weight: 1,
      opacity: 1,
      fillOpacity: 0.6
    }).bindPopup('Name: ' + obj[0] + '</br>' + 'Date: ' + 
      obj[1] + '</br>' + 'Latitude: ' + obj[2] + '</br>' + 
      'Longitude: ' + obj[3] + '</br>' + 'Magnitude: ' + obj[4] 
    ).addTo(even);