Lukasz
Lukasz

Reputation: 2616

Leaflet highlight marker when mouseover with different colors

I'm trying to setup a marker highlight when I mouse over a marker. My markers are coloured based on whether a user is active or not. If they are active the marker further distinguishes between males and females.

My HTML file looks like:

<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml">

<head profile="http://gmpg.org/xfn/11">
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

  <!--The CSS files-->
  <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css"/>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" type="text/css">

  <!--The dependent .js files-->
  <script type="text/javascript" src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
  <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
  <script type="text/javascript" src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
</head>

<body>
    <title>Circle Highlight</title>
    <style> html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }

    #map {
      height: 100%;
    }
    </style>
</body> 

<div id="map"></div>
<script type='text/javascript' src='C:\Users\Lukasz Obara\OneDrive\Programing\HTML\Slider\circles.geojson'></script>
<script type='text/javascript' src='C:\Users\Lukasz Obara\OneDrive\Programing\HTML\Slider\leaflet_demo_circles.js'></script>

my circles.geojson file:

var circles= {
    "type": "FeatureCollection",
    "features": [{
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [35.1966, 31.7825]
        },
        "properties": {
            "GPSId": "2",
            "DateStart": "2015-06-23",
            "DateClosed": "2016-01-23",
            "GPSUserName": "fake2",
            "GPSUserColor": "#FF5500",
            "Gender": "Male",
            "Active": 1
        }
    }, {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [35.2, 31.780117]
        },
        "properties": {
            "GPSId": "6",
            "DateStart": "2015-06-23",
            "DateClosed": "2016-01-23",
            "GPSUserName": "fake1",
            "GPSUserColor": "#00FF57",
            "Gender": "Female",
            "Active": 0
        }
    }, {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [35.201715, 31.779548]
        },
        "properties": {
            "GPSId": "15",
            "DateStart": "2015-02-21",
            "DateClosed": "2016-02-28",
            "GPSUserName": "fake10",
            "GPSUserColor": "#00FF57",
            "Gender": "Male",
            "Active": 1
        }
    }, {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [35.200987, 31.779606]
        },
        "properties": {
            "GPSId": "16",
            "DateStart": "2015-01-01",
            "DateClosed": "2016-01-01",
            "GPSUserName": "fake11",
            "GPSUserColor": "#00FF57",
            "Gender": "Female",
            "Active": 0
        }
    }, {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [35.200987, 31.780522]
        },
        "properties": {
            "GPSId": "17",
            "DateStart": "2015-02-04",
            "DateClosed": "2016-09-21",
            "GPSUserName": "fake12",
            "GPSUserColor": "#00FF57",
            "Gender": "Male",
            "Active": 1
        }
    }]
};

and my javascript leaflet_demo_circles.js file

var map = L.map( 'map', {
center: [31.780117, 35.2],
zoom: 17,
minZoom: 2,
maxZoom: 20
});

L.tileLayer('http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright" title="OpenStreetMap" target="_blank">OpenStreetMap</a> contributors | Tiles Courtesy of <a href="http://www.mapquest.com/" title="MapQuest" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png" width="16" height="16">',
    subdomains: ['otile1','otile2','otile3','otile4']
}).addTo(map);

// This will produce a static black circle
var circle2 = L.circle([31.7805, 35.203], 8, {
    color: "#000000",
    stroke: true,
    fillColor: "#000000",
    weight: 2,
    fillOpacity: 0.7
}).addTo(map);

///////////////////////////////////////////////////////////////////////////
//Aesthetics                                                             //
///////////////////////////////////////////////////////////////////////////

//define styles for circle markers
var blueMarker ={
    radius: 8,
    stroke: true,
    color: "#0000FF",
    weight: 2,
    opacity: 1,
    fill: true,
//  fillColor: "#FF0000",
    fillOpacity: 0.5
}

var pinkMarker ={
    radius: 8,
    stroke: true,
    color: "#FF99FF",
    weight: 2,
    opacity: 1,
    fill: true,
//  fillColor: "#FF0000",
    fillOpacity: 0.5
}

var greyMarker = {
    radius: 8,
    stroke: true,
    color: "#808080",
    weight: 2,
    opacity: 1,
    fill: true,
//  fillColor: "#FF0000",
    fillOpacity: 0.5
};

