| New file |
| | |
| | | /* |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-05-06 20:24:41 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-05-06 21:15:24 |
| | | * @FilePath: \srs-police-affairs\src\utils\CesiumHeatmap.js |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | */ |
| | | /* eslint-disable no-undef */ |
| | | /* |
| | | * CesiumHeatmap.js v0.1 | global.DC.Namespace.Cesium Heatmap Library |
| | | * |
| | | * Works with heatmap.js v2.0.0: http://www.patrick-wied.at/static/heatmapjs/ |
| | | */ |
| | | (function (window) { |
| | | 'use strict' |
| | | |
| | | function define_CesiumHeatmap () { |
| | | var CesiumHeatmap = { |
| | | defaults: { |
| | | useEntitiesIfAvailable: true, //whether to use entities if a Viewer is supplied or always use an ImageryProvider |
| | | minCanvasSize: 700, // minimum size (in pixels) for the heatmap canvas |
| | | maxCanvasSize: 2000, // maximum size (in pixels) for the heatmap canvas |
| | | radiusFactor: 60, // data point size factor used if no radius is given (the greater of height and width divided by this number yields the used radius) |
| | | spacingFactor: 1.5, // extra space around the borders (point radius multiplied by this number yields the spacing) |
| | | maxOpacity: 0.8, // the maximum opacity used if not given in the heatmap options object |
| | | minOpacity: 0.1, // the minimum opacity used if not given in the heatmap options object |
| | | blur: 0.85, // the blur used if not given in the heatmap options object |
| | | gradient: { // the gradient used if not given in the heatmap options object |
| | | '0.9': 'red', |
| | | '0.8': 'orange', |
| | | '0.7': 'yellow', |
| | | '0.5': 'blue', |
| | | '0.3': 'green', |
| | | }, |
| | | } |
| | | } |
| | | |
| | | /* Create a CesiumHeatmap instance |
| | | * |
| | | * cesium: the CesiumWidget or Viewer instance |
| | | * bb: the WGS84 bounding box like {north, east, south, west} |
| | | * options: a heatmap.js options object (see http://www.patrick-wied.at/static/heatmapjs/docs.html#h337-create) |
| | | */ |
| | | CesiumHeatmap.create = function (cesium, bb, options) { |
| | | var instance = new CHInstance(cesium, bb, options) |
| | | return instance |
| | | } |
| | | |
| | | CesiumHeatmap._getContainer = function (width, height, id) { |
| | | var c = document.createElement("div") |
| | | if (id) { |
| | | c.setAttribute("id", id) |
| | | } |
| | | c.setAttribute("style", "width: " + width + "px; height: " + height + "px; margin: 0px; display: none;") |
| | | document.body.appendChild(c) |
| | | return c |
| | | } |
| | | |
| | | CesiumHeatmap._getImageryProvider = function (instance) { |
| | | //var n = (new Date()).getTime(); |
| | | var d = instance._heatmap.getDataURL() |
| | | //console.log("Create data URL: " + ((new Date()).getTime() - n)); |
| | | |
| | | //var n = (new Date()).getTime(); |
| | | var imgprov = new global.DC.Namespace.Cesium.SingleTileImageryProvider({ |
| | | url: d, |
| | | rectangle: instance._rectangle |
| | | }) |
| | | //console.log("Create imageryprovider: " + ((new Date()).getTime() - n)); |
| | | |
| | | imgprov._tilingScheme = new global.DC.Namespace.Cesium.WebMercatorTilingScheme({ |
| | | rectangleSouthwestInMeters: new global.DC.Namespace.Cesium.Cartesian2(instance._mbounds.west, instance._mbounds.south), |
| | | rectangleNortheastInMeters: new global.DC.Namespace.Cesium.Cartesian2(instance._mbounds.east, instance._mbounds.north) |
| | | }) |
| | | |
| | | return imgprov |
| | | } |
| | | |
| | | CesiumHeatmap._getID = function (len) { |
| | | var text = "" |
| | | var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" |
| | | |
| | | for (var i = 0; i < ((len) ? len : 8); i++) |
| | | text += possible.charAt(Math.floor(Math.random() * possible.length)) |
| | | |
| | | return text |
| | | } |
| | | |
| | | var WMP = new global.DC.Namespace.Cesium.WebMercatorProjection() |
| | | var Cesium = global.DC.Namespace.Cesium |
| | | |
| | | /* Convert a WGS84 location into a mercator location |
| | | * |
| | | * p: the WGS84 location like {x: lon, y: lat} |
| | | */ |
| | | CesiumHeatmap.wgs84ToMercator = function (p) { |
| | | var mp = WMP.project(Cesium.Cartographic.fromDegrees(p.x, p.y)) |
| | | return { |
| | | x: mp.x, |
| | | y: mp.y |
| | | } |
| | | } |
| | | |
| | | /* Convert a WGS84 bounding box into a mercator bounding box |
| | | * |
| | | * bb: the WGS84 bounding box like {north, east, south, west} |
| | | */ |
| | | CesiumHeatmap.wgs84ToMercatorBB = function (bb) { |
| | | var sw = WMP.project(Cesium.Cartographic.fromDegrees(bb.west, bb.south)) |
| | | var ne = WMP.project(Cesium.Cartographic.fromDegrees(bb.east, bb.north)) |
| | | return { |
| | | north: ne.y, |
| | | east: ne.x, |
| | | south: sw.y, |
| | | west: sw.x |
| | | } |
| | | } |
| | | |
| | | /* Convert a mercator location into a WGS84 location |
| | | * |
| | | * p: the mercator lcation like {x, y} |
| | | */ |
| | | CesiumHeatmap.mercatorToWgs84 = function (p) { |
| | | var wp = WMP.unproject(new Cesium.Cartesian3(p.x, p.y)) |
| | | return { |
| | | x: wp.longitude, |
| | | y: wp.latitude |
| | | } |
| | | } |
| | | |
| | | /* Convert a mercator bounding box into a WGS84 bounding box |
| | | * |
| | | * bb: the mercator bounding box like {north, east, south, west} |
| | | */ |
| | | CesiumHeatmap.mercatorToWgs84BB = function (bb) { |
| | | var sw = WMP.unproject(new Cesium.Cartesian3(bb.west, bb.south)) |
| | | var ne = WMP.unproject(new Cesium.Cartesian3(bb.east, bb.north)) |
| | | return { |
| | | north: this.rad2deg(ne.latitude), |
| | | east: this.rad2deg(ne.longitude), |
| | | south: this.rad2deg(sw.latitude), |
| | | west: this.rad2deg(sw.longitude) |
| | | } |
| | | } |
| | | |
| | | /* Convert degrees into radians |
| | | * |
| | | * d: the degrees to be converted to radians |
| | | */ |
| | | CesiumHeatmap.deg2rad = function (d) { |
| | | var r = d * (Math.PI / 180.0) |
| | | return r |
| | | } |
| | | |
| | | /* Convert radians into degrees |
| | | * |
| | | * r: the radians to be converted to degrees |
| | | */ |
| | | CesiumHeatmap.rad2deg = function (r) { |
| | | var d = r / (Math.PI / 180.0) |
| | | return d |
| | | } |
| | | |
| | | return CesiumHeatmap |
| | | } |
| | | |
| | | if (typeof (CesiumHeatmap) === 'undefined') { |
| | | window.CesiumHeatmap = define_CesiumHeatmap(global.DC.Namespace.Cesium) |
| | | } else { |
| | | console.log("CesiumHeatmap already defined.") |
| | | } |
| | | })(window) |
| | | |
| | | /* Initiate a CesiumHeatmap instance |
| | | * |
| | | * c: CesiumWidget instance |
| | | * bb: a WGS84 bounding box like {north, east, south, west} |
| | | * o: a heatmap.js options object (see http://www.patrick-wied.at/static/heatmapjs/docs.html#h337-create) |
| | | */ |
| | | function CHInstance (c, bb, o) { |
| | | if (!bb) { |
| | | return null |
| | | } |
| | | if (!o) { |
| | | o = {} |
| | | } |
| | | |
| | | this._cesium = c |
| | | this._options = o |
| | | this._id = CesiumHeatmap._getID() |
| | | |
| | | this._options.gradient = ((this._options.gradient) ? this._options.gradient : CesiumHeatmap.defaults.gradient) |
| | | this._options.maxOpacity = ((this._options.maxOpacity) ? this._options.maxOpacity : CesiumHeatmap.defaults.maxOpacity) |
| | | this._options.minOpacity = ((this._options.minOpacity) ? this._options.minOpacity : CesiumHeatmap.defaults.minOpacity) |
| | | this._options.blur = ((this._options.blur) ? this._options.blur : CesiumHeatmap.defaults.blur) |
| | | |
| | | this._mbounds = CesiumHeatmap.wgs84ToMercatorBB(bb) |
| | | this._setWidthAndHeight(this._mbounds) |
| | | |
| | | this._options.radius = Math.round((this._options.radius) ? this._options.radius : ((this.width > this.height) ? this.width / CesiumHeatmap.defaults.radiusFactor : this.height / CesiumHeatmap.defaults.radiusFactor)) |
| | | |
| | | this._spacing = this._options.radius * CesiumHeatmap.defaults.spacingFactor |
| | | this._xoffset = this._mbounds.west |
| | | this._yoffset = this._mbounds.south |
| | | |
| | | this.width = Math.round(this.width + this._spacing * 2) |
| | | this.height = Math.round(this.height + this._spacing * 2) |
| | | |
| | | this._mbounds.west -= this._spacing * this._factor |
| | | this._mbounds.east += this._spacing * this._factor |
| | | this._mbounds.south -= this._spacing * this._factor |
| | | this._mbounds.north += this._spacing * this._factor |
| | | |
| | | this.bounds = CesiumHeatmap.mercatorToWgs84BB(this._mbounds) |
| | | |
| | | this._rectangle = global.DC.Namespace.Cesium.Rectangle.fromDegrees(this.bounds.west, this.bounds.south, this.bounds.east, this.bounds.north) |
| | | this._container = CesiumHeatmap._getContainer(this.width, this.height, this._id) |
| | | this._options.container = this._container |
| | | this._heatmap = window.h337.create(this._options) |
| | | this._container.children[0].setAttribute("id", this._id + "-hm") |
| | | } |
| | | |
| | | /* Convert a WGS84 location to the corresponding heatmap location |
| | | * |
| | | * p: a WGS84 location like {x:lon, y:lat} |
| | | */ |
| | | CHInstance.prototype.wgs84PointToHeatmapPoint = function (p) { |
| | | return this.mercatorPointToHeatmapPoint(CesiumHeatmap.wgs84ToMercator(p)) |
| | | } |
| | | |
| | | /* Convert a mercator location to the corresponding heatmap location |
| | | * |
| | | * p: a WGS84 location like {x: lon, y:lat} |
| | | */ |
| | | CHInstance.prototype.mercatorPointToHeatmapPoint = function (p) { |
| | | var pn = {} |
| | | |
| | | pn.x = Math.round((p.x - this._xoffset) / this._factor + this._spacing) |
| | | pn.y = Math.round((p.y - this._yoffset) / this._factor + this._spacing) |
| | | pn.y = this.height - pn.y |
| | | |
| | | return pn |
| | | } |
| | | |
| | | CHInstance.prototype._setWidthAndHeight = function (mbb) { |
| | | this.width = ((mbb.east > 0 && mbb.west < 0) ? mbb.east + Math.abs(mbb.west) : Math.abs(mbb.east - mbb.west)) |
| | | this.height = ((mbb.north > 0 && mbb.south < 0) ? mbb.north + Math.abs(mbb.south) : Math.abs(mbb.north - mbb.south)) |
| | | this._factor = 1 |
| | | |
| | | if (this.width > this.height && this.width > CesiumHeatmap.defaults.maxCanvasSize) { |
| | | this._factor = this.width / CesiumHeatmap.defaults.maxCanvasSize |
| | | |
| | | if (this.height / this._factor < CesiumHeatmap.defaults.minCanvasSize) { |
| | | this._factor = this.height / CesiumHeatmap.defaults.minCanvasSize |
| | | } |
| | | } else if (this.height > this.width && this.height > CesiumHeatmap.defaults.maxCanvasSize) { |
| | | this._factor = this.height / CesiumHeatmap.defaults.maxCanvasSize |
| | | |
| | | if (this.width / this._factor < CesiumHeatmap.defaults.minCanvasSize) { |
| | | this._factor = this.width / CesiumHeatmap.defaults.minCanvasSize |
| | | } |
| | | } else if (this.width < this.height && this.width < CesiumHeatmap.defaults.minCanvasSize) { |
| | | this._factor = this.width / CesiumHeatmap.defaults.minCanvasSize |
| | | |
| | | if (this.height / this._factor > CesiumHeatmap.defaults.maxCanvasSize) { |
| | | this._factor = this.height / CesiumHeatmap.defaults.maxCanvasSize |
| | | } |
| | | } else if (this.height < this.width && this.height < CesiumHeatmap.defaults.minCanvasSize) { |
| | | this._factor = this.height / CesiumHeatmap.defaults.minCanvasSize |
| | | |
| | | if (this.width / this._factor > CesiumHeatmap.defaults.maxCanvasSize) { |
| | | this._factor = this.width / CesiumHeatmap.defaults.maxCanvasSize |
| | | } |
| | | } |
| | | |
| | | this.width = this.width / this._factor |
| | | this.height = this.height / this._factor |
| | | } |
| | | |
| | | /* Set an array of heatmap locations |
| | | * |
| | | * min: the minimum allowed value for the data values |
| | | * max: the maximum allowed value for the data values |
| | | * data: an array of data points in heatmap coordinates and values like {x, y, value} |
| | | */ |
| | | CHInstance.prototype.setData = function (min, max, data) { |
| | | if (data && data.length > 0 && min !== null && min !== false && max !== null && max !== false) { |
| | | this._heatmap.setData({ |
| | | min: min, |
| | | max: max, |
| | | data: data |
| | | }) |
| | | |
| | | this.updateLayer() |
| | | return true |
| | | } |
| | | |
| | | return false |
| | | } |
| | | |
| | | /* Set an array of WGS84 locations |
| | | * |
| | | * min: the minimum allowed value for the data values |
| | | * max: the maximum allowed value for the data values |
| | | * data: an array of data points in WGS84 coordinates and values like { x:lon, y:lat, value } |
| | | */ |
| | | CHInstance.prototype.setWGS84Data = function (min, max, data) { |
| | | if (data && data.length > 0 && min !== null && min !== false && max !== null && max !== false) { |
| | | var convdata = [] |
| | | |
| | | for (var i = 0; i < data.length; i++) { |
| | | var gp = data[i] |
| | | |
| | | var hp = this.wgs84PointToHeatmapPoint(gp) |
| | | if (gp.value || gp.value === 0) { |
| | | hp.value = gp.value |
| | | } |
| | | |
| | | convdata.push(hp) |
| | | } |
| | | |
| | | return this.setData(min, max, convdata) |
| | | } |
| | | |
| | | return false |
| | | } |
| | | |
| | | /* Set whether or not the heatmap is shown on the map |
| | | * |
| | | * s: true means the heatmap is shown, false means the heatmap is hidden |
| | | */ |
| | | CHInstance.prototype.show = function (s) { |
| | | if (this._layer) { |
| | | this._layer.show = s |
| | | } |
| | | } |
| | | |
| | | /* Update/(re)draw the heatmap |
| | | */ |
| | | CHInstance.prototype.updateLayer = function () { |
| | | |
| | | // only works with a Viewer instance since the cesiumWidget |
| | | // instance doesn't contain an entities property |
| | | if (CesiumHeatmap.defaults.useEntitiesIfAvailable && this._cesium.entities) { |
| | | if (this._layer) { |
| | | this._cesium.entities.remove(this._layer) |
| | | } |
| | | |
| | | // Work around issue with material rendering in global.DC.Namespace.Cesium |
| | | // provided by https://github.com/criis |
| | | material = new global.DC.Namespace.Cesium.ImageMaterialProperty({ |
| | | image: this._heatmap._renderer.canvas, |
| | | }) |
| | | if (global.DC.Namespace.Cesium.VERSION >= "1.21") { |
| | | material.transparent = true |
| | | } else if (global.DC.Namespace.Cesium.VERSION >= "1.16") { |
| | | material.alpha = 0.99 |
| | | } |
| | | |
| | | this._layer = this._cesium.entities.add({ |
| | | show: true, |
| | | rectangle: { |
| | | coordinates: this._rectangle, |
| | | material: material |
| | | } |
| | | }) |
| | | } else { |
| | | if (this._layer) { |
| | | this._cesium.scene.imageryLayers.remove(this._layer) |
| | | } |
| | | this._layer = this._cesium.scene.imageryLayers.addImageryProvider(CesiumHeatmap._getImageryProvider(this)) |
| | | } |
| | | }; |
| | | |
| | | /* DON'T TOUCH: |
| | | * |
| | | * heatmap.js v2.0.0 | JavaScript Heatmap Library: http://www.patrick-wied.at/static/heatmapjs/ |
| | | * |
| | | * Copyright 2008-2014 Patrick Wied <heatmapjs@patrick-wied.at> - All rights reserved. |
| | | * Dual licensed under MIT and Beerware license |
| | | * |
| | | * :: 2014-10-31 21:16 |
| | | */ |
| | | (function (a, b, c) { |
| | | b[a] = c()//稍微改了下 |
| | | })("h337", this, function () { |
| | | var a = { |
| | | defaultRadius: 40, |
| | | defaultRenderer: "canvas2d", |
| | | defaultGradient: { .25: "rgb(0,0,255)", .55: "rgb(0,255,0)", .85: "yellow", 1: "rgb(255,0,0)" }, |
| | | defaultMaxOpacity: 1, |
| | | defaultMinOpacity: 0, |
| | | defaultBlur: .85, |
| | | defaultXField: "x", |
| | | defaultYField: "y", |
| | | defaultValueField: "value", |
| | | plugins: {} |
| | | } |
| | | var b = function h () { |
| | | var b = function d (a) { |
| | | this._coordinator = {} |
| | | this._data = [] |
| | | this._radi = [] |
| | | this._min = 0 |
| | | this._max = 1 |
| | | this._xField = a["xField"] || a.defaultXField |
| | | this._yField = a["yField"] || a.defaultYField |
| | | this._valueField = a["valueField"] || a.defaultValueField |
| | | if (a["radius"]) { |
| | | this._cfgRadius = a["radius"] |
| | | } |
| | | } |
| | | var c = a.defaultRadius |
| | | b.prototype = { |
| | | _organiseData: function (a, b) { |
| | | var d = a[this._xField] |
| | | var e = a[this._yField] |
| | | var f = this._radi |
| | | var g = this._data |
| | | var h = this._max |
| | | var i = this._min |
| | | var j = a[this._valueField] || 1 |
| | | var k = a.radius || this._cfgRadius || c |
| | | if (!g[d]) { |
| | | g[d] = [] |
| | | f[d] = [] |
| | | } |
| | | if (!g[d][e]) { |
| | | g[d][e] = j |
| | | f[d][e] = k |
| | | } else { |
| | | g[d][e] += j |
| | | } |
| | | if (g[d][e] > h) { |
| | | if (!b) { |
| | | this._max = g[d][e] |
| | | } else { |
| | | this.setDataMax(g[d][e]) |
| | | } |
| | | return false |
| | | } else { |
| | | return { x: d, y: e, value: j, radius: k, min: i, max: h } |
| | | } |
| | | }, _unOrganizeData: function () { |
| | | var a = [] |
| | | var b = this._data |
| | | var c = this._radi |
| | | for (var d in b) { |
| | | for (var e in b[d]) { |
| | | a.push({ x: d, y: e, radius: c[d][e], value: b[d][e] }) |
| | | } |
| | | } |
| | | return { min: this._min, max: this._max, data: a } |
| | | }, _onExtremaChange: function () { |
| | | this._coordinator.emit("extremachange", { min: this._min, max: this._max }) |
| | | }, addData: function () { |
| | | if (arguments[0].length > 0) { |
| | | var a = arguments[0] |
| | | var b = a.length |
| | | while (b--) { |
| | | this.addData.call(this, a[b]) |
| | | } |
| | | } else { |
| | | var c = this._organiseData(arguments[0], true) |
| | | if (c) { |
| | | this._coordinator.emit("renderpartial", { min: this._min, max: this._max, data: [c] }) |
| | | } |
| | | } |
| | | return this |
| | | }, setData: function (a) { |
| | | var b = a.data |
| | | var c = b.length |
| | | this._data = [] |
| | | this._radi = [] |
| | | for (var d = 0; d < c; d++) { |
| | | this._organiseData(b[d], false) |
| | | } |
| | | this._max = a.max |
| | | this._min = a.min || 0 |
| | | this._onExtremaChange() |
| | | this._coordinator.emit("renderall", this._getInternalData()) |
| | | return this |
| | | }, removeData: function () { |
| | | }, setDataMax: function (a) { |
| | | this._max = a |
| | | this._onExtremaChange() |
| | | this._coordinator.emit("renderall", this._getInternalData()) |
| | | return this |
| | | }, setDataMin: function (a) { |
| | | this._min = a |
| | | this._onExtremaChange() |
| | | this._coordinator.emit("renderall", this._getInternalData()) |
| | | return this |
| | | }, setCoordinator: function (a) { |
| | | this._coordinator = a |
| | | }, _getInternalData: function () { |
| | | return { max: this._max, min: this._min, data: this._data, radi: this._radi } |
| | | }, getData: function () { |
| | | return this._unOrganizeData() |
| | | } |
| | | } |
| | | return b |
| | | }() |
| | | var c = function i () { |
| | | var a = function (a) { |
| | | var b = a.gradient || a.defaultGradient |
| | | var c = document.createElement("canvas") |
| | | var d = c.getContext("2d") |
| | | c.width = 256 |
| | | c.height = 1 |
| | | var e = d.createLinearGradient(0, 0, 256, 1) |
| | | for (var f in b) { |
| | | e.addColorStop(f, b[f]) |
| | | } |
| | | d.fillStyle = e |
| | | d.fillRect(0, 0, 256, 1) |
| | | return d.getImageData(0, 0, 256, 1).data |
| | | } |
| | | var b = function (a, b) { |
| | | var c = document.createElement("canvas") |
| | | var d = c.getContext("2d") |
| | | var e = a |
| | | var f = a |
| | | c.width = c.height = a * 2 |
| | | if (b == 1) { |
| | | d.beginPath() |
| | | d.arc(e, f, a, 0, 2 * Math.PI, false) |
| | | d.fillStyle = "rgba(0,0,0,1)" |
| | | d.fill() |
| | | } else { |
| | | var g = d.createRadialGradient(e, f, a * b, e, f, a) |
| | | g.addColorStop(0, "rgba(0,0,0,1)") |
| | | g.addColorStop(1, "rgba(0,0,0,0)") |
| | | d.fillStyle = g |
| | | d.fillRect(0, 0, 2 * a, 2 * a) |
| | | } |
| | | return c |
| | | } |
| | | var c = function (a) { |
| | | var b = [] |
| | | var c = a.min |
| | | var d = a.max |
| | | var e = a.radi |
| | | // eslint-disable-next-line no-redeclare |
| | | var a = a.data |
| | | var f = Object.keys(a) |
| | | var g = f.length |
| | | while (g--) { |
| | | var h = f[g] |
| | | var i = Object.keys(a[h]) |
| | | var j = i.length |
| | | while (j--) { |
| | | var k = i[j] |
| | | var l = a[h][k] |
| | | var m = e[h][k] |
| | | b.push({ x: h, y: k, value: l, radius: m }) |
| | | } |
| | | } |
| | | return { min: c, max: d, data: b } |
| | | } |
| | | |
| | | function d (b) { |
| | | var c = b.container |
| | | var d = this.shadowCanvas = document.createElement("canvas") |
| | | var e = this.canvas = b.canvas || document.createElement("canvas") |
| | | var f = this._renderBoundaries = [1e4, 1e4, 0, 0] |
| | | var g = getComputedStyle(b.container) || {} |
| | | e.className = "heatmap-canvas" |
| | | this._width = e.width = d.width = +g.width.replace(/px/, "") |
| | | this._height = e.height = d.height = +g.height.replace(/px/, "") |
| | | this.shadowCtx = d.getContext("2d") |
| | | this.ctx = e.getContext("2d") |
| | | e.style.cssText = d.style.cssText = "position:absolute;left:0;top:0;" |
| | | c.style.position = "relative" |
| | | c.appendChild(e) |
| | | this._palette = a(b) |
| | | this._templates = {} |
| | | this._setStyles(b) |
| | | } |
| | | |
| | | d.prototype = { |
| | | renderPartial: function (a) { |
| | | this._drawAlpha(a) |
| | | this._colorize() |
| | | }, renderAll: function (a) { |
| | | this._clear() |
| | | this._drawAlpha(c(a)) |
| | | this._colorize() |
| | | }, _updateGradient: function (b) { |
| | | this._palette = a(b) |
| | | }, updateConfig: function (a) { |
| | | if (a["gradient"]) { |
| | | this._updateGradient(a) |
| | | } |
| | | this._setStyles(a) |
| | | }, setDimensions: function (a, b) { |
| | | this._width = a |
| | | this._height = b |
| | | this.canvas.width = this.shadowCanvas.width = a |
| | | this.canvas.height = this.shadowCanvas.height = b |
| | | }, _clear: function () { |
| | | this.shadowCtx.clearRect(0, 0, this._width, this._height) |
| | | this.ctx.clearRect(0, 0, this._width, this._height) |
| | | }, _setStyles: function (a) { |
| | | this._blur = a.blur == 0 ? 0 : a.blur || a.defaultBlur |
| | | if (a.backgroundColor) { |
| | | this.canvas.style.backgroundColor = a.backgroundColor |
| | | } |
| | | this._opacity = (a.opacity || 0) * 255 |
| | | this._maxOpacity = (a.maxOpacity || a.defaultMaxOpacity) * 255 |
| | | this._minOpacity = (a.minOpacity || a.defaultMinOpacity) * 255 |
| | | this._useGradientOpacity = !!a.useGradientOpacity |
| | | }, _drawAlpha: function (a) { |
| | | var c = this._min = a.min |
| | | var d = this._max = a.max |
| | | // eslint-disable-next-line no-redeclare |
| | | var a = a.data || [] |
| | | var e = a.length |
| | | var f = 1 - this._blur |
| | | while (e--) { |
| | | var g = a[e] |
| | | var h = g.x |
| | | var i = g.y |
| | | var j = g.radius |
| | | var k = Math.min(g.value, d) |
| | | var l = h - j |
| | | var m = i - j |
| | | var n = this.shadowCtx |
| | | var o |
| | | if (!this._templates[j]) { |
| | | this._templates[j] = o = b(j, f) |
| | | } else { |
| | | o = this._templates[j] |
| | | } |
| | | n.globalAlpha = (k - c) / (d - c) |
| | | n.drawImage(o, l, m) |
| | | if (l < this._renderBoundaries[0]) { |
| | | this._renderBoundaries[0] = l |
| | | } |
| | | if (m < this._renderBoundaries[1]) { |
| | | this._renderBoundaries[1] = m |
| | | } |
| | | if (l + 2 * j > this._renderBoundaries[2]) { |
| | | this._renderBoundaries[2] = l + 2 * j |
| | | } |
| | | if (m + 2 * j > this._renderBoundaries[3]) { |
| | | this._renderBoundaries[3] = m + 2 * j |
| | | } |
| | | } |
| | | }, _colorize: function () { |
| | | var a = this._renderBoundaries[0] |
| | | var b = this._renderBoundaries[1] |
| | | var c = this._renderBoundaries[2] - a |
| | | var d = this._renderBoundaries[3] - b |
| | | var e = this._width |
| | | var f = this._height |
| | | var g = this._opacity |
| | | var h = this._maxOpacity |
| | | var i = this._minOpacity |
| | | var j = this._useGradientOpacity |
| | | if (a < 0) { |
| | | a = 0 |
| | | } |
| | | if (b < 0) { |
| | | b = 0 |
| | | } |
| | | if (a + c > e) { |
| | | c = e - a |
| | | } |
| | | if (b + d > f) { |
| | | d = f - b |
| | | } |
| | | var k = this.shadowCtx.getImageData(a, b, c, d) |
| | | var l = k.data |
| | | var m = l.length |
| | | var n = this._palette |
| | | for (var o = 3; o < m; o += 4) { |
| | | var p = l[o] |
| | | var q = p * 4 |
| | | if (!q) { |
| | | continue |
| | | } |
| | | var r |
| | | if (g > 0) { |
| | | r = g |
| | | } else { |
| | | if (p < h) { |
| | | if (p < i) { |
| | | r = i |
| | | } else { |
| | | r = p |
| | | } |
| | | } else { |
| | | r = h |
| | | } |
| | | } |
| | | l[o - 3] = n[q] |
| | | l[o - 2] = n[q + 1] |
| | | l[o - 1] = n[q + 2] |
| | | l[o] = j ? n[q + 3] : r |
| | | } |
| | | k.data = l |
| | | this.ctx.putImageData(k, a, b) |
| | | this._renderBoundaries = [1e3, 1e3, 0, 0] |
| | | }, getValueAt: function (a) { |
| | | var b |
| | | var c = this.shadowCtx |
| | | var d = c.getImageData(a.x, a.y, 1, 1) |
| | | var e = d.data[3] |
| | | var f = this._max |
| | | var g = this._min |
| | | b = Math.abs(f - g) * (e / 255) >> 0 |
| | | return b |
| | | }, getDataURL: function () { |
| | | return this.canvas.toDataURL() |
| | | } |
| | | } |
| | | return d |
| | | }() |
| | | var d = function j () { |
| | | var b = false |
| | | if (a["defaultRenderer"] === "canvas2d") { |
| | | b = c |
| | | } |
| | | return b |
| | | }() |
| | | var e = { |
| | | merge: function () { |
| | | var a = {} |
| | | var b = arguments.length |
| | | for (var c = 0; c < b; c++) { |
| | | var d = arguments[c] |
| | | for (var e in d) { |
| | | a[e] = d[e] |
| | | } |
| | | } |
| | | return a |
| | | } |
| | | } |
| | | var f = function k () { |
| | | var c = function h () { |
| | | function a () { |
| | | this.cStore = {} |
| | | } |
| | | |
| | | a.prototype = { |
| | | on: function (a, b, c) { |
| | | var d = this.cStore |
| | | if (!d[a]) { |
| | | d[a] = [] |
| | | } |
| | | d[a].push(function (a) { |
| | | return b.call(c, a) |
| | | }) |
| | | }, emit: function (a, b) { |
| | | var c = this.cStore |
| | | if (c[a]) { |
| | | var d = c[a].length |
| | | for (var e = 0; e < d; e++) { |
| | | var f = c[a][e] |
| | | f(b) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return a |
| | | }() |
| | | var f = function (a) { |
| | | var b = a._renderer |
| | | var c = a._coordinator |
| | | var d = a._store |
| | | c.on("renderpartial", b.renderPartial, b) |
| | | c.on("renderall", b.renderAll, b) |
| | | c.on("extremachange", function (b) { |
| | | a._config.onExtremaChange && a._config.onExtremaChange({ |
| | | min: b.min, |
| | | max: b.max, |
| | | gradient: a._config["gradient"] || a._config["defaultGradient"] |
| | | }) |
| | | }) |
| | | d.setCoordinator(c) |
| | | } |
| | | |
| | | function g () { |
| | | var g = this._config = e.merge(a, arguments[0] || {}) |
| | | this._coordinator = new c |
| | | if (g["plugin"]) { |
| | | var h = g["plugin"] |
| | | if (!a.plugins[h]) { |
| | | throw new Error("Plugin '" + h + "' not found. Maybe it was not registered.") |
| | | } else { |
| | | var i = a.plugins[h] |
| | | this._renderer = new i.renderer(g) |
| | | this._store = new i.store(g) |
| | | } |
| | | } else { |
| | | this._renderer = new d(g) |
| | | this._store = new b(g) |
| | | } |
| | | f(this) |
| | | } |
| | | |
| | | g.prototype = { |
| | | addData: function () { |
| | | this._store.addData.apply(this._store, arguments) |
| | | return this |
| | | }, removeData: function () { |
| | | this._store.removeData && this._store.removeData.apply(this._store, arguments) |
| | | return this |
| | | }, setData: function () { |
| | | this._store.setData.apply(this._store, arguments) |
| | | return this |
| | | }, setDataMax: function () { |
| | | this._store.setDataMax.apply(this._store, arguments) |
| | | return this |
| | | }, setDataMin: function () { |
| | | this._store.setDataMin.apply(this._store, arguments) |
| | | return this |
| | | }, configure: function (a) { |
| | | this._config = e.merge(this._config, a) |
| | | this._renderer.updateConfig(this._config) |
| | | this._coordinator.emit("renderall", this._store._getInternalData()) |
| | | return this |
| | | }, repaint: function () { |
| | | this._coordinator.emit("renderall", this._store._getInternalData()) |
| | | return this |
| | | }, getData: function () { |
| | | return this._store.getData() |
| | | }, getDataURL: function () { |
| | | return this._renderer.getDataURL() |
| | | }, getValueAt: function (a) { |
| | | if (this._store.getValueAt) { |
| | | return this._store.getValueAt(a) |
| | | } else if (this._renderer.getValueAt) { |
| | | return this._renderer.getValueAt(a) |
| | | } else { |
| | | return null |
| | | } |
| | | } |
| | | } |
| | | return g |
| | | }() |
| | | var g = { |
| | | create: function (a) { |
| | | return new f(a) |
| | | }, register: function (b, c) { |
| | | a.plugins[b] = c |
| | | } |
| | | } |
| | | return g |
| | | }) |