Filtering Leaflet data with jQRangeSlider

Here, a jQRangeSlider is used to filter GeoJSON data dynamically based on a numerical property (year). The GeoJSON data are created with a quasi-normal spatial distribution, filtered, then displayed as circle markers on a Leaflet map. Because the data are filtered and re-displayed every time the slider is moved, performance is rather slow. This can be alleviated by replacing "valuesChanging" with "valuesChanged" in the slider filter binding (line 214).

by Alex Azuero

HTML

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css">
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
<link rel="stylesheet" href="http://ghusse.github.io/jQRangeSlider/stable/css/classic.css">
<script src="https://biojs.googlecode.com/svn-history/r546/trunk/src/main/resources/dependencies/jquery/jQRangeSlider-5.1/jQRangeSlider-withRuler-min.js"></script>
<div id="map"></div>

CSS

html, body, #map {
    height: 100%;
    width:100%;
    padding:0px;
    margin:0px;
    font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
    color: #333;
}
.sliderContainer {
    padding: 15px;
}
/*overriding some of the slider defaults from classic.css*/
 .ui-rangeSlider .ui-rangeSlider-innerBar {
    background:#BBB;
}
.ui-rangeSlider .ui-rangeSlider-bar {
    background:rgba(32, 160, 255, 0.25);
}
/*adding styles for ruler ticks*/
 .ui-rangeSlider .ui-ruler-scale {
    position:absolute;
    top:0;
    left:0;
    bottom:0;
    right:0;
}
.ui-rangeSlider .ui-ruler-tick {
    float: left;
}
.ui-rangeSlider .ui-ruler-scale0 .ui-ruler-tick-inner {
    color: white;
    margin-top:1px;
    border-left: 1px solid white;
    height:22px;
    bottom: 4px;
    padding-left:2px;
    position:relative;
}
.ui-rangeSlider .ui-ruler-scale0 .ui-ruler-tick-label {
    position:absolute;
    bottom: 1px;
}
.ui-rangeSlider .ui-ruler-scale1 .ui-ruler-tick-inner {
    border-left:1px solid white;
    margin-top: 13px;
    height: 3px;
}

JavaScript

/////////////////////////////////////////////////////////////////////////////////////////////
//Here, a jQRangeSlider is used to filter GeoJSON data dynamically based on a numerical 
//property (year). The GeoJSON data are created with a quasi-normal spatial distribution, 
//filtered, then displayed as circle markers on a Leaflet map. 
/////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////
//setting up the map//
/////////////////////////////////////////////////////////////////////////////////////////////

// set center coordinates
var centerlat = 34.05;
var centerlon = -118.25;

// set default zoom level
var zoomLevel = 10;

// initialize map
var map = L.map('map').setView([centerlat, centerlon], zoomLevel);

// set source for map tiles
ATTR = '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a> | ' +
'&copy; <a href="http://cartodb.com/attributions">CartoDB</a>';

CDB_URL = 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png';

// add tiles to map
L.tileLayer(CDB_URL, {attribution: ATTR}).addTo(map);

/////////////////////////////////////////////////////////////////////////////////////////////
//creating some synthetic GeoJSON data//
/////////////////////////////////////////////////////////////////////////////////////////////

//initialize
var dotlayer;
var dots;
var dotcount = 200;

//cheapo normrand function
function normish(mean, range) {
    var num_out = ((Math.random() + Math.random() + Math.random() + Math.random() - 2) / 2) * range + mean;
    return num_out;
}

//create geojson data with random ~normal distribution
function make_dots() {

    dots = {
        type: "FeatureCollection",
        features: []
    };

    for (var i = 0; i < dotcount; ++i) {

        //set up random variables
        x = normish(0, 3);
   ...