当前位置: 首页 > 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;
});

相关文章:

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

山海鲸引入天地图目前只有 iframe 的方式引入 首先我们创建一个文件夹 ——index.html ——index.js ——data.js 大家都是大佬&#xff0c;我就不详细介绍了&#xff0c;上代码都能看得懂 首先是index.html <!DOCTYPE html> <html lang"zh-CN"> <…...

Python 利用pandas处理CSV文件(DataFrame的基础用法)

前面介绍过通过Python标准库中的CSV模块处理CSV文件&#xff1a; Python 利用CSV模块处理数据 相比CSV模块&#xff0c;pandas的功能更加强大&#xff0c;本文将简单介绍如何通过pandas来处理CSV文件。 文章目录 一、pandas简介二、用法示例2.1 读取CSV文件2.1.1 read_csv参数…...

c++ 的(引用)和*(指针)

在C中&#xff0c;&&#xff08;引用&#xff09;和*&#xff08;指针&#xff09;在函数参数中的使用有各自的特点和用途。下面是它们的具体使用方式以及它们之间的一些区别&#xff1a; 引用&#xff08;&&#xff09; 使用方式: 引用作为函数参数时&#xff0c;可…...

人工智能算法工程师(中级)课程6-sklearn机器学习之聚类问题与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程6-sklearn机器学习之聚类问题与代码详解。在机器学习领域&#xff0c;聚类是一种无监督学习方法&#xff0c;旨在将相似的数据点划分为同一类别。sklearn是一个广泛应用于机器学习的Py…...

Objective-C 中的 isa 不再是简单的结构体指针

了解 Objective-C 中的 isa 指针内存结构 在 Objective-C 中&#xff0c;isa 指针是对象和类之间的重要桥梁。它不仅帮助运行时系统识别对象的类型&#xff0c;还参与了一些内存和性能优化。本文将深入讲解 isa 指针的内存结构&#xff0c;包括其在早期和现代实现中的演变。 …...

中介子方程五十二

XXFXXaXnXaXXαXLXyXXWXuXeXKXXiXyXΣXXΣXXVXuXhXXWXηXXiXhXXpXiXXpXXbXXpXXiXpXXhXiXXηXWXXhXuXVXXΣXXΣXyXiXXKXeXuXWXXyXLXαXXaXnXaXXFXXaXnXaXXαXLXyXXWXuXeXKXXiXyXΣXXΣXXVXuXhXXWXηXXiXhXXpXiXXpXXbXXpXXiXpXXhXiXXηXWXXhXuXVXXΣXXΣXyXiXXKXeXuXWXXyXLXαXXa…...

LabVIEW在半导体自动化测试中的应用

半导体制造的复杂性和精密度要求极高&#xff0c;每一个生产步骤都需要严格的控制和监测。自动化测试设备在半导体制造中起到了关键作用&#xff0c;通过精密测量和数据分析&#xff0c;确保产品质量和生产效率。本文介绍如何使用LabVIEW结合研华硬件&#xff0c;开发一个用于半…...

政安晨:【Keras机器学习示例演绎】(五十三)—— 使用 TensorFlow 决策森林进行分类

目录 简介 设置 准备数据 定义数据集元数据 配置超参数 实施培训和评估程序 实验 1&#xff1a;使用原始特征的决策森林 检查模型 实验 2&#xff1a;目标编码决策森林 创建模型输入 使用目标编码实现特征编码 使用预处理器创建梯度提升树模型 训练和评估模型 实验…...

51单片机:电脑通过串口控制LED亮灭(附溢出率和波特率详解)

一、功能实现 1.电脑通过串口发送数据&#xff1a;0F 2.点亮4个LED 二、注意事项 1.发送和接受数据的文本模式 2.串口要对应 3.注意串口的波特率要和程序中的波特率保持一致 4.有无校验位和停止位 三、如何使用串口波特率计算器 1.以本程序为例 2.生成代码如下 void Uar…...

Java中的消息中间件选择与比较

Java中的消息中间件选择与比较 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在分布式系统中&#xff0c;消息中间件是一种关键组件&#xff0c;它能帮助不同…...

react基础语法,模板语法,ui渲染,jsx,useState状态管理

创建一个react应用 这里使用create-react-app的脚手架构建项目&#xff08;结构简洁&#xff0c;基于webpack-cli&#xff09;&#xff0c; npx create-react-app [项目名称] 使用其他脚手架构建项目可以参考&#xff1a;react框架&#xff0c;使用vite和nextjs构建react项目…...

OJ-0710

示例1 input 4 100 200 300 5001 21 32 4output700100 200 500 300 示例2 input 4 100 200 300 500 1 2 1 3 1 4output1100100 200500300 示例3 input 6 100 200 300 400 300 550 1 2 1 3 1 4 2 5 2 6output1050100 200 300600 300400 import java.util.ArrayList; im…...

