当前位置: 首页 > news >正文

山海鲸可视化——天地图画面和热力图

山海鲸引入天地图目前只有 iframe 的方式引入

首先我们创建一个文件夹
——index.html
——index.js
——data.js

大家都是大佬,我就不详细介绍了,上代码都能看得懂

首先是index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><title>天地图</title><script type="text/javascript" src="http://api.tianditu.gov.cn/api?v=4.0&tk=天地图申请的key"></script><style>body,html {width: 100%;height: 100%;margin: 0;font-family: "Microsoft YaHei",serif}#mapDiv {width: 100%;height: 100%;}input,b,p {margin-left: 5px;font-size: 14px}</style></head>
<script src="./index.js" defer></script>
<script src="./data.js" defer></script><body onload="onLoad()">
<div id="mapDiv">
</div>
</body>
</html>

index.html里面就是创建了基础的地图元素和引入方法 没啥东西

接下来是index.js

let map;
const zoom = 13; //缩放大小
let polygonInitArray = null; //保存默认地块数组
function onLoad() {//初始化地图对象map = new T.Map("mapDiv");//设置显示地图的中心点和级别map.centerAndZoom(new T.LngLat(102.85428, 24.82373), zoom);map.setMinZoom(12); // 设置最大缩放级别map.setStyle("indigo"); // 设置地图风格//允许鼠标滚轮缩放地图map.enableScrollWheelZoom();// 第一块const points1 = generatePolygonArray(lineData1);const polygon1 = createLandAndSetStyle(points1, "#fff", 2, 0.5, "#0BFA01", 1);// .....很多块polygonInitArray = [polygon1,//....很多块];polygonInitArray.forEach((polygon) => map.addOverLay(polygon));// 生成地块数组函数function generatePolygonArray(data) {return data.map(({ lng, lat }) => new T.LngLat(lng, lat));}// 创建地块并为地块设置颜色的函数function createLandAndSetStyle(targetObj,color,weight,opacity,fillColor,fillOpacity,lineStyle = "solid") {return new T.Polygon(targetObj, {color,weight,opacity,fillColor,fillOpacity,lineStyle,});}
}

上面就是创建块的函数,还缺的就是组成这个块的每一个点的经纬度

接下来是data.js


const lineData1 = [{ lng: 102.83233134, lat: 24.8511322 },{ lng: 102.84071464, lat: 24.85366787 },{ lng: 102.8415131, lat: 24.85049824 },{ lng: 102.83971668, lat: 24.8482342 },{ lng: 102.83742126, lat: 24.84705688 },{ lng: 102.83402801, lat: 24.84841532 },{ lng: 102.83233134, lat: 24.8511322 },
];

看不懂的直接复制代码,运行了就知道了,注意 天地图的key要自己申请

上面讲的是地图上勾画面

接下来我们说天地图热力图怎么画

首先也是创建文件夹

包含
——index.html
——index.js
——heatMap.js(这个是生成热力图关键的js不需要改动)
这里我没有把数据放data.js里面,全放index.js里面,懒了

首先index.html里面没啥改动,跟上面差不多

<!DOCTYPE html>
<html lang="zh-CN"><head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><title>天地图-地图API-范例-地图加载单图层</title><scripttype="text/javascript"src="http://api.tianditu.gov.cn/api?v=4.0&tk=申请的天地图key"></script><style>body,html {width: 100%;height: 100%;margin: 0;font-family: "Microsoft YaHei", serif;}#mapDiv {width: 100%;height: 100%;}input,b,p {margin-left: 5px;font-size: 14px;}</style></head><script src="./index.js" defer></script><script src="./heatMap.js" defer></script><body onload="onLoad()"><div id="mapDiv"></div></body>
</html>

接下来index.js

