Filtering Leaflet data with a slider

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 257).

by msjade

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>
<br />
<br />
<div class="sliderContainer">
  <div id="dotSlider"></div>
</div>

CSS

html,
body,
#map {
  height: calc(100% - 30px);
  width: 100%;
  padding: 0px;
  margin: 0px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  color: #333;
}

.sliderContainer {
  margin: 0 50px;
}

.dotLegend {
  border-radius: 50%;
  width: 10px;
  height: 10px;
  display: inline-block;
  behavior: url(PIE.htc);
  /* remove if you don't care about IE8 */
}

.dotColor {
  background: #20a0ff;
}

.gdotColor {
  background: #40b060;
}

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.1;
var centerlon = -118.3;

// set default zoom level
var zoomLevel = 11;

// 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);

var geocodeControl = new L.Control.GeoSearch({
  provider: new L.GeoSearch.Provider.OpenStreetMap()
}).addTo(map);

//////////////////////////////////////////////////////////////////////////////////////////////
//creating the data//
//////////////////////////////////////////////////////////////////////////////////////////////

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

var gdotlayer;
var gdots;
var gdotcount = 75;

//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:...