// Highlighted circles ///////////////////
var blueMarkerHighlighted ={
    radius: 10,
    stroke: true,
    color: "#0000FF",
    weight: 2,
    opacity: 1,
    fill: true,
//  fillColor: "#FF0000",
    fillOpacity: 0.75
}

var pinkMarkerHighlighted ={
    radius: 10,
    stroke: true,
    color: "#FF99FF",
    weight: 2,
    opacity: 1,
    fill: true,
//  fillColor: "#FF0000",
    fillOpacity: 0.75
}

var greyMarkerHighlighted = {
    radius: 10,
    stroke: true,
    color: "#808080",
    weight: 2,
    opacity: 1,
    fill: true,
//  fillColor: "#FF0000",
    fillOpacity: 0.75
};

///////////////////////////////////////////////////////////////////////////
//functions to attach styles and popups to the marker layer              //
///////////////////////////////////////////////////////////////////////////

//Assigns colors based on activity and gender
function colors (feature, layer) {
    if (feature.properties.Active === 1) {
        if (feature.properties.Gender === "Male") {
            return L.circleMarker(layer, blueMarker);
        } else {
            return L.circleMarker(layer, pinkMarker);
       }
    } else {
        return L.circleMarker(layer, greyMarker);
    }
};

function popup (feature, layer) {
    layer.bindPopup("<h1>" + feature.properties.GPSUserName + "</h1>");
};

///////////////////////////////////////////////////////////////////////////
//displaying the data on the map                                         //
///////////////////////////////////////////////////////////////////////////

dotlayer = L.geoJson(circles, {
    pointToLayer: colors,
    onEachFeature: popup
}).addTo(map);

I tried replacing the two above functions with the following to assign a colour and have an effect when I mouse over, but I have no success.

function dotStyleDefault() {
    if (feature.properties.Active === 1) {
        if (feature.properties.Gender === "Male") {
            return blueMarker;
        } else {
            return pinkMarker;
       }
    } else {
        return greyMarker;
    }
};

function dotStyleHighlight(){
    if (feature.properties.Active === 1) {
        if (feature.properties.Gender === "Male") {
            return blueMarkerHighlighted;
        } else {
            return pinkMarkerHighlighted;
       }
    } else {
        return greyMarkerHighlighted;
    }
}

function highlightDot(e) {
    var layer = e.target;
    layer.setStyle(dotStyleHighlight);
};

function resetDotHighlight(e) {
    var layer = e.target;
    layer.setStyle(dotStyleDefault);
};

function onEachDot(feature, layer) {
    layer.on({
        mouseover: highlightDot,
        mouseout: resetDotHighlight
    });
    layer.bindPopup('<table style="width:150px"><tbody><tr><td><div><b>name:</b></div></td><td><div>' + feature.properties.GPSId + '</div></td></tr><tr class><td><div><b>year:</b></div></td><td><div>' + feature.properties.DateStart + '</div></td></tr></tbody></table>');
};

///////////////////////////////////////////////////////////////////////////
//displaying the data on the map                                         //
///////////////////////////////////////////////////////////////////////////

dotlayer = L.geoJson(circles, {
    pointToLayer: function (feature, latlng) {
        return L.circleMarker(latlng, dotStyleDefault);
    },
    onEachFeature: onEachDot
}).addTo(map);

Upvotes: 2

Views: 3297

Answers (1)

Lukasz
Lukasz

Reputation: 2616

A solution that I found was to modify the geojson file to include a Colour property. Hence circles.geojson would resemble