let map;
const zoom = 13;
function onLoad() {//初始化地图对象map = new T.Map("mapDiv");//设置显示地图的中心点和级别map.centerAndZoom(new T.LngLat(102.85428, 24.82373), zoom);map.setMinZoom(12); // 设置最大缩放级别map.setStyle("indigo"); // 设置地图风格//允许鼠标滚轮缩放地图map.enableScrollWheelZoom();// 创建一块热力图//参数说明如下:/* visible 热力图是否显示,默认为true* opacity 热力的透明度,1-100* radius 势力图的每个点的半径大小* gradient  {JSON} 热力图的渐变区间 . gradient如下所示*	{.2:'rgb(0, 255, 255)',.5:'rgb(0, 110, 255)',.8:'rgb(100, 0, 255)'}value 为颜色值.*/const data = [{ name: "test1", value: 190 },{ name: "test2", value: 180 },{ name: "test3", value: 170 },{ name: "test4", value: 105 },{ name: "test5", value: 95 },{ name: "test6", value: 134 },{ name: "test7", value: 167 },{ name: "test8", value: 178 },{ name: "test9", value: 87 },{ name: "test10", value: 178 },{ name: "test11", value: 147 },{ name: "test12", value: 87 },{ name: "test13", value: 100 },{ name: "test14", value: 124 },];const geoCoordMap = {test1: [102.85428, 24.82373],test2: [102.88428, 24.85373],test3: [102.89428, 24.83373],test4: [102.84303354, 24.80530684],test5: [102.84071464, 24.85366787],test6: [102.82823951, 24.85040768],test7: [102.83991634, 24.84270977],test8: [102.84370878, 24.84479278],test9: [102.84150136, 24.82757133],test10: [102.83916618, 24.8021391],test11: [102.88084795, 24.84942571],test12: [102.87013422, 24.81139329],test13: [102.88492484, 24.84942571],test14: [102.8701342, 24.81139329],};var convertData = function (data) {var res = [];for (var i = 0; i < data.length; i++) {var geoCoord = geoCoordMap[data[i].name];if (geoCoord) {res.push({name: data[i].name,lat: geoCoord[1],lng: geoCoord[0],count: data[i].value,});}}return res;};var points = convertData(data);let heatmapOverlay = new T.HeatmapOverlay({radius: 30,visible: true,gradient: {0.2: "#FAFFA8FF",0.5: "#FF8C12FF",0.8: "#F51D27FF",},});map.addOverLay(heatmapOverlay);heatmapOverlay.setDataSet({ data: points, max: 300 });
}

接下来就是一个heatMap.js文件,这个是我自己再天地图示例里面复制源码来的,下载要上github,懒得去,你们要有直接复制用

