// rivet var filter = {city:'London', country:null, mode:'qmprice'}; filter['countries'] = Array.from(new Set(data.features.map(function(d){return d['properties']['country']}))); rivets.bind(document.getElementById('overlay'), {filter: filter}); function clone(d){ return JSON.parse(JSON.stringify(d)); } function percentile(arr, p) { if (arr.length === 0) return 0; if (typeof p !== 'number') throw new TypeError('p must be a number'); if (p <= 0) return arr[0]; if (p >= 1) return arr[arr.length - 1]; var index = arr.length * p, lower = Math.floor(index), upper = lower + 1, weight = index % 1; if (upper >= arr.length) return arr[lower]; return arr[lower] * (1 - weight) + arr[upper] * weight; } function update(){ // close overlay var modal = document.getElementById('modal_overlay'); modal.classList.toggle('modal-open'); // init heatmap heatmap = new HexgridHeatmap(map, "hexgrid-heatmap", "waterway-label"); heatmap.setIntensity(6); // dunno yet heatmap.setSpread(0.15); // dunno yet heatmap.setCellDensity(0.5); // small value == bigger hexagons heatmap.setPropertyName(filter.mode); // set filter if(filter.city){ cityDim.filterExact(filter.city); } else if(filter.country){ countryDim.filterExact(filter.country); }else{ alert('nothing loadable'); } filter.count = cityDim.top(Infinity).length; var subset = {"type": "FeatureCollection", "features": []}; indexDim.top(Infinity).forEach(function(i){ subset.features.push(data.features[i.index]); }); loadData(subset); } function loadData(subset){ heatmap.setData(subset); var values = subset.features.map(function(d){return d['properties'][filter.mode]}); values = values.sort(function(a,b){return a-b;}); // setting the color stops, min is at 5th percentile, max at 95percentile var min = values[Math.round(values.length * 0.05)]; var max = values[Math.round(values.length * 0.95)]; var colorStopsPerc = [ [0, "rgba(0,185,243,0)"], [25, "rgba(0,185,243,0.24)"], [60, "rgba(255,223,0,0.3)"], [100, "rgba(255,105,0,0.3)"], ]; makeLegend(colorStopsPerc, min, max); var colorStopsValue = colorStopsPerc.map(function(d){ return [min + d[0]*(max-min)/100, d[1]]; }); heatmap.setColorStops(colorStopsValue); heatmap.update(); //get bounding box and zoom to that area // we use a 1% percentile since some data can be corrupt var longitudes = subset.features.map(function(d){return d.geometry.coordinates[0];}).sort(function(a,b){return a-b;}); var latitudes = subset.features.map(function(d){return d.geometry.coordinates[1];}).sort(function(a,b){return a-b;}); var minlng = percentile(longitudes, 0.01); var maxlng = percentile(longitudes, 0.99); var minlat = percentile(latitudes, 0.01); var maxlat = percentile(latitudes, 0.99); map.fitBounds([ [minlng, minlat], [maxlng, maxlat] ]); } mapboxgl.accessToken = 'pk.eyJ1IjoiZGktdG8iLCJhIjoiY2o0bnBoYXcxMW1mNzJ3bDhmc2xiNWttaiJ9.ZccatVk_4shzoAsEUXXecA'; var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/light-v9', center: [13.38032, 49.994210], zoom: 5 }); map.on("load", function(){ var crossData = data.features.map(function(d, i){ //clone properties var props = clone(d['properties']); props['index'] = i; return props; }); cf = crossfilter(crossData); qmDim = cf.dimension(function(d){return d.qm;}); cityDim = cf.dimension(function(d){return d.city;}); countryDim = cf.dimension(function(d){return d.country;}); rentDim = cf.dimension(function(d){return d.total_price;}); roomsDim = cf.dimension(function(d){return d.rooms;}); indexDim = cf.dimension(function(d){return d.index;}); }); // map.addInteraction('my-polygon-click-interaction', { // type: 'click', // target: 'polygons', // handler: (e) => { // console.log('Polygon clicked:', e.feature); // map.setFeatureState(e.feature, {highlight: true}); // } // }); function makeLegend(colorstops, minValue, maxValue){ /** * colorstops: [[0, 'green'], [100, 'red']] * @type {number} */ var svg_height = 300, svg_width=70; var svg = d3.select('#svg'); var defs = svg .attr('height', svg_height) .attr('width', svg_width); var linearGradient = svg.append("defs") .append("linearGradient") .attr("id", "linear-gradient"); linearGradient .attr("x1", "0%") .attr("y1", "100%") .attr("x2", "0%") .attr("y2", "0%"); svg.append("rect") .attr("width", svg_width*0.4) .attr("height", svg_height) .attr('rx', 4) .style("fill", "url(#linear-gradient)"); colorstops.forEach(function(d){ linearGradient.append("stop") .attr("offset", d[0] + "%") .attr("stop-color", d[1]); }); var xScale = d3.scaleLinear().range([svg_height-20,0]).domain([minValue,maxValue]); var xAxis = d3.axisRight(xScale).ticks(5); svg.append("g") .attr("class", "axis") .attr("transform", "translate("+svg_width/2+"," + (10) + ")") .call(xAxis); }