From d96c0e64f995e7e103217842284cf0d502aa961f Mon Sep 17 00:00:00 2001 From: Scott Haskell Date: Wed, 6 Jun 2018 16:48:12 -0700 Subject: [PATCH] using modified HeatLayer.js and simpleheat from npm due to this bug - https://github.com/Leaflet/Leaflet.heat/pull/78 --- .../maps-plus/contrib/HeatLayer.js | 200 ++++++++++++++++++ .../visualizations/maps-plus/package.json | 2 +- .../visualizations/maps-plus/src/maps-plus.js | 2 +- .../visualizations/maps-plus/visualization.js | 200 +++++++++++++++--- .../maps-plus/webpack.config.js | 4 + 5 files changed, 374 insertions(+), 34 deletions(-) create mode 100644 appserver/static/visualizations/maps-plus/contrib/HeatLayer.js diff --git a/appserver/static/visualizations/maps-plus/contrib/HeatLayer.js b/appserver/static/visualizations/maps-plus/contrib/HeatLayer.js new file mode 100644 index 0000000..364bf96 --- /dev/null +++ b/appserver/static/visualizations/maps-plus/contrib/HeatLayer.js @@ -0,0 +1,200 @@ +'use strict'; + +L.HeatLayer = (L.Layer ? L.Layer : L.Class).extend({ + + // options: { + // minOpacity: 0.05, + // maxZoom: 18, + // radius: 25, + // blur: 15, + // max: 1.0 + // }, + + initialize: function (latlngs, options) { + this._latlngs = latlngs; + L.setOptions(this, options); + }, + + setLatLngs: function (latlngs) { + this._latlngs = latlngs; + return this.redraw(); + }, + + addLatLng: function (latlng) { + this._latlngs.push(latlng); + return this.redraw(); + }, + + setOptions: function (options) { + L.setOptions(this, options); + if (this._heat) { + this._updateOptions(); + } + return this.redraw(); + }, + + redraw: function () { + if (this._heat && !this._frame && !this._map._animating) { + this._frame = L.Util.requestAnimFrame(this._redraw, this); + } + return this; + }, + + onAdd: function (map) { + this._map = map; + + if (!this._canvas) { + this._initCanvas(); + } + + map._panes.overlayPane.appendChild(this._canvas); + + map.on('moveend', this._reset, this); + + if (map.options.zoomAnimation && L.Browser.any3d) { + map.on('zoomanim', this._animateZoom, this); + } + + this._reset(); + }, + + onRemove: function (map) { + map.getPanes().overlayPane.removeChild(this._canvas); + + map.off('moveend', this._reset, this); + + if (map.options.zoomAnimation) { + map.off('zoomanim', this._animateZoom, this); + } + }, + + addTo: function (map) { + map.addLayer(this); + return this; + }, + + _initCanvas: function () { + var canvas = this._canvas = L.DomUtil.create('canvas', 'leaflet-heatmap-layer leaflet-layer'); + + var originProp = L.DomUtil.testProp(['transformOrigin', 'WebkitTransformOrigin', 'msTransformOrigin']); + canvas.style[originProp] = '50% 50%'; + + var size = this._map.getSize(); + canvas.width = size.x; + canvas.height = size.y; + + var animated = this._map.options.zoomAnimation && L.Browser.any3d; + L.DomUtil.addClass(canvas, 'leaflet-zoom-' + (animated ? 'animated' : 'hide')); + + this._heat = simpleheat(canvas); + this._updateOptions(); + }, + + _updateOptions: function () { + this._heat.radius(this.options.radius || this._heat.defaultRadius, this.options.blur); + + if (this.options.gradient) { + this._heat.gradient(this.options.gradient); + } + this._max = 1; + }, + + _reset: function () { + var topLeft = this._map.containerPointToLayerPoint([0, 0]); + L.DomUtil.setPosition(this._canvas, topLeft); + + var size = this._map.getSize(); + + if (this._heat._width !== size.x) { + this._canvas.width = this._heat._width = size.x; + } + if (this._heat._height !== size.y) { + this._canvas.height = this._heat._height = size.y; + } + + this._redraw(); + }, + + _redraw: function () { + var data = [], + r = this._heat._r, + size = this._map.getSize(), + bounds = new L.Bounds( + L.point([-r, -r]), + size.add([r, r])), + + max = this.options.max === undefined ? 1 : this.options.max, + maxZoom = this.options.maxZoom === undefined ? this._map.getMaxZoom() : this.options.maxZoom, + v = 1 / Math.pow(2, Math.max(0, Math.min(maxZoom - this._map.getZoom(), 12))), + cellSize = r / 2, + grid = [], + panePos = this._map._getMapPanePos(), + offsetX = panePos.x % cellSize, + offsetY = panePos.y % cellSize, + i, len, p, cell, x, y, j, len2, k; + + // console.time('process'); + for (i = 0, len = this._latlngs.length; i < len; i++) { + p = this._map.latLngToContainerPoint(this._latlngs[i]); + if (bounds.contains(p)) { + x = Math.floor((p.x - offsetX) / cellSize) + 2; + y = Math.floor((p.y - offsetY) / cellSize) + 2; + + var alt = + this._latlngs[i].alt !== undefined ? this._latlngs[i].alt : + this._latlngs[i][2] !== undefined ? +this._latlngs[i][2] : 1; + k = alt; + + grid[y] = grid[y] || []; + cell = grid[y][x]; + + if (!cell) { + grid[y][x] = [p.x, p.y, k]; + + } else { + cell[0] = (cell[0] * cell[2] + p.x * k) / (cell[2] + k); // x + cell[1] = (cell[1] * cell[2] + p.y * k) / (cell[2] + k); // y + cell[2] += k; // cumulated intensity value + } + } + } + + for (i = 0, len = grid.length; i < len; i++) { + if (grid[i]) { + for (j = 0, len2 = grid[i].length; j < len2; j++) { + cell = grid[i][j]; + if (cell) { + data.push([ + Math.round(cell[0]), + Math.round(cell[1]), + Math.min(cell[2], max) + ]); + } + } + } + } + // console.timeEnd('process'); + + // console.time('draw ' + data.length); + this._heat.data(data).draw(this.options.minOpacity); + // console.timeEnd('draw ' + data.length); + + this._frame = null; + }, + + _animateZoom: function (e) { + var scale = this._map.getZoomScale(e.zoom), + offset = this._map._getCenterOffset(e.center)._multiplyBy(-scale).subtract(this._map._getMapPanePos()); + + if (L.DomUtil.setTransform) { + L.DomUtil.setTransform(this._canvas, offset, scale); + + } else { + this._canvas.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(offset) + ' scale(' + scale + ')'; + } + } +}); + +L.heatLayer = function (latlngs, options) { + return new L.HeatLayer(latlngs, options); +}; \ No newline at end of file diff --git a/appserver/static/visualizations/maps-plus/package.json b/appserver/static/visualizations/maps-plus/package.json index 30ac3ef..4f3a59e 100644 --- a/appserver/static/visualizations/maps-plus/package.json +++ b/appserver/static/visualizations/maps-plus/package.json @@ -28,7 +28,7 @@ "leaflet-contextmenu": "^1.2.1", "leaflet-dialog": "^1.0.1", "leaflet-google-places-autocomplete": "^0.0.8", - "leaflet.heat":"^0.2.0", + "simpleheat": "^0.4.0", "load-google-maps-api": "^1.0.0", "leaflet-bing-layer": "^3.3.0", "leaflet.markercluster": "^1.3.0", diff --git a/appserver/static/visualizations/maps-plus/src/maps-plus.js b/appserver/static/visualizations/maps-plus/src/maps-plus.js index 50b2f84..7dd23d0 100644 --- a/appserver/static/visualizations/maps-plus/src/maps-plus.js +++ b/appserver/static/visualizations/maps-plus/src/maps-plus.js @@ -15,7 +15,7 @@ define([ 'leaflet-dialog', 'leaflet-google-places-autocomplete', 'leaflet.markercluster', - 'leaflet.heat', + 'simpleheat', '../contrib/leaflet.spin', '../contrib/leaflet.featuregroup.subgroup-src', '../contrib/leaflet-measure', diff --git a/appserver/static/visualizations/maps-plus/visualization.js b/appserver/static/visualizations/maps-plus/visualization.js index 5634cd0..1ddebee 100644 --- a/appserver/static/visualizations/maps-plus/visualization.js +++ b/appserver/static/visualizations/maps-plus/visualization.js @@ -45986,9 +45986,9 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( mom = createUTC([2000, 1]).day(i); if (strict && !this._fullWeekdaysParse[i]) { - this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i'); - this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i'); - this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i'); + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); } if (!this._weekdaysParse[i]) { regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); @@ -46791,7 +46791,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( function preprocessRFC2822(s) { // Remove comments and folding whitespace and replace multiple-spaces with a single space - return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').trim(); + return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); } function checkWeekday(weekdayStr, parsedInput, config) { @@ -48970,7 +48970,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( // Side effect imports - hooks.version = '2.22.1'; + hooks.version = '2.22.2'; setHookCallback(createLocal); @@ -50065,7 +50065,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( relativeTime : { future : '%s sonra', past : '%s əvvəl', - s : 'birneçə saniyyə', + s : 'birneçə saniyə', ss : '%d saniyə', m : 'bir dəqiqə', mm : '%d dəqiqə', @@ -50160,7 +50160,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( weekdays : { format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'), standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), - isFormat: /\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/ + isFormat: /\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/ }, weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), @@ -57391,7 +57391,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( calendar : { sameDay : '[ਅਜ] LT', nextDay : '[ਕਲ] LT', - nextWeek : 'dddd, LT', + nextWeek : '[ਅਗਲਾ] dddd, LT', lastDay : '[ਕਲ] LT', lastWeek : '[ਪਿਛਲੇ] dddd, LT', sameElse : 'L' @@ -61535,7 +61535,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( /* 246 */ /***/ (function(module, exports, __webpack_require__) { - var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(global, module) {// Underscore.js 1.9.0 + var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(global, module) {// Underscore.js 1.9.1 // http://underscorejs.org // (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. @@ -61597,7 +61597,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( } // Current version. - _.VERSION = '1.9.0'; + _.VERSION = '1.9.1'; // Internal function that returns an efficient (for current engines) version // of the passed-in callback, to be repeatedly applied in other Underscore @@ -61685,6 +61685,10 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( }; }; + var has = function(obj, path) { + return obj != null && hasOwnProperty.call(obj, path); + } + var deepGet = function(obj, path) { var length = path.length; for (var i = 0; i < length; i++) { @@ -61982,7 +61986,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( // Groups the object's values by a criterion. Pass either a string attribute // to group by, or a function that returns the criterion. _.groupBy = group(function(result, value, key) { - if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + if (has(result, key)) result[key].push(value); else result[key] = [value]; }); // Indexes the object's values by a criterion, similar to `groupBy`, but for @@ -61995,7 +61999,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( // either a string attribute to count by, or a function that returns the // criterion. _.countBy = group(function(result, value, key) { - if (_.has(result, key)) result[key]++; else result[key] = 1; + if (has(result, key)) result[key]++; else result[key] = 1; }); var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; @@ -62030,7 +62034,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( // values in the array. Aliased as `head` and `take`. The **guard** check // allows it to work with `_.map`. _.first = _.head = _.take = function(array, n, guard) { - if (array == null || array.length < 1) return void 0; + if (array == null || array.length < 1) return n == null ? void 0 : []; if (n == null || guard) return array[0]; return _.initial(array, array.length - n); }; @@ -62045,7 +62049,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( // Get the last element of an array. Passing **n** will return the last N // values in the array. _.last = function(array, n, guard) { - if (array == null || array.length < 1) return void 0; + if (array == null || array.length < 1) return n == null ? void 0 : []; if (n == null || guard) return array[array.length - 1]; return _.rest(array, Math.max(0, array.length - n)); }; @@ -62348,7 +62352,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( var memoize = function(key) { var cache = memoize.cache; var address = '' + (hasher ? hasher.apply(this, arguments) : key); - if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + if (!has(cache, address)) cache[address] = func.apply(this, arguments); return cache[address]; }; memoize.cache = {}; @@ -62515,7 +62519,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( // Constructor is a special case. var prop = 'constructor'; - if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + if (has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); while (nonEnumIdx--) { prop = nonEnumerableProps[nonEnumIdx]; @@ -62531,7 +62535,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( if (!_.isObject(obj)) return []; if (nativeKeys) return nativeKeys(obj); var keys = []; - for (var key in obj) if (_.has(obj, key)) keys.push(key); + for (var key in obj) if (has(obj, key)) keys.push(key); // Ahem, IE < 9. if (hasEnumBug) collectNonEnumProps(obj, keys); return keys; @@ -62816,7 +62820,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( while (length--) { // Deep compare each member key = keys[length]; - if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + if (!(has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; } } // Remove the first object from the stack of traversed objects. @@ -62866,7 +62870,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( // there isn't any inspectable "Arguments" type. if (!_.isArguments(arguments)) { _.isArguments = function(obj) { - return _.has(obj, 'callee'); + return has(obj, 'callee'); }; } @@ -62908,7 +62912,7 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( // on itself (in other words, not on a prototype). _.has = function(obj, path) { if (!_.isArray(path)) { - return obj != null && hasOwnProperty.call(obj, path); + return has(obj, path); } var length = path.length; for (var i = 0; i < length; i++) { @@ -67023,19 +67027,151 @@ define(["api/SplunkVisualizationBase","api/SplunkVisualizationUtils"], function( /***/ }), /* 251 */ -/***/ (function(module, exports) { +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + if (true) module.exports = simpleheat; + + function simpleheat(canvas) { + if (!(this instanceof simpleheat)) return new simpleheat(canvas); + + this._canvas = canvas = typeof canvas === 'string' ? document.getElementById(canvas) : canvas; + + this._ctx = canvas.getContext('2d'); + this._width = canvas.width; + this._height = canvas.height; + + this._max = 1; + this._data = []; + } + + simpleheat.prototype = { + + defaultRadius: 25, + + defaultGradient: { + 0.4: 'blue', + 0.6: 'cyan', + 0.7: 'lime', + 0.8: 'yellow', + 1.0: 'red' + }, + + data: function (data) { + this._data = data; + return this; + }, + + max: function (max) { + this._max = max; + return this; + }, + + add: function (point) { + this._data.push(point); + return this; + }, + + clear: function () { + this._data = []; + return this; + }, + + radius: function (r, blur) { + blur = blur === undefined ? 15 : blur; + + // create a grayscale blurred circle image that we'll use for drawing points + var circle = this._circle = this._createCanvas(), + ctx = circle.getContext('2d'), + r2 = this._r = r + blur; + + circle.width = circle.height = r2 * 2; + + ctx.shadowOffsetX = ctx.shadowOffsetY = r2 * 2; + ctx.shadowBlur = blur; + ctx.shadowColor = 'black'; + + ctx.beginPath(); + ctx.arc(-r2, -r2, r, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fill(); + + return this; + }, + + resize: function () { + this._width = this._canvas.width; + this._height = this._canvas.height; + }, + + gradient: function (grad) { + // create a 256x1 gradient that we'll use to turn a grayscale heatmap into a colored one + var canvas = this._createCanvas(), + ctx = canvas.getContext('2d'), + gradient = ctx.createLinearGradient(0, 0, 0, 256); + + canvas.width = 1; + canvas.height = 256; + + for (var i in grad) { + gradient.addColorStop(+i, grad[i]); + } + + ctx.fillStyle = gradient; + ctx.fillRect(0, 0, 1, 256); + + this._grad = ctx.getImageData(0, 0, 1, 256).data; + + return this; + }, + + draw: function (minOpacity) { + if (!this._circle) this.radius(this.defaultRadius); + if (!this._grad) this.gradient(this.defaultGradient); + + var ctx = this._ctx; + + ctx.clearRect(0, 0, this._width, this._height); + + // draw a grayscale heatmap by putting a blurred circle at each data point + for (var i = 0, len = this._data.length, p; i < len; i++) { + p = this._data[i]; + ctx.globalAlpha = Math.max(p[2] / this._max, minOpacity === undefined ? 0.05 : minOpacity); + ctx.drawImage(this._circle, p[0] - this._r, p[1] - this._r); + } + + // colorize the heatmap, using opacity value of each pixel to get the right color from our gradient + var colored = ctx.getImageData(0, 0, this._width, this._height); + this._colorize(colored.data, this._grad); + ctx.putImageData(colored, 0, 0); + + return this; + }, + + _colorize: function (pixels, gradient) { + for (var i = 0, len = pixels.length, j; i < len; i += 4) { + j = pixels[i + 3] * 4; // get gradient color from opacity value + + if (j) { + pixels[i] = gradient[j]; + pixels[i + 1] = gradient[j + 1]; + pixels[i + 2] = gradient[j + 2]; + } + } + }, + + _createCanvas: function () { + if (typeof document !== 'undefined') { + return document.createElement('canvas'); + } else { + // create a new canvas instance in node.js + // the canvas class needs to have a default constructor without any parameter + return new this._canvas.constructor(); + } + } + }; - /* - (c) 2014, Vladimir Agafonkin - simpleheat, a tiny JavaScript library for drawing heatmaps with Canvas - https://github.com/mourner/simpleheat - */ - !function(){"use strict";function t(i){return this instanceof t?(this._canvas=i="string"==typeof i?document.getElementById(i):i,this._ctx=i.getContext("2d"),this._width=i.width,this._height=i.height,this._max=1,void this.clear()):new t(i)}t.prototype={defaultRadius:25,defaultGradient:{.4:"blue",.6:"cyan",.7:"lime",.8:"yellow",1:"red"},data:function(t,i){return this._data=t,this},max:function(t){return this._max=t,this},add:function(t){return this._data.push(t),this},clear:function(){return this._data=[],this},radius:function(t,i){i=i||15;var a=this._circle=document.createElement("canvas"),s=a.getContext("2d"),e=this._r=t+i;return a.width=a.height=2*e,s.shadowOffsetX=s.shadowOffsetY=200,s.shadowBlur=i,s.shadowColor="black",s.beginPath(),s.arc(e-200,e-200,t,0,2*Math.PI,!0),s.closePath(),s.fill(),this},gradient:function(t){var i=document.createElement("canvas"),a=i.getContext("2d"),s=a.createLinearGradient(0,0,0,256);i.width=1,i.height=256;for(var e in t)s.addColorStop(e,t[e]);return a.fillStyle=s,a.fillRect(0,0,1,256),this._grad=a.getImageData(0,0,1,256).data,this},draw:function(t){this._circle||this.radius(this.defaultRadius),this._grad||this.gradient(this.defaultGradient);var i=this._ctx;i.clearRect(0,0,this._width,this._height);for(var a,s=0,e=this._data.length;e>s;s++)a=this._data[s],i.globalAlpha=Math.max(a[2]/this._max,t||.05),i.drawImage(this._circle,a[0]-this._r,a[1]-this._r);var n=i.getImageData(0,0,this._width,this._height);return this._colorize(n.data,this._grad),i.putImageData(n,0,0),this},_colorize:function(t,i){for(var a,s=3,e=t.length;e>s;s+=4)a=4*t[s],a&&(t[s-3]=i[a],t[s-2]=i[a+1],t[s-1]=i[a+2])}},window.simpleheat=t}(),/* - (c) 2014, Vladimir Agafonkin - Leaflet.heat, a tiny and fast heatmap plugin for Leaflet. - https://github.com/Leaflet/Leaflet.heat - */ - L.HeatLayer=(L.Layer?L.Layer:L.Class).extend({initialize:function(t,i){this._latlngs=t,L.setOptions(this,i)},setLatLngs:function(t){return this._latlngs=t,this.redraw()},addLatLng:function(t){return this._latlngs.push(t),this.redraw()},setOptions:function(t){return L.setOptions(this,t),this._heat&&this._updateOptions(),this.redraw()},redraw:function(){return!this._heat||this._frame||this._map._animating||(this._frame=L.Util.requestAnimFrame(this._redraw,this)),this},onAdd:function(t){this._map=t,this._canvas||this._initCanvas(),t._panes.overlayPane.appendChild(this._canvas),t.on("moveend",this._reset,this),t.options.zoomAnimation&&L.Browser.any3d&&t.on("zoomanim",this._animateZoom,this),this._reset()},onRemove:function(t){t.getPanes().overlayPane.removeChild(this._canvas),t.off("moveend",this._reset,this),t.options.zoomAnimation&&t.off("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},_initCanvas:function(){var t=this._canvas=L.DomUtil.create("canvas","leaflet-heatmap-layer leaflet-layer"),i=L.DomUtil.testProp(["transformOrigin","WebkitTransformOrigin","msTransformOrigin"]);t.style[i]="50% 50%";var a=this._map.getSize();t.width=a.x,t.height=a.y;var s=this._map.options.zoomAnimation&&L.Browser.any3d;L.DomUtil.addClass(t,"leaflet-zoom-"+(s?"animated":"hide")),this._heat=simpleheat(t),this._updateOptions()},_updateOptions:function(){this._heat.radius(this.options.radius||this._heat.defaultRadius,this.options.blur),this.options.gradient&&this._heat.gradient(this.options.gradient),this.options.max&&this._heat.max(this.options.max)},_reset:function(){var t=this._map.containerPointToLayerPoint([0,0]);L.DomUtil.setPosition(this._canvas,t);var i=this._map.getSize();this._heat._width!==i.x&&(this._canvas.width=this._heat._width=i.x),this._heat._height!==i.y&&(this._canvas.height=this._heat._height=i.y),this._redraw()},_redraw:function(){var t,i,a,s,e,n,h,o,r,d=[],_=this._heat._r,l=this._map.getSize(),m=new L.Bounds(L.point([-_,-_]),l.add([_,_])),c=void 0===this.options.max?1:this.options.max,u=void 0===this.options.maxZoom?this._map.getMaxZoom():this.options.maxZoom,f=1/Math.pow(2,Math.max(0,Math.min(u-this._map.getZoom(),12))),g=_/2,p=[],v=this._map._getMapPanePos(),w=v.x%g,y=v.y%g;for(t=0,i=this._latlngs.length;i>t;t++)if(a=this._map.latLngToContainerPoint(this._latlngs[t]),m.contains(a)){e=Math.floor((a.x-w)/g)+2,n=Math.floor((a.y-y)/g)+2;var x=void 0!==this._latlngs[t].alt?this._latlngs[t].alt:void 0!==this._latlngs[t][2]?+this._latlngs[t][2]:1;r=x*f,p[n]=p[n]||[],s=p[n][e],s?(s[0]=(s[0]*s[2]+a.x*r)/(s[2]+r),s[1]=(s[1]*s[2]+a.y*r)/(s[2]+r),s[2]+=r):p[n][e]=[a.x,a.y,r]}for(t=0,i=p.length;i>t;t++)if(p[t])for(h=0,o=p[t].length;o>h;h++)s=p[t][h],s&&d.push([Math.round(s[0]),Math.round(s[1]),Math.min(s[2],c)]);this._heat.data(d).draw(this.options.minOpacity),this._frame=null},_animateZoom:function(t){var i=this._map.getZoomScale(t.zoom),a=this._map._getCenterOffset(t.center)._multiplyBy(-i).subtract(this._map._getMapPanePos());L.DomUtil.setTransform?L.DomUtil.setTransform(this._canvas,a,i):this._canvas.style[L.DomUtil.TRANSFORM]=L.DomUtil.getTranslateString(a)+" scale("+i+")"}}),L.heatLayer=function(t,i){return new L.HeatLayer(t,i)}; /***/ }), /* 252 */ diff --git a/appserver/static/visualizations/maps-plus/webpack.config.js b/appserver/static/visualizations/maps-plus/webpack.config.js index 8449d53..2d2f237 100644 --- a/appserver/static/visualizations/maps-plus/webpack.config.js +++ b/appserver/static/visualizations/maps-plus/webpack.config.js @@ -18,6 +18,10 @@ module.exports = { test: /leaflet\.spin\.js$/, loader: 'imports-loader?L=leaflet' }, + { + test: /HeatLayer\.js$/, + loaders: ['imports-loader?L=leaflet', 'imports-loader?simpleheat'] + }, { test: /leaflet\.awesome-markers\.js$/, loader: 'imports-loader?L=leaflet'