人工智能在自动驾驶中的目标检测研究

摘要 随着自动驾驶技术的快速发展&#xff0c;视觉识别作为核心技术之一&#xff0c;扮演着至关重要的角色。本文旨在探讨人工智能如何通过视觉识别在自动驾驶中进行目标检测。我们将详细讨论目标检测的基本原理、常用算法、最新进展、已有的开源项目及其在自动驾驶中的应用和…...

【合并两个有序数组】

合并两个有序数组 一、题目二、普通解法三、双指针 一、题目 二、普通解法 先合并后排序 补充:js合并数组方法详见https://blog.csdn.net/ACCPluzhiqi/article/details/131702269?fromshareblogdetail js排序方法见http://t.csdnimg.cn/wVCOP 时间复杂度&#xff1a;O(mn)…...

链表 OJ(一)

移除链表元素 题目连接&#xff1a; https://leetcode.cn/problems/remove-linked-list-elements/description/ 使用双指针法&#xff0c;开始时&#xff0c;一个指针指向头节点&#xff0c;另一个指针指向头节点的下一个结点&#xff0c;然后开始遍历链表删除结点。 这里要注…...

《Linux与Windows文件系统的区别》

Linux与Windows文件系统的区别 在计算机操作系统领域&#xff0c;Linux和Windows是两种广泛使用的操作系统&#xff0c;它们在文件系统方面有许多显著的差异。这篇博客将详细介绍这两种操作系统文件系统的区别&#xff0c;帮助读者更好地理解它们各自的特点和优势。 类别Linu…...

批量修改Git历史commit信息中的username

之前很长一段时间GitHub上的提交都在使用工作账户, 导致私人仓库中的提交者比较混乱. 在StackOver里面找到了一个bash脚本可以批量修改username, 在这里记录一下. 修改的步骤一共两步: 执行修改脚本将本地修改同步到Git服务器 首先我们来看脚本: #!/bin/shgit filter-branch…...

LabVIEW与ABB工业机器人据监控

​1. 前言 随着工业自动化的发展&#xff0c;工业机器人在制造业中的应用越来越广泛。为了实现对工业机器人的高效监控和控制&#xff0c;本文介绍了利用OPC&#xff08;OLE for Process Control&#xff09;服务器将ABB工业机器人与LabVIEW连接起来的解决方案。通过OPC服务器…...

c++栈内存和堆内存的基本使用

c栈内存和堆内存的基本使用 #include <iostream>// 定义一个简单的结构体 struct Person {std::string name;int age; };int main() {// 栈内存分配int a 10; // 基本数据类型的栈内存分配Person person; // 结构体的栈内存分配person.name "John";person.a…...

快速入门,springboot知识点汇总

学习 springboot 应该像学习一门编程语言一样&#xff0c;首先要熟练掌握常用的知识&#xff0c;而对于不常用的内容可以简单了解一下。先对整个框架和语言有一个大致的轮廓&#xff0c;然后再逐步补充细节。 前序: Spring Boot 通过简化配置和提供开箱即用的特性&#xff0c…...

Ubuntu20.04系统非root用户安装GAMIT10.71

&#xff08;测试环境&#xff1a;20240701升级包和20240701数据&#xff0c;解算通过&#xff09; QQ:8212714 群&#xff1a;302883438群文件&#xff08;source安装包20240701升级包&#xff09; 1、首先在计算机中安装VMware Workstation 16 Pro。建议&#xff1a;分配…...

stm32 开发板可以拿来做什么?

STM32开发板可以用来做许多不同的事情&#xff0c;具体取决于您的应用需求和编程能力。我收集归类了一份嵌入式学习包&#xff0c;对于新手而言简直不要太棒&#xff0c;里面包括了新手各个时期的学习方向编程教学、问题视频讲解、毕设800套和语言类教学&#xff0c;敲个22就可…...

latex英文转中文word,及一些latex相关工具分享

前言&#xff1a;想要转换latex生成的英文pdf文件为中文word文件 一、主要步骤 1、文字翻译&#xff1a;直接使用谷歌翻译等辅助将英文翻译成中文即可&#xff1b; 支持英文pdf文件全文翻译&#xff0c;再用迅捷PDF转换器之类的转成word&#xff0c;再手动调整。 https://app…...

EasyOCR: 简单易用的多语言OCR工具

EasyOCR: 简单易用的多语言OCR工具 1. 什么是EasyOCR?2. 使用场景3. 基本使用方法安装示例代码代码解释 4. 结语 1. 什么是EasyOCR? EasyOCR是一个基于Python的开源光学字符识别(OCR)工具,它支持80多种语言的文本识别。该项目由JaidedAI开发,旨在提供一个简单易用但功能强大…...

