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

山海鲸引入天地图目前只有 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;
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/868882.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

神领物流项目第二天

文章目录 首先登录使用获取手机号码双token验证关于校验 首先登录使用 获取openid 获取openid 是在微信登录成功之后返回的信息中 有这个openid 那么第一步就是进行登录 登录是get请求,然后使用的参数有 appid 还有秘钥 还有登录code这个是前端获取的,前端调用登录接口 然后…

实时追踪与分析用户反馈:淘宝/天猫商品评论API的应用实践

实时追踪与分析用户反馈是电商平台提升用户体验、优化产品策略的重要手段。淘宝/天猫作为国内领先的电商平台&#xff0c;其商品评论API接口为商家提供了强大的数据支持&#xff0c;帮助商家实时追踪用户反馈并进行深入分析。以下是淘宝/天猫商品评论API在实时追踪与分析用户反…

推荐一款Win11主题WPF UI框架

最近在微软商店&#xff0c;官方上架了新款Win11风格的WPF版UI框架【WPF Gallery Preview 1.0.0.0】,这款应用引入了前沿的Fluent Design UI设计&#xff0c;为用户带来全新的视觉体验。 WPF Gallery简介 做为一关注前沿资讯的开发人员&#xff0c;首先关注的是应用WPF Gallery…

cloneable接口

Cloneable 接口是 Java 标准库中的一个标记接口&#xff0c;用于指示一个类的对象能够被合法地克隆。克隆是指创建一个对象的副本&#xff0c;即一个新的对象&#xff0c;其内容与原对象相同。Cloneable 接口本身没有方法&#xff0c;它只是一个标记&#xff0c;表示实现这个接…

HTML(27)——渐变

渐变是多个颜色逐渐变化的效果&#xff0c;一般用于设置盒子模型 线性渐变 属性&#xff1a;background-image : linear-gradient( 渐变方向 颜色1 终点位置, 颜色2 终点位置, ......&#xff09;&#xff1b; 取值: 渐变方向:可选 to 方位名词角度度数 终点位置:可选 百分…

Java语言+后端+前端Vue,ElementUI 数字化产科管理平台 产科电子病历系统源码

Java语言后端前端Vue,ElementUI 数字化产科管理平台 产科电子病历系统源码 Java开发的数字化产科管理系统&#xff0c;已在多家医院实施&#xff0c;支持直接部署。系统涵盖孕产全程&#xff0c;包括门诊、住院、统计和移动服务&#xff0c;整合高危管理、智能提醒、档案追踪等…

idea运行旧的项目如何引入jar包

背景: 有一个旧项目,年份不详, 生产环境运行正常, 生产环境jenkins打包正常;部分jar包为私包,已无法下载 现在要对这个项目进行调试修改 从生产环境下载正常的jar包解压找到lib把lib放到项目目录中 然后选者对应的jdk版本: 一个模块一个模块的 把刚才的库加进去 然后试着启…

Unity海面效果——5、水沫和海平线

Unity引擎制作海面效果 大家好&#xff0c;我是阿赵。 继续做海面效果&#xff0c;上次做完了漫反射颜色和水波动画&#xff0c;还有法线和高光效果。 原则上来说&#xff0c;这个海面已经基本能看了&#xff0c;从性能的考虑&#xff0c;到这里差不多可以停止了。不过有些细节…

error: ‘make_unique’ is not a member of ‘g2o’ 的参考解决方法

文章目录 写在前面一、问题描述二、解决方法 写在前面 自己的测试环境&#xff1a; Ubuntu20.04 一、问题描述 编译调用g2o的程序时&#xff0c;出现如下报错 error: ‘make_unique’ is not a member of ‘g2o’; did you mean ‘std::make_unique’?42 | auto s…

文章SameStr(四):图4代码

“Publication Figure 4” 百度云盘链接: https://pan.baidu.com/s/15g7caZp354zIWktpnWzWhQ 提取码: 4sh7 Libraries Standard Import library(tidyverse) library(cowplot) library(scales) library(ggpubr)Special library(caret) library(plotROC) library(tidymodel…

AIGC:为创意产业注入新质生产力