/*** 浠ョ壒娈婇珮浜殑褰㈠紡鐩磋灞曠ず鏁版嵁鍒嗗竷鐘跺喌銆�* 娉細chrome銆乻afari銆両E9鍙婁互涓婃祻瑙堝櫒锛屾牳蹇冪殑浠g爜涓昏鏉ヨ嚜浜庣涓夋柟heatmap.js銆侤author juyang*/
T.HeatmapOverlay = T.Overlay.extend({/***鏋勯€�* @param options*/initialize: function (options) {this.conf = options;this.heatmap = null;this.latlngs = [];this.bounds = null;},onAdd: function (map) {this._map = map;var el = document.createElement("div");el.style.position = "absolute";el.style.top = 0;el.style.left = 0;el.style.border = 0;el.style.width = this._map.getSize().x + "px";el.style.height = this._map.getSize().y + "px";this.conf.container = el;if (!this.isSupportCanvas()) {//鍒ゆ柇鏄惁鏀寔Canvas.return el;}this.conf.valueField = this.conf.valueField || "count";this.conf.latField = this.conf.latField || "lat";this.conf.lngField = this.conf.lngField || "lng";this.heatmap = h337.create(this.conf);this.heatmap._renderer.setDimensions(this._map.getSize().x,this._map.getSize().y);map.getPanes().overlayPane.appendChild(el);map.on("moveend", this._reset, this);this._div = el;},onRemove: function (map) {map.getPanes().overlayPane.removeChild(this._div);map.off("moveend", this._reset, this);},_reset: function () {var size = this._map.getSize();this._div.style.width = size.x + "px";this._div.style.height = size.y + "px";this.heatmap._renderer.setDimensions(size.x, size.y);this.draw();},getElement: function () {return this.conf.container;},draw: function () {if (!this.isSupportCanvas()) {//鍒ゆ柇鏄惁鏀寔Canvas.return;}//  if (this.isHidden())  return;var currentBounds = this._map.getBounds();if (!this.isadd && currentBounds.equals(this.bounds)) {this.isadd = false;return;}this.bounds = currentBounds;var ne = this._map.lngLatToLayerPoint(currentBounds.getNorthEast()),sw = this._map.lngLatToLayerPoint(currentBounds.getSouthWest()),topY = ne.y,leftX = sw.x,h = sw.y - ne.y,w = ne.x - sw.x;this.conf.container.style.width = w + "px";this.conf.container.style.height = h + "px";this.conf.container.style[this.CSS_TRANSFORM()] ="translate(" + Math.round(leftX) + "px," + Math.round(topY) + "px)";if (this.latlngs.length > 0) {this.heatmap.removeData();}var len = this.latlngs.length;d = {max: this.heatmap._store.getData().max,data: [],};while (len--) {var latlng = this.latlngs[len].latlng;if (!currentBounds.contains(latlng)) {continue;}var roundedPoint = this._getContainerPoint(latlng);d.data.push({x: roundedPoint.x,y: roundedPoint.y,count: this.latlngs[len].c,});}this.heatmap.setData(d);},CSS_TRANSFORM: function () {var div = document.createElement("div");var props = ["transform","WebkitTransform","MozTransform","OTransform","msTransform",];for (var i = 0; i < props.length; i++) {var prop = props[i];if (div.style[prop] !== undefined) {return prop;}}return props[0];},/*** 璁剧疆鐑姏鍥惧睍鐜扮殑璇︾粏鏁版嵁, 瀹炵幇涔嬪悗,鍗冲彲浠ョ珛鍒诲睍鐜�* {"<b>max</b>" : {Number} 鏉冮噸鐨勬渶澶у€�,* <br />"<b>data</b>" : {Array} 鍧愭爣璇︾粏鏁版嵁,鏍煎紡濡備笅 <br/>* {"lng":116.421969,"lat":39.913527,"count":3}, 鍏朵腑<br/>* lng lat鍒嗗埆涓虹粡绾害, count鏉冮噸鍊�* @param data*/setDataSet: function (data) {this.data = data;if (!this.isSupportCanvas()) {//鍒ゆ柇鏄惁鏀寔Canvas.return;}var currentBounds = this._map.getBounds();var mapdata = {max: data.max,data: [],};var d = data.data,dlen = d.length;this.latlngs = [];this.heatmap.removeData();while (dlen--) {var latlng = new T.LngLat(d[dlen][this.conf.lngField],d[dlen][this.conf.latField]);this.latlngs.push({latlng: latlng,c: d[dlen].count,});if (!currentBounds.contains(latlng)) {continue;}var point = this._getContainerPoint(latlng);mapdata.data.push({x: point.x,y: point.y,count: d[dlen].count,});}this.heatmap.setData(mapdata);},_getContainerPoint: function (latlng) {var currentBounds = this._map.getBounds();var divPixel = this._map.lngLatToLayerPoint(latlng),leftX = this._map.lngLatToLayerPoint(currentBounds.getSouthWest()).x,topY = this._map.lngLatToLayerPoint(currentBounds.getNorthEast()).y,screenPixel = new T.Point(divPixel.x - leftX, divPixel.y - topY);var point = this.pixelTransform(screenPixel);return point;},/*** 娣诲姞鍔垮姏鍥剧殑璇︾粏鍧愭爣鐐�* @param {Number} lng 缁忓害鍧愭爣* @param {Number} lat 缁忓害鍧愭爣* @param {Number} count 缁忓害鍧愭爣*/addDataPoint: function (lng, lat, count) {if (!this.isSupportCanvas()) {return;}if (this.data && this.data.data) {this.data.data.push({lng: lng,lat: lat,count: count,});}var latlng = new T.LngLat(lng, lat),point = this.pixelTransform(this._map.lngLatToContainerPoint(latlng));this.latlngs.push({latlng: latlng,c: count,});// this.heatmap.addData({x: point.x, y: point.y, value: count });this.isadd = true;this.draw();},/*** 鍐呴儴浣跨敤鐨勫潗鏍囪浆鍖�* @param p* @returns {*}*/pixelTransform: function (p) {var h = this.heatmap._config.container.clientHeight,w = this.heatmap._config.container.clientWidth;if (w == 0 || h == 0) return p;while (p.x < 0) {p.x += w;}while (p.x > w) {p.x -= w;}while (p.y < 0) {p.y += h;}while (p.y > h) {p.y -= h;}p.x = p.x >> 0;p.y = p.y >> 0;return p;},/*** 鏇存敼鐑姏鍥剧殑灞曠幇鎴栬€呭叧闂�*/toggle: function () {if (!this.isSupportCanvas()) {//鍒ゆ柇鏄惁鏀寔Canvas.return;}if (this.conf.visible === true) {this.conf.visible = false;} else {this.conf.visible = true;}if (this.conf.visible) {this.conf.container.style.display = "block";} else {this.conf.container.style.display = "none";}return this.conf.visible;},setOptions: function (options) {if (!this.isSupportCanvas()) {//鍒ゆ柇鏄惁鏀寔Canvas.return;}for (var key in options) {if (key == "radius") {this.heatmap._store._cfgRadius = options[key];}if (key == "opacity") {options[key] = options[key] / 100;}}this.heatmap.configure(options);if (this.data) {this.setDataSet(this.data); //閲嶆柊娓叉煋}},isSupportCanvas: function () {var elem = document.createElement("canvas");return !!(elem.getContext && elem.getContext("2d"));},
});
/*==============================浠ヤ笂閮ㄥ垎涓轰笓涓哄ぉ鍦板浘鎵撻€犵殑瑕嗙洊鐗�===================================================*/
/*==============================浠ヤ笅閮ㄥ垎涓篽eatmap.js鐨勬牳蹇冧唬鐮�,鍙礋璐g儹鍔涘浘鐨勫睍鐜�====================================*//** heatmap.js v2.0.2 | JavaScript Heatmap Library** Copyright 2008-2016 Patrick Wied <heatmapjs@patrick-wied.at> - All rights reserved.* Dual licensed under MIT and Beerware license** :: 2016-02-04 21:41*/
(function (name, context, factory) {// Supports UMD. AMD, CommonJS/Node.js and browser contextif (typeof module !== "undefined" && module.exports) {module.exports = factory();} else if (typeof define === "function" && define.amd) {define(factory);} else {context[name] = factory();}
})("h337", this, function () {// Heatmap Config stores default values and will be merged with instance configvar HeatmapConfig = {defaultRadius: 40,defaultRenderer: "canvas2d",defaultGradient: {0.25: "rgb(0,0,255)",0.55: "rgb(0,255,0)",0.85: "yellow",1.0: "rgb(255,0,0)",},defaultMaxOpacity: 1,defaultMinOpacity: 0,defaultBlur: 0.85,defaultXField: "x",defaultYField: "y",defaultValueField: "value",plugins: {},};var Store = (function StoreClosure() {var Store = function Store(config) {this._coordinator = {};this._data = [];this._radi = [];this._min = 0;this._max = 1;this._xField = config["xField"] || config.defaultXField;this._yField = config["yField"] || config.defaultYField;this._valueField = config["valueField"] || config.defaultValueField;if (config["radius"]) {this._cfgRadius = config["radius"];}};var defaultRadius = HeatmapConfig.defaultRadius;Store.prototype = {// when forceRender = false -> called from setData, omits renderall event_organiseData: function (dataPoint, forceRender) {var x = dataPoint[this._xField];var y = dataPoint[this._yField];var radi = this._radi;var store = this._data;var max = this._max;var min = this._min;var value = dataPoint[this._valueField] || 1;var radius = dataPoint.radius || this._cfgRadius || defaultRadius;if (!store[x]) {store[x] = [];radi[x] = [];}if (!store[x][y]) {store[x][y] = value;radi[x][y] = radius;} else {store[x][y] += value;}if (store[x][y] > max) {if (!forceRender) {this._max = store[x][y];} else {this.setDataMax(store[x][y]);}return false;} else {return {x: x,y: y,value: value,radius: radius,min: min,max: max,};}},_unOrganizeData: function () {var unorganizedData = [];var data = this._data;var radi = this._radi;for (var x in data) {for (var y in data[x]) {unorganizedData.push({x: x,y: y,radius: radi[x][y],value: data[x][y],});}}return {min: this._min,max: this._max,data: unorganizedData,};},_onExtremaChange: function () {this._coordinator.emit("extremachange", {min: this._min,max: this._max,});},addData: function () {if (arguments[0].length > 0) {var dataArr = arguments[0];var dataLen = dataArr.length;while (dataLen--) {this.addData.call(this, dataArr[dataLen]);}} else {// add to storevar organisedEntry = this._organiseData(arguments[0], true);if (organisedEntry) {this._coordinator.emit("renderpartial", {min: this._min,max: this._max,data: [organisedEntry],});}}return this;},setData: function (data) {var dataPoints = data.data;var pointsLen = dataPoints.length;// reset data arraysthis._data = [];this._radi = [];for (var i = 0; i < pointsLen; i++) {this._organiseData(dataPoints[i], false);}this._max = data.max;this._min = data.min || 0;this._onExtremaChange();this._coordinator.emit("renderall", this._getInternalData());return this;},removeData: function () {// TODO: implement},setDataMax: function (max) {this._max = max;this._onExtremaChange();this._coordinator.emit("renderall", this._getInternalData());return this;},setDataMin: function (min) {this._min = min;this._onExtremaChange();this._coordinator.emit("renderall", this._getInternalData());return this;},setCoordinator: function (coordinator) {this._coordinator = coordinator;},_getInternalData: function () {return {max: this._max,min: this._min,data: this._data,radi: this._radi,};},getData: function () {return this._unOrganizeData();} /*,TODO: rethink.getValueAt: function(point) {var value;var radius = 100;var x = point.x;var y = point.y;var data = this._data;if (data[x] && data[x][y]) {return data[x][y];} else {var values = [];// radial search for datapoints based on default radiusfor(var distance = 1; distance < radius; distance++) {var neighbors = distance * 2 +1;var startX = x - distance;var startY = y - distance;for(var i = 0; i < neighbors; i++) {for (var o = 0; o < neighbors; o++) {if ((i == 0 || i == neighbors-1) || (o == 0 || o == neighbors-1)) {if (data[startY+i] && data[startY+i][startX+o]) {values.push(data[startY+i][startX+o]);}} else {continue;}}}}if (values.length > 0) {return Math.max.apply(Math, values);}}return false;}*/,};return Store;})();var Canvas2dRenderer = (function Canvas2dRendererClosure() {var _getColorPalette = function (config) {var gradientConfig = config.gradient || config.defaultGradient;var paletteCanvas = document.createElement("canvas");var paletteCtx = paletteCanvas.getContext("2d");paletteCanvas.width = 256;paletteCanvas.height = 1;var gradient = paletteCtx.createLinearGradient(0, 0, 256, 1);for (var key in gradientConfig) {gradient.addColorStop(key, gradientConfig[key]);}paletteCtx.fillStyle = gradient;paletteCtx.fillRect(0, 0, 256, 1);return paletteCtx.getImageData(0, 0, 256, 1).data;};var _getPointTemplate = function (radius, blurFactor) {var tplCanvas = document.createElement("canvas");var tplCtx = tplCanvas.getContext("2d");var x = radius;var y = radius;tplCanvas.width = tplCanvas.height = radius * 2;if (blurFactor == 1) {tplCtx.beginPath();tplCtx.arc(x, y, radius, 0, 2 * Math.PI, false);tplCtx.fillStyle = "rgba(0,0,0,1)";tplCtx.fill();} else {var gradient = tplCtx.createRadialGradient(x,y,radius * blurFactor,x,y,radius);gradient.addColorStop(0, "rgba(0,0,0,1)");gradient.addColorStop(1, "rgba(0,0,0,0)");tplCtx.fillStyle = gradient;tplCtx.fillRect(0, 0, 2 * radius, 2 * radius);}return tplCanvas;};var _prepareData = function (data) {var renderData = [];var min = data.min;var max = data.max;var radi = data.radi;var data = data.data;var xValues = Object.keys(data);var xValuesLen = xValues.length;while (xValuesLen--) {var xValue = xValues[xValuesLen];var yValues = Object.keys(data[xValue]);var yValuesLen = yValues.length;while (yValuesLen--) {var yValue = yValues[yValuesLen];var value = data[xValue][yValue];var radius = radi[xValue][yValue];renderData.push({x: xValue,y: yValue,value: value,radius: radius,});}}return {min: min,max: max,data: renderData,};};function Canvas2dRenderer(config) {var container = config.container;var shadowCanvas = (this.shadowCanvas = document.createElement("canvas"));var canvas = (this.canvas =config.canvas || document.createElement("canvas"));var renderBoundaries = (this._renderBoundaries = [10000, 10000, 0, 0]);var computed = getComputedStyle(config.container) || {};canvas.className = "heatmap-canvas";this._width =canvas.width =shadowCanvas.width =config.width || +computed.width.replace(/px/, "");this._height =canvas.height =shadowCanvas.height =config.height || +computed.height.replace(/px/, "");this.shadowCtx = shadowCanvas.getContext("2d");this.ctx = canvas.getContext("2d");// @TODO:// conditional wrappercanvas.style.cssText = shadowCanvas.style.cssText ="position:absolute;left:0;top:0;";container.style.position = "relative";container.appendChild(canvas);this._palette = _getColorPalette(config);this._templates = {};this._setStyles(config);}Canvas2dRenderer.prototype = {renderPartial: function (data) {if (data.data.length > 0) {this._drawAlpha(data);this._colorize();}},renderAll: function (data) {// reset render boundariesthis._clear();if (data.data.length > 0) {this._drawAlpha(_prepareData(data));this._colorize();}},_updateGradient: function (config) {this._palette = _getColorPalette(config);},updateConfig: function (config) {if (config["gradient"]) {this._updateGradient(config);}this._setStyles(config);},setDimensions: function (width, height) {this._width = width;this._height = height;this.canvas.width = this.shadowCanvas.width = width;this.canvas.height = this.shadowCanvas.height = height;},_clear: function () {this.shadowCtx.clearRect(0, 0, this._width, this._height);this.ctx.clearRect(0, 0, this._width, this._height);},_setStyles: function (config) {this._blur = config.blur == 0 ? 0 : config.blur || config.defaultBlur;if (config.backgroundColor) {this.canvas.style.backgroundColor = config.backgroundColor;}this._width =this.canvas.width =this.shadowCanvas.width =config.width || this._width;this._height =this.canvas.height =this.shadowCanvas.height =config.height || this._height;this._opacity = (config.opacity || 0) * 255;this._maxOpacity =(config.maxOpacity || config.defaultMaxOpacity) * 255;this._minOpacity =(config.minOpacity || config.defaultMinOpacity) * 255;this._useGradientOpacity = !!config.useGradientOpacity;},_drawAlpha: function (data) {var min = (this._min = data.min);var max = (this._max = data.max);var data = data.data || [];var dataLen = data.length;// on a point basis?var blur = 1 - this._blur;while (dataLen--) {var point = data[dataLen];var x = point.x;var y = point.y;var radius = point.radius;// if value is bigger than max// use max as valuevar value = Math.min(point.value, max);var rectX = x - radius;var rectY = y - radius;var shadowCtx = this.shadowCtx;var tpl;if (!this._templates[radius]) {this._templates[radius] = tpl = _getPointTemplate(radius, blur);} else {tpl = this._templates[radius];}// value from minimum / value range// => [0, 1]var templateAlpha = (value - min) / (max - min);// this fixes #176: small values are not visible because globalAlpha < .01 cannot be read from imageDatashadowCtx.globalAlpha = templateAlpha < 0.01 ? 0.01 : templateAlpha;shadowCtx.drawImage(tpl, rectX, rectY);// update renderBoundariesif (rectX < this._renderBoundaries[0]) {this._renderBoundaries[0] = rectX;}if (rectY < this._renderBoundaries[1]) {this._renderBoundaries[1] = rectY;}if (rectX + 2 * radius > this._renderBoundaries[2]) {this._renderBoundaries[2] = rectX + 2 * radius;}if (rectY + 2 * radius > this._renderBoundaries[3]) {this._renderBoundaries[3] = rectY + 2 * radius;}}},_colorize: function () {var x = this._renderBoundaries[0];var y = this._renderBoundaries[1];var width = this._renderBoundaries[2] - x;var height = this._renderBoundaries[3] - y;var maxWidth = this._width;var maxHeight = this._height;var opacity = this._opacity;var maxOpacity = this._maxOpacity;var minOpacity = this._minOpacity;var useGradientOpacity = this._useGradientOpacity;if (x < 0) {x = 0;}if (y < 0) {y = 0;}if (x + width > maxWidth) {width = maxWidth - x;}if (y + height > maxHeight) {height = maxHeight - y;}var img = this.shadowCtx.getImageData(x, y, width, height);var imgData = img.data;var len = imgData.length;var palette = this._palette;for (var i = 3; i < len; i += 4) {var alpha = imgData[i];var offset = alpha * 4;if (!offset) {continue;}var finalAlpha;if (opacity > 0) {finalAlpha = opacity;} else {if (alpha < maxOpacity) {if (alpha < minOpacity) {finalAlpha = minOpacity;} else {finalAlpha = alpha;}} else {finalAlpha = maxOpacity;}}imgData[i - 3] = palette[offset];imgData[i - 2] = palette[offset + 1];imgData[i - 1] = palette[offset + 2];imgData[i] = useGradientOpacity ? palette[offset + 3] : finalAlpha;}img.data = imgData;this.ctx.putImageData(img, x, y);this._renderBoundaries = [1000, 1000, 0, 0];},getValueAt: function (point) {var value;var shadowCtx = this.shadowCtx;var img = shadowCtx.getImageData(point.x, point.y, 1, 1);var data = img.data[3];var max = this._max;var min = this._min;value = (Math.abs(max - min) * (data / 255)) >> 0;return value;},getDataURL: function () {return this.canvas.toDataURL();},};return Canvas2dRenderer;})();var Renderer = (function RendererClosure() {var rendererFn = false;if (HeatmapConfig["defaultRenderer"] === "canvas2d") {rendererFn = Canvas2dRenderer;}return rendererFn;})();var Util = {merge: function () {var merged = {};var argsLen = arguments.length;for (var i = 0; i < argsLen; i++) {var obj = arguments[i];for (var key in obj) {merged[key] = obj[key];}}return merged;},};// Heatmap Constructorvar Heatmap = (function HeatmapClosure() {var Coordinator = (function CoordinatorClosure() {function Coordinator() {this.cStore = {};}Coordinator.prototype = {on: function (evtName, callback, scope) {var cStore = this.cStore;if (!cStore[evtName]) {cStore[evtName] = [];}cStore[evtName].push(function (data) {return callback.call(scope, data);});},emit: function (evtName, data) {var cStore = this.cStore;if (cStore[evtName]) {var len = cStore[evtName].length;for (var i = 0; i < len; i++) {var callback = cStore[evtName][i];callback(data);}}},};return Coordinator;})();var _connect = function (scope) {var renderer = scope._renderer;var coordinator = scope._coordinator;var store = scope._store;coordinator.on("renderpartial", renderer.renderPartial, renderer);coordinator.on("renderall", renderer.renderAll, renderer);coordinator.on("extremachange", function (data) {scope._config.onExtremaChange &&scope._config.onExtremaChange({min: data.min,max: data.max,gradient:scope._config["gradient"] || scope._config["defaultGradient"],});});store.setCoordinator(coordinator);};function Heatmap() {var config = (this._config = Util.merge(HeatmapConfig,arguments[0] || {}));this._coordinator = new Coordinator();if (config["plugin"]) {var pluginToLoad = config["plugin"];if (!HeatmapConfig.plugins[pluginToLoad]) {throw new Error("Plugin '" +pluginToLoad +"' not found. Maybe it was not registered.");} else {var plugin = HeatmapConfig.plugins[pluginToLoad];// set plugin renderer and storethis._renderer = new plugin.renderer(config);this._store = new plugin.store(config);}} else {this._renderer = new Renderer(config);this._store = new Store(config);}_connect(this);}// @TODO:// add API documentationHeatmap.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 (config) {this._config = Util.merge(this._config, config);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 (point) {if (this._store.getValueAt) {return this._store.getValueAt(point);} else if (this._renderer.getValueAt) {return this._renderer.getValueAt(point);} else {return null;}},};return Heatmap;})();// corevar heatmapFactory = {create: function (config) {return new Heatmap(config);},register: function (pluginKey, plugin) {HeatmapConfig.plugins[pluginKey] = plugin;},};return heatmapFactory;
});

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python面试题:在 Python 中,如何连接并操作数据库?
  • 开源项目有哪些机遇与挑战?
  • 老年人在日常生活中可以做哪些简单的伸展运动来缓解身体僵硬?
  • Linux 调试命令记录
  • python压缩PDF方案(Ghostscript+pdfc)
  • Git仓库介绍
  • Vue get请求传递数组,springboot接受数组(ai生成)
  • 【uniapp微信小程序】uniapp微信小程序——页面通信
  • ChatGPT对话:Scratch编程中一个单词,如balloon,每个字母行为一致,如何优化编程
  • 第2章 大话 ASP.NET Core 入门
  • Python | Leetcode Python题解之第225题用队列实现栈
  • 【高中数学/指数、对数】已知9^m=10,a=10^m-11,b=8^m-9,则ab两数和0的大小关系是?(2022年全国统考高考真题)
  • 架构师机器学习操作 (MLOps) 指南
  • OR-152 IGBT光耦系列
  • wpf中ComboBox属性text 绑定变量后画面上不显示值
  • php的引用
  • 0基础学习移动端适配
  • 77. Combinations
  • axios 和 cookie 的那些事
  • ERLANG 网工修炼笔记 ---- UDP
  • idea + plantuml 画流程图
  • rabbitmq延迟消息示例
  • Rancher如何对接Ceph-RBD块存储
  • Spring Cloud Feign的两种使用姿势
  • swift基础之_对象 实例方法 对象方法。
  • vuex 笔记整理
  • 从零开始学习部署
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 将回调地狱按在地上摩擦的Promise
  • 前端性能优化——回流与重绘
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 线上 python http server profile 实践
  • ​520就是要宠粉,你的心头书我买单
  • ​linux启动进程的方式
  • ​经​纬​恒​润​二​面​​三​七​互​娱​一​面​​元​象​二​面​
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • #07【面试问题整理】嵌入式软件工程师
  • #大学#套接字
  • ( 10 )MySQL中的外键
  • (145)光线追踪距离场柔和阴影
  • (BFS)hdoj2377-Bus Pass
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (附源码)计算机毕业设计ssm电影分享网站
  • (接口封装)
  • (九十四)函数和二维数组
  • (算法设计与分析)第一章算法概述-习题
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (转)c++ std::pair 与 std::make
  • (转)ORM
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • ./configure,make,make install的作用(转)
  • .NET Core引入性能分析引导优化
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • @angular/cli项目构建--Dynamic.Form
  • @Import注解详解