var circles = {
    "type": "FeatureCollection",
    "features": [{
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [35.1966, 31.7825]
        },
        "properties": {
            "GPSId": "2",
            "DateStart": "2015-06-23",
            "DateClosed": "2016-01-23",
            "GPSUserName": "2",
            "GPSUserColor": "#FF5500",
            "Gender": "Male",
            "Active": 1,
            "Colour": "#0000FF" //THIS IS ADDED BASED ON ACTIVITY LEVEL AND GENDER
        }
    }, {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [35.2, 31.780117]
        },
        "properties": {
            "GPSId": "6",
            "DateStart": "2015-06-23",
            "DateClosed": "2016-01-23",
            "GPSUserName": "fake1",
            "GPSUserColor": "#00FF57",
            "Gender": "Female",
            "Active": 0,
            "Colour": "#808080" //THIS IS ADDED BASED ON ACTIVITY LEVEL AND GENDER
        }
    }, {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [35.201715, 31.779548]
        },
        "properties": {
            "GPSId": "15",
            "DateStart": "2015-02-21",
            "DateClosed": "2016-02-28",
            "GPSUserName": "fake10",
            "GPSUserColor": "#00FF57",
            "Gender": "Male",
            "Active": 1,
            "Colour": "#0000FF" //THIS IS ADDED BASED ON ACTIVITY LEVEL AND GENDER
        }
    }, {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [35.200987, 31.779606]
        },
        "properties": {
            "GPSId": "16",
            "DateStart": "2015-01-01",
            "DateClosed": "2016-01-01",
            "GPSUserName": "fake11",
            "GPSUserColor": "#00FF57",
            "Gender": "Female",
            "Active": 0,
            "Colour": "#808080" //THIS IS ADDED BASED ON ACTIVITY LEVEL AND GENDER
        }
    }, {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [35.200987, 31.780522]
        },
        "properties": {
            "GPSId": "17",
            "DateStart": "2015-02-04",
            "DateClosed": "2016-09-21",
            "GPSUserName": "fake12",
            "GPSUserColor": "#00FF57",
            "Gender": "Male",
            "Active": 1,
            "Colour": "#0000FF" //THIS IS ADDED BASED ON ACTIVITY LEVEL AND GENDER
        }
    }

then I could omit the conditional statements in circles.js, which would result in:

var map = L.map( 'map', {
    center: [31.780117, 35.2],
    zoom: 17,
    minZoom: 2,
    maxZoom: 20
});

L.tileLayer('http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright" title="OpenStreetMap" target="_blank">OpenStreetMap</a> contributors | Tiles Courtesy of <a href="http://www.mapquest.com/" title="MapQuest" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png" width="16" height="16">',
    subdomains: ['otile1','otile2','otile3','otile4']
}).addTo(map);

// This will produce a static black circle
var circle2 = L.circle([31.7805, 35.203], 8, {
    color: "#000000",
    stroke: true,
    fillColor: "#000000",
    weight: 2,
    fillOpacity: 0.7
}).addTo(map);

///////////////////////////////////////////////////////////////////////////////
//Aesthetics                                                                 //
///////////////////////////////////////////////////////////////////////////////

var markerDefault = {
    radius: 8,
    weight: 2,
    opacity: 1,
    fillOpacity: 0.5
};

var markerHighlight = {
    radius: 10,
    weight: 3,
    opacity: 1,
    fillOpacity: 0.75
};

///////////////////////////////////////////////////////////////////////////////
//functions to attach styles and popups to the marker layer                  //
///////////////////////////////////////////////////////////////////////////////

function highlightDot(e) {
    var layer = e.target;
    layer.setStyle(markerHighlight);
};

function resetDotHighlight(e) {
    var layer = e.target;
    layer.setStyle(markerDefault);
};

function onEachDot(feature, layer) {
    layer.on({
        mouseover: highlightDot,
        mouseout: resetDotHighlight
    });
    layer.bindPopup('<table style="width:150px"><tbody><tr><td><div><b>name:</b></div></td><td><div>' + feature.properties.GPSId + '</div></td></tr><tr class><td><div><b>year:</b></div></td><td><div>' + feature.properties.DateStart + '</div></td></tr></tbody></table>');
};

///////////////////////////////////////////////////////////////////////////
//displaying the data on the map                                         //
///////////////////////////////////////////////////////////////////////////

dotlayer = L.geoJson(circles, {
    style: function(feature) {
        return {color: feature.properties.Colour};
    },
    pointToLayer: function(feature, latlng) {
        return new L.CircleMarker(latlng, markerDefault);
    },
    onEachFeature: onEachDot
}).addTo(map);

// init a map scale
L.control.scale().addTo(map);

It would still be nice to find a solution without modifying the .geojson file

Upvotes: 1

Related Questions