arm架构安装chrome

在ARM架构设备上安装谷歌软件或应用通常涉及到几个步骤&#xff0c;这取决于你要安装的具体谷歌产品&#xff0c;比如谷歌浏览器、Google Play服务或者是其他谷歌开发的软件。下面我会给出一些常见的指导步骤&#xff0c;以安装谷歌浏览器为例&#xff1a; 在Linux ARM64上安装…...

ETAS工具导入Com Arxml修改步骤

文章目录 前言Confgen之前的更改Confgen之后的修改CANCanIfComComMEcuM修改CanNmCanSMDCMCanTp生成RTE过程报错修改DEXT-诊断文件修改Extract问题总结前言 通讯协议栈开发一般通过导入DBC实现,ETAS工具本身导入DBC也是生成arxml后执行cfggen,本文介绍直接导入客户提供的arxml…...

Apache Kylin模型构建全解析:深入理解大数据的多维分析

引言 Apache Kylin是一个开源的分布式分析引擎&#xff0c;旨在为大数据提供快速的多维分析能力。它通过预计算技术&#xff0c;将数据转化为立方体模型&#xff08;Cube&#xff09;&#xff0c;从而实现对Hadoop大数据集的秒级查询响应。本文将详细介绍Kylin中模型构建的全过…...

element-plus的文件上传组件el-upload

el-upload组件 支持多种风格&#xff0c;如文件列表&#xff0c;图片&#xff0c;图片卡片&#xff0c;支持多种事件&#xff0c;预览&#xff0c;删除&#xff0c;上传成功&#xff0c;上传中等钩子。 file-list&#xff1a;上传的文件集合&#xff0c;一定要用v-model:file-…...

等保测评视角下的哈尔滨智慧城市安全框架构建

随着智慧城市的兴起&#xff0c;哈尔滨作为东北地区的重要城市&#xff0c;正在积极探索和实践智慧城市安全框架的构建&#xff0c;以确保在数字化转型的过程中&#xff0c;既能享受科技带来的便利&#xff0c;又能有效防范和应对各类网络安全风险。 本文将从等保测评的视角出…...

Java中的数据缓存技术及其应用

Java中的数据缓存技术及其应用 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在现代应用程序中&#xff0c;数据缓存是一种重要的技术手段&#xff0c;用于提…...

网站流量提升/网站提交入口大全

真实案例&#xff1a;查看nginx日志&#xff0c;发现别有用心的人恶意调用API接口刷短信&#xff1a;30966487 115.213.229.38 "-" [05/Jun/2018:14:37:29 0800] 0.003 xxxxxx.com "POST /xxx/sendCheckCode HTTP/1.1" 401 200 46 xx.xx.xx.xx:0000 0.003 …...

网站开发的图片要求/广告公司推广软文

2018.05.05_day111、执行Python脚本的两种方式 第一种&#xff0c;在命令行输入“python 文件名” 第二种&#xff0c;从解释器打开脚本文件&#xff0c;并运行。2、简述位、字节的关系 位是计算机存储的最小单位&#xff0c;一个位要么是“0”要么是“1”&#xff0c;8个位等于…...

wordpress 显示微博内容/福州网站建设团队

os包是操作文件和目录的包。io的接口Reader&#xff0c;用于从数据源中读取数据并将数据转换成字节流&#xff0c;Writer接口字节流中读取数据&#xff0c;并将数据作为输出写入目标数据源。创建空文件结果&#xff1a;C:golangworking-with-files>go fmt example1.goC:gola…...

做网站备案不少天/专业软文发布平台

相同点&#xff0c;使用drop delete truncate 都会删除表中的内容drop table 表名delete from 表名(后面不跟where语句&#xff0c;则也删除表中所有的数据)truncate table 表名区别首先delete 属于DML&#xff0c;当不commit时时不生效的而truncate 和 drop 则是直接生效的&am…...

做陶瓷的公司网站/站长之家权重

卷积&#xff0c;池化&#xff0c;特征图&#xff0c;实战&#xff1a; LeNet-5分层解析&#xff1a; MLP原理&#xff1a; 较为全面的DL: RBF: RBF课件&#xff1a; BP算法&#xff1a; 感受野&#xff1a;转载于:https://www.cnblogs.com/maggie94/p/6742900.html...

江门市网站建设/一句话让客户主动找你

Enabling the capability for Photo Video Camera 启用相机能力 为了使用摄像头&#xff0c;我们必须启用WebCam能力。 在Unity中打开Player settings展开Windows Store标签页在"Publishing Settings > Capabilities"部分勾选WebCam能力同一时刻只能执行一次相机操…...