// This is a Chiasm component that implements a bubble map. // Based on chiasm-leaflet. function BubbleMap() { // Extend chiasm-leaflet using composition (not inheritence). var my = ChiasmLeaflet(); // my.map is the Leaflet instance. // TODO move this into chiasm-component. my.addPublicProperties = function (publicProperties){ Object.keys(publicProperties).forEach(function (property){ my.addPublicProperty(property, publicProperties[property]); }); }; my.addPublicProperties({ // This is the data column that maps to bubble size. // "r" stands for radius. rColumn: Model.None, // The circle radius used if rColumn is not specified. rDefault: 3, // The range of the radius scale if rColumn is specified. rMin: 0, rMax: 10, }); var rScale = d3.scale.sqrt(); // Add a semi-transparent white layer to fade the // black & white base map to the background. var canvasTiles = L.tileLayer.canvas(); canvasTiles.drawTile = function(canvas, tilePoint, zoom) { var ctx = canvas.getContext('2d'); ctx.fillStyle = "rgba(255, 255, 250, 0.8)"; ctx.fillRect(0, 0, canvas.width, canvas.height); } canvasTiles.addTo(my.map); // Generate a function or constant for circle radius, // depending on whether or not rColumn is defined. my.when(["data", "rColumn", "rDefault", "rMin", "rMax"], function (data, rColumn, rDefault, rMin, rMax){ if(rColumn === Model.None){ my.r = function (){ return rDefault}; } else { rScale .domain(d3.extent(data, function (d){ return d[rColumn]; })) .range([rMin, rMax]); my.r = function (d){ return rScale(d[rColumn]); }; } }); my.when(["data", "r"], function (data, r){ // TODO remove old markers. // TODO move these to config. var latitudeColumn = "latitude"; var longitudeColumn = "longitude"; data.forEach(function (d){ var lat = d[latitudeColumn]; var lng = d[longitudeColumn]; var markerCenter = L.latLng(lat, lng); var circleMarker = L.circleMarker(markerCenter, { // TODO move this to config. color: "#FF4136", weight: 1, clickable: false }); circleMarker.setRadius(r(d)); circleMarker.addTo(my.map); }); }); return my; }