在当今数字化浪潮下&#xff0c;人工智能&#xff08;AI&#xff09;正以惊人的速度重塑着各行各业&#xff0c;特别是在创意产业领域&#xff0c;AI所带来的变革显得尤为深刻且广泛。 我深切感受到AIGC&#xff08;Artificial Intelligence Generated Content&#xff0c;即人…

几款常见的数字孪生引擎

Unity Unity 是一个通用的游戏引擎&#xff0c;广泛用于创建3D和2D的互动内容。它也被广泛用于数字孪生模型的开发。Unity提供了高效的图形处理能力、物理引擎和跨平台支持&#xff0c;使其成为构建交互式数字孪生模型的理想选择。 ②Unreal Engine Unreal Engine 是另一个流…

淘宝卖家难免遇到的商品问题 在淘宝买的东西出问题了,该如何维权

很多朋友对于淘宝卖家难免遇到的商品问题和在淘宝买的东西出问题了&#xff0c;该如何维权不太懂&#xff0c;今天就由小编来为大家分享&#xff0c;希望可以帮助到大家&#xff0c;下面一起来看看吧&#xff01; [1] 淘宝买东西&#xff0c;过了售后期&#xff0c;有质量问题怎…

gen_cross_contour_xld 为每个输入点生成一个十字形状的XLD轮廓。

gen_cross_contour_xld Name 名称 gen_cross_contour_xld — Generate one XLD contour in the shape of a cross for each input point. 为每个输入点生成一个十字形状的XLD轮廓。 Signature 签名 gen_cross_contour_xld( : Cross : Row, Col, Size, Angle : ) Descripti…

uniapp开发android调试工具

程序运行在真机后&#xff0c;点击Hbuilder菜单栏中的视图&#xff0c;点击下方的显示Webview调试控制台 下方就会展示你在手机端操作的界面 点击需要在电脑端调试的界面&#xff0c;界面会在新开的浏览器中展示&#xff0c;这样一些h5浏览器无法点击出来的样式就可以这样调试了…

【Java】搜索引擎设计:信息搜索怎么避免大海捞针?

一、内容分析 我们准备开发一个针对全网内容的搜索引擎&#xff0c;产品名称为“Bingoo”。 Bingoo的主要技术挑战包括&#xff1a; 针对爬虫获取的海量数据&#xff0c;如何高效地进行数据管理&#xff1b;当用户输入搜索词的时候&#xff0c;如何快速查找包含搜索词的网页…

PHP语言教程与实战案例详解

PHP是一种广泛使用的开源脚本语言&#xff0c;尤其适合Web开发并可嵌入HTML中。PHP语法吸收了C语言、Java和Perl的特点&#xff0c;易于学习&#xff0c;使用灵活&#xff0c;支持多种数据库&#xff0c;因此在Web开发领域中占据了重要地位。本文将从PHP的基本概念入手&#xf…

软件测试市场复苏了?

今年大家听到“就业大环境很差”、“工作不好找”之类的太多了。如今大环境已经逐渐好转&#xff0c;虽然不需要太过焦虑&#xff0c;但是也要持续的提升自己。 最近和几位准备跳槽的兄弟聊天发现&#xff0c;原有八股文已经不足以应对现在面试官的提问了。大厂对测试员的技术要…

零基础STM32单片机编程入门(十一) OLED显示屏实战含源码视频

文章目录 一.概要二.0.96寸OLED屏介绍1.OLED屏外观图2.OLED屏特点3.OLED屏接口定义4.OLED屏原理图5.OLED屏像素分辨率 三.字库取模软件PCtoLCD2002介绍四.STM32单片机驱动OLED显示实验五.CubeMX工程源代码下载六.讲解视频链接地址七.小结 一.概要 OLED被称为有机激光二极管显示…

二分查找(红绿标记法)

文章目录 1.线性查找2.二分查找2.1一般的二分查找2.2特殊的二分查找——红绿标记法2.3 原理解释&#xff1a;2.4 代码中的应用&#xff1a; 1.线性查找 线性查找&#xff08;Linear Search&#xff09;是一种简单直观的搜索算法&#xff0c;用于在数组中查找特定值的位置。它的…