@soonspacejs/plugin-heat-map 2.13.17 → 2.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CreateDrawing.d.ts +3 -4
- package/dist/index.d.ts +4 -5
- package/dist/index.esm.js +555 -1
- package/dist/tools.d.ts +1 -1
- package/package.json +3 -3
package/dist/CreateDrawing.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import SoonSpace from 'soonspacejs';
|
|
2
|
-
import
|
|
3
|
-
import HeatMapPlugin, { DrawingParam, ScenePolygonDataPoint, StoreValue, StoreValuePolygon } from '.';
|
|
1
|
+
import { default as SoonSpace, PluginObject } from 'soonspacejs';
|
|
2
|
+
import { default as HeatMapPlugin, DrawingParam, ScenePolygonDataPoint, StoreValue, StoreValuePolygon } from '.';
|
|
4
3
|
declare class CreateDrawing {
|
|
5
4
|
readonly heatMapPlugin: HeatMapPlugin;
|
|
6
|
-
readonly store: Map<string | number,
|
|
5
|
+
readonly store: Map<string | number, StoreValuePolygon | StoreValue>;
|
|
7
6
|
ssp: SoonSpace;
|
|
8
7
|
intervalId: number | null;
|
|
9
8
|
currentMouseEvent: MouseEvent | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Box2, Matrix4, Vector3 } from 'three';
|
|
2
|
-
import SoonSpace,
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import CreateDrawing from './CreateDrawing';
|
|
2
|
+
import { default as SoonSpace, IVector3, PlaneIVector2, SignalsState, PluginObject } from 'soonspacejs';
|
|
3
|
+
import { default as HeatMap, DataPoint } from 'heatmap-ts';
|
|
4
|
+
import { default as CreateDrawing } from './CreateDrawing';
|
|
6
5
|
export interface SceneDataPoint extends Omit<DataPoint, 'y'> {
|
|
7
6
|
z: number;
|
|
8
7
|
}
|
|
@@ -90,7 +89,7 @@ export interface StoreValuePolygon {
|
|
|
90
89
|
export default class HeatMapPlugin {
|
|
91
90
|
readonly ssp: SoonSpace;
|
|
92
91
|
hmInstance: HeatMap | null;
|
|
93
|
-
readonly store: Map<string | number,
|
|
92
|
+
readonly store: Map<string | number, StoreValuePolygon | StoreValue>;
|
|
94
93
|
constructor(ssp: SoonSpace);
|
|
95
94
|
maxCanvasSize: number;
|
|
96
95
|
create(param: CreateParam): PluginObject;
|
package/dist/index.esm.js
CHANGED
|
@@ -1 +1,555 @@
|
|
|
1
|
-
import{Matrix4 as t,Vector2 as e,Shape as i,ShapeGeometry as a,Box2 as n,Plane as s,Vector3 as r,Matrix3 as o,PlaneGeometry as h,CanvasTexture as d,MeshStandardMaterial as l,Mesh as c,Box3 as u,DoubleSide as p}from"three";"function"==typeof SuppressedError&&SuppressedError;var m={defaultRadius:40,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:{}},g=function(){function t(){this.eStore={}}return t.prototype.on=function(t,e,i){this.eStore[t]||(this.eStore[t]=[]),this.eStore[t].push(function(t){return e.call(i,t)})},t.prototype.emit=function(t,e){this.eStore[t]&&this.eStore[t].forEach(function(t){return t(e)})},t}(),v=function(){function t(t){this.coordinator=new g,this.data=[],this.radi=[],this.min=10,this.max=1,this.xField=t.xField||m.defaultXField,this.yField=t.yField||m.defaultYField,this.valueField=t.valueField||m.defaultValueField,this.radius=t.radius||m.defaultRadius}return t.prototype._organiseData=function(t,e){var i=t[this.xField],a=t[this.yField],n=this.radi,s=this.data,r=this.max,o=this.min,h=t[this.valueField]||1,d=t.radius||this.radius;n[i]||(s[i]=[],n[i]=[]),n[i][a]?s[i][a]+=h:(s[i][a]=h,n[i][a]=d);var l=s[i][a];return l?l>r?(e?this.setDataMax(l):this.max=l,!1):l<o?(e?this.setDataMin(l):this.min=l,!1):void 0:{x:i,y:a,value:h,radius:d,min:o,max:r}},t.prototype._unOrganizeData=function(){for(var t=[],e=0;e<this.radi.length;e++)for(var i=0;i<this.radi[e].length;i++)t.push({x:e,y:i,radius:this.radi[e][i],value:this.radi[e][i]});return{min:this.min,max:this.max,data:t}},t.prototype._onExtremaChange=function(){this.coordinator.emit("extremachange",{min:this.min,max:this.max})},t.prototype.addData=function(t){var e=this._organiseData(t,!0);e&&(0===this.data.length&&(this.min=e.value,this.max=e.value),this.coordinator.emit("renderpartial",{min:this.min,max:this.max,data:[e]}))},t.prototype.setData=function(t){var e=t.data;this.data=[],this.radi=[];for(var i=0;i<e.length;i++)this._organiseData(e[i],!1);return this.min=t.min||0,this.max=t.max||100,this._onExtremaChange(),this.coordinator.emit("renderall",this._getInternalData()),this},t.prototype.setDataMax=function(t){return this.max=t,this._onExtremaChange(),this.coordinator.emit("renderall",this._getInternalData()),this},t.prototype.setDataMin=function(t){return this.min=t,this._onExtremaChange(),this.coordinator.emit("renderall",this._getInternalData()),this},t.prototype._getInternalData=function(){return{max:this.max,min:this.min,data:this.data,radi:this.radi}},t.prototype.getData=function(){return this._unOrganizeData()},t}(),y=function(){function t(t){this.canvas=t.canvas||document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),this.shadowCanvas=t.shadowCanvas||document.createElement("canvas"),this.shadowCtx=this.shadowCanvas.getContext("2d"),this.width=t.width||512,this.height=t.height||512,this.max=100,this.min=1,this.blur=1,this.opacity=1,this.maxOpacity=1,this.minOpacity=0,this.useGradientOpacity=!1,this.canvas.style.cssText=this.shadowCanvas.style.cssText="position:absolute;left:0;top:0;",t.container&&(t.container.style.position="relative",t.container.appendChild(this.canvas)),this.renderBoundaries=[1e4,1e4,0,0],this.palette=this._getColorPalette(t),this.templates=[],this._setStyles(t)}return t.prototype.renderPartial=function(t){t.data.length>0&&(this._drawAlpha(t),this._colorize())},t.prototype.renderAll=function(t){this._clear(),t.data.length>0&&(this._drawAlpha(this._prepareData(t)),this._colorize())},t.prototype.updateConfig=function(t){t.gradient&&this._updateGradient(t),this._setStyles(t)},t.prototype.setDimensions=function(t,e){this.width=this.canvas.width=this.shadowCanvas.width=t,this.height=this.canvas.height=this.shadowCanvas.height=e},t.prototype.getValueAt=function(t){if(!this.shadowCtx)return 0;var e=this.shadowCtx.getImageData(t.x,t.y,1,1);return Math.abs(this.max-this.min)*(e.data[3]/255)|0},t.prototype.getDataURL=function(){return this.canvas.toDataURL()},t.prototype._getColorPalette=function(t){var e=t.gradient||m.defaultGradient,i=document.createElement("canvas"),a=i.getContext("2d");if(i.width=256,i.height=1,!a)return new Uint8ClampedArray(1024);var n=a.createLinearGradient(0,0,256,1);for(var s in e)n.addColorStop(Number(s),e[s]);return a.fillStyle=n,a.fillRect(0,0,256,1),a.getImageData(0,0,256,1).data},t.prototype._getPointTemplate=function(t,e){var i=document.createElement("canvas"),a=i.getContext("2d");if(!a)return i;var n=t,s=t;if(i.width=i.height=2*t,1===e)a.beginPath(),a.arc(n,s,t,0,2*Math.PI,!1),a.fillStyle="rgba(0,0,0,1)",a.fill();else{var r=a.createRadialGradient(n,s,t*e,n,s,t);r.addColorStop(0,"rgba(0,0,0,1)"),r.addColorStop(1,"rgba(0,0,0,0)"),a.fillStyle=r,a.fillRect(0,0,2*t,2*t)}return i},t.prototype._prepareData=function(t){for(var e=[],i=t.min,a=t.max,n=t.radi,s=t.data,r=Object.keys(s),o=r.length;o--;)for(var h=r[o],d=Object.keys(s[h]),l=d.length;l--;){var c=d[l],u=s[h][c],p=n[h][c];e.push({x:Number(h),y:Number(c),value:u,radius:p})}return{min:i,max:a,data:e}},t.prototype._setStyles=function(t){this.blur=0===t.blur?0:t.blur||m.defaultBlur,t.backgroundColor&&(this.canvas.style.backgroundColor=t.backgroundColor),this.width=this.canvas.width=this.shadowCanvas.width=t.width||this.width,this.height=this.canvas.height=this.shadowCanvas.height=t.height||this.height,this.opacity=255*(t.opacity||0),this.maxOpacity=255*(t.maxOpacity||m.defaultMaxOpacity),this.minOpacity=255*(t.minOpacity||m.defaultMinOpacity),this.useGradientOpacity=!!t.useGradientOpacity},t.prototype._updateGradient=function(t){this.palette=this._getColorPalette(t)},t.prototype._drawAlpha=function(t){for(var e=this.min=t.min||0,i=this.max=t.max||100,a=t.data||[],n=a.length,s=1-this.blur;n--;){var r=a[n],o=r.x,h=r.y,d=r.radius,l=Math.min(r.value,i),c=o-d,u=h-d;if(!this.shadowCtx)return;var p=void 0;this.templates[d]?p=this.templates[d]:this.templates[d]=p=this._getPointTemplate(d,s);var m=(l-e)/(i-e);this.shadowCtx.globalAlpha=m<.01?.01:m,this.shadowCtx.drawImage(p,c,u),c<this.renderBoundaries[0]&&(this.renderBoundaries[0]=c),u<this.renderBoundaries[1]&&(this.renderBoundaries[1]=u),c+2*d>this.renderBoundaries[2]&&(this.renderBoundaries[2]=c+2*d),u+2*d>this.renderBoundaries[3]&&(this.renderBoundaries[3]=u+2*d)}},t.prototype._colorize=function(){var t=this.renderBoundaries[0],e=this.renderBoundaries[1],i=this.renderBoundaries[2]-t,a=this.renderBoundaries[3]-e,n=this.width,s=this.height;if(t<0&&(t=0),e<0&&(e=0),t+i>n&&(i=n-t),e+a>s&&(a=s-e),this.ctx&&this.shadowCtx){for(var r=this.shadowCtx.getImageData(t,e,i,a),o=3;o<r.data.length;o+=4){var h,d=r.data[o],l=4*d;l&&(h=this.opacity>0?this.opacity:d<this.maxOpacity?d<this.minOpacity?this.minOpacity:d:this.maxOpacity,r.data[o-3]=this.palette[l],r.data[o-2]=this.palette[l+1],r.data[o-1]=this.palette[l+2],r.data[o]=this.useGradientOpacity?this.palette[l+3]:h)}this.ctx.putImageData(r,t,e),this.renderBoundaries=[1e3,1e3,0,0]}},t.prototype._clear=function(){this.ctx&&this.shadowCtx&&(this.ctx.clearRect(0,0,this.width,this.height),this.shadowCtx.clearRect(0,0,this.width,this.height))},t}(),f=function(){function t(t){this.config=t,this.renderer=new y(this.config),this.store=new v(this.config),this._init()}return t.prototype._init=function(){var t=this;this.store.coordinator.on("renderpartial",this.renderer.renderPartial,this.renderer),this.store.coordinator.on("renderall",this.renderer.renderAll,this.renderer),this.store.coordinator.on("extremachange",function(e){t.config.onExtremaChange&&t.config.onExtremaChange({min:e.min,max:e.max,gradient:t.config.gradient||m.defaultGradient})})},t.prototype.addData=function(t){return this.store.addData(t),this},t.prototype.setData=function(t){return this.store.setData(t),this},t.prototype.setDataMaxx=function(t){return this.store.setDataMax(t),this},t.prototype.setDataMin=function(t){return this.store.setDataMin(t),this},t.prototype.repaint=function(){return this.store.coordinator.emit("renderall",this.store._getInternalData()),this},t.prototype.getData=function(){return this.store.getData()},t.prototype.getDataURL=function(){return this.renderer.getDataURL()},t.prototype.getValueAt=function(t){return this.renderer.getValueAt(t)},t}();function x(h){const d=function(t){const[e,i,a]=t,n=new s;n.setFromCoplanarPoints(i,e,a);const h=n.normal,d=h.clone().cross(new r(0,0,1));d.equals(new r)&&d.set(1,0,0);const l=h.clone().cross(d);d.normalize(),l.normalize(),h.normalize();const c=new o;return c.elements=[d.x,d.y,d.z,l.x,l.y,l.z,h.x,h.y,h.z],c}(h),l=new t;l.setFromMatrix3(d);const c=h[0],u=l.clone();u.setPosition(c);const p=u.clone().invert(),m=h.map(t=>{const i=t.clone().applyMatrix4(p);return new e(i.x,i.y)}),g=new i(m),v=new a(g),y=new n;y.setFromPoints(m);const f=function(t){const i=t.min,a=t.getSize(new e),n=new o;return n.elements=[a.x,0,0,0,a.y,0,i.x,i.y,1],n.invert()}(y);return v.getAttribute("uv").applyMatrix3(f),v.applyMatrix4(l),{geometry:v,polygonBox:y,modelMatrix:l,planeMatrix:u,projectionMatrix:p,position:c}}function w(t,e,i,a,n,s){const{min:o,max:h,radius:d,beforePointUpdate:l,value:c,distanceInterval:u}=i,p=n.object,m=s.viewport.getIntersects(t,[p]);if(!((null==m?void 0:m.length)>0))return null;const g=m[0].point.clone();if(a.length>0&&u){const{x:t,y:e,z:i}=a[a.length-1];if(u>new r(t,e,i).distanceTo(g))return null}const v=Array.isArray(c)?function(t,e){if(t>=e)throw new Error("Min value must be less than max value.");return Math.floor(Math.random()*(e-t+1))+t}(c[0],c[1]):c,y=Object.assign(Object.assign({},g),{radius:d,value:v}),f=null==l?void 0:l(e,y,a);return!1===f?null:"object"==typeof f?f:y}class P{constructor(t,e){this.heatMapPlugin=t,this.store=new Map,this.intervalId=null,this.currentMouseEvent=null,this.events={},this.isDragging=!1,this.isStarting=!1,this.dataPoints=[],this.start=()=>{const{addTriggerType:t,doneTriggerType:e,undoTriggerType:i}=this.createDrawingParam;return new Promise((a,n)=>{this.startResolve=a,this.startReject=n,this.isStarting?console.warn("请先取消绘制再调用start方法"):(this.isStarting=!0,this.handleEventListeners("add",t,this.handleAddPoint),this.handleEventListeners("add",e,this.done),this.handleEventListeners("add",i,this.popPoint))})},this.cancel=()=>{var t;const{id:e}=this.createDrawingParam,i=[...this.dataPoints];this.heatMapPlugin.setDataPolygon(e,[]),this.remove(),null===(t=this.startReject)||void 0===t||t.call(this,i)},this.dispose=()=>{const{id:t}=this.createDrawingParam;this.remove(),this.heatMapPlugin.removeById(t)},this.done=()=>{var t;const e=[...this.dataPoints];this.remove(),null===(t=this.startResolve)||void 0===t||t.call(this,e)},this.remove=()=>{const{addTriggerType:t,doneTriggerType:e,undoTriggerType:i}=this.createDrawingParam;this.dataPoints=[],this.lastTime=void 0,this.setMouseEvent(null),this.handleEventListeners("remove",t,this.handleAddPoint),this.handleEventListeners("remove",e,this.done),this.handleEventListeners("remove",i,this.popPoint),this.events={},this.isDragging=!1,this.ssp.controls.enabled=!0,this.isStarting=!1},this.pushPoint=t=>{if(!t)return;const{id:e,onAdd:i}=this.createDrawingParam,a=t;this.dataPoints.push(a),this.heatMapPlugin.setDataPolygon(e,this.dataPoints),null==i||i(a,this.dataPoints)},this.popPoint=()=>{var t;const e=null===(t=this.dataPoints)||void 0===t?void 0:t.length;if(!(e>0))return;const{id:i,beforePointUpdate:a,onUndo:n}=this.createDrawingParam,s=null==a?void 0:a("undo",this.dataPoints[e-1],this.dataPoints);if(!1===s)return;"object"==typeof s&&(this.dataPoints[e-1]=s);const r=this.dataPoints.pop();r&&(this.heatMapPlugin.setDataPolygon(i,this.dataPoints),null==n||n(r,this.dataPoints))},this.handleAddPoint=t=>{if(!(null==t?void 0:t.clientX))throw new Error("addTriggerType仅支持:time、drag、click、dblClick、rightClick、mouseDown、mouseMove、mouseUp、mouseWheel");this.setMouseEvent(t);const e=this.getPoint(t,"add");this.pushPoint(e)},this.setMouseEvent=t=>{this.currentMouseEvent=t},this.handleEventListeners=(t,e,i)=>{(null==e?void 0:e.length)>0&&(e.forEach(e=>{var a,n,s,r;if("object"!=typeof e)if("time"!==e){if("drag"===e){const a=this.ssp.viewport.container,n=e;return void("add"===t?(this.events[n]=t=>{this.onPointerMove(i,t)},a.addEventListener("pointerdown",this.onPointerdown),a.addEventListener("pointermove",this.events[n]),a.addEventListener("pointerup",this.onPointerUp)):(a.removeEventListener("pointerdown",this.onPointerdown),a.removeEventListener("pointermove",this.events[n]),a.removeEventListener("pointerup",this.onPointerUp)))}null===(r=null===(s=this.ssp.signals[e])||void 0===s?void 0:s[t])||void 0===r||r.call(s,i)}else if("add"===t){const{timeInterval:t}=this.createDrawingParam||{};this.ssp.signals.mouseMove.add(this.setMouseEvent),this.intervalId=window.setInterval(()=>{this.currentMouseEvent&&i(this.currentMouseEvent)},t)}else this.ssp.signals.mouseMove.remove(this.setMouseEvent);else for(const[s,r]of Object.entries(e)){const e=`${s}_${r.join("_")}`;"add"===t&&(this.events[e]=t=>{this.keyEvents(r,i,t)}),null===(n=null===(a=this.ssp.signals[s])||void 0===a?void 0:a[t])||void 0===n||n.call(a,this.events[e])}}),"remove"===t&&this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null))},this.onPointerdown=t=>{this.ssp.controls.enabled=!1,this.isDragging=!0},this.onPointerMove=(t,e)=>{e.preventDefault(),this.isDragging&&t(e)},this.onPointerUp=t=>{this.isDragging=!1,this.ssp.controls.enabled=!0};const{data:i=[]}=e;this.ssp=t.ssp,this.store=t.store,this.createDrawingParam=e,this.dataPoints=[...i],this.object=t.createPolygon(e)}keyEvents(t,e,i){(null==t?void 0:t.includes(i.code))&&e()}getPoint(t,e){const{id:i,timeInterval:a=100}=this.createDrawingParam;if(this.lastTime&&a&&a>(new Date).getTime()-this.lastTime.getTime())return null;this.lastTime=new Date;const n=this.store.get(i);return w(t,e,this.createDrawingParam,this.dataPoints,n,this.ssp)}}class D{constructor(t){this.ssp=t,this.store=new Map,this.maxCanvasSize=512,this.hmInstance=null}create(t){const{id:e,name:i,yAxisHeight:a,minPosition:n,maxPosition:s,data:o,min:u=0,max:p=100,radius:m=100,canvasScalar:g=1}=t,v=new r((s.x+n.x)/2,a,(s.z+n.z)/2),y=s.x-n.x,f=s.z-n.z,x=this._formatCanvasSize(y*g,f*g),{canvas:w,hmInstance:P}=this.createInitData(Object.assign(Object.assign({},x),{radius:m}));P.setData({max:p,min:u,data:this._formatData(o,n,{width:y,height:f},x)});const D=new h(y,f),b=new d(w),C=new l({map:b,depthWrite:!1,transparent:!0}),M=new c(D,C),O=this.ssp.createPluginObject({id:e,name:i,position:v.clone(),rotation:{x:-Math.PI/2,y:0,z:0}},M);return this.store.set(e,{object:O,canvas:w,param:Object.assign(Object.assign({},t),{min:u,max:p}),width:y,height:f}),O}createPolygon(t){const{id:i,name:a,points:n,data:s,min:o=0,max:h=100,radius:c=100}=t,m=n.map(t=>new r(t.x,t.y,t.z)),{geometry:g,projectionMatrix:v,polygonBox:y,position:f}=x(m);(new u).setFromPoints(m);const{x:w,y:P}=y.getSize(new e),D=this._formatCanvasSize(w,P),{canvas:b,hmInstance:C}=this.createInitData(Object.assign(Object.assign({},D),{radius:c}));s&&s.length>0&&C.setData({max:h,min:o,data:this._formatData_Polygon(s,v,y,D)});const M=new d(b),O=new l({map:M,depthWrite:!1,transparent:!0,side:p}),_=new this.ssp.library.BaseMesh({id:`${i}_mesh`,name:a},g,O);_.renderOrder=0;const I=this.ssp.createPluginObject({id:i,name:a,position:f},_);return this.store.set(i,{object:I,canvas:b,param:Object.assign(Object.assign({},t),{min:o,max:h}),width:w,height:P,projectionMatrix:v,polygonBox:y,position:f.clone()}),I}createDrawing(t){const{data:e=[],addTriggerType:i=["click","mouseMove"],doneTriggerType:a=["dblClick",{keyDown:["Enter"]}],undoTriggerType:n=["rightClick",{keyDown:["Backspace"]}],timeInterval:s=100,min:r=0,max:o=100,radius:h=100,value:d=[r,o],distanceInterval:l=5}=t,c=function(t,e){var i={};for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&e.indexOf(a)<0&&(i[a]=t[a]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(a=Object.getOwnPropertySymbols(t);n<a.length;n++)e.indexOf(a[n])<0&&Object.prototype.propertyIsEnumerable.call(t,a[n])&&(i[a[n]]=t[a[n]])}return i}(t,["data","addTriggerType","doneTriggerType","undoTriggerType","timeInterval","min","max","radius","value","distanceInterval"]),u=Object.assign({data:e,addTriggerType:i,doneTriggerType:a,undoTriggerType:n,timeInterval:s,min:r,max:o,radius:h,value:d,distanceInterval:l},c);return new P(this,u)}setData(t,e){const i=this.store.get(t);if(i){const{object:t,canvas:a,param:{minPosition:n,min:s,max:r},width:o,height:h}=i,l=this.createInitData(),{canvas:c,hmInstance:u}=l;u.renderer.updateConfig({width:a.width,height:a.height}),u.setData({max:r,min:s,data:this._formatData(e,n,{width:o,height:h},this._formatCanvasSize(o,h))});const p=t.children[0].material;return this.ssp.render(()=>{const t=new d(c);p.map&&p.map.dispose(),p.map=t}),t}return console.warn(`In soonspacejs: 插件(plugin-heat-map)未找到 id 为 '"${t}"' 的热力图对象!`)}setDataPolygon(t,i){const a=this.store.get(t);if(a){const{object:n,canvas:s,param:{min:o,max:h},projectionMatrix:l,polygonBox:c,position:u}=a;if(!l)throw new Error(`${t} 不是多边形热力图类型`);const p=this.getById(t),m=null==p?void 0:p.getWorldPosition(new r),g=this.createInitData(),{canvas:v,hmInstance:y}=g;y.renderer.updateConfig({width:s.width,height:s.height});const f=c.getSize(new e);y.setData({max:h,min:o,data:this._formatData_Polygon(i,l,c,this._formatCanvasSize(f.x,f.y),u,m)});const x=n.children[0].material;return this.ssp.render(()=>{const t=new d(v);x.map&&x.map.dispose(),x.map=t}),n}return console.warn(`In soonspacejs: 插件(plugin-heat-map)未找到 id 为 '"${t}"' 的热力图对象!`)}getById(t){return this.ssp.getObjectById(t)}getByName(t){return this.ssp.getObjectByName(t)}removeById(t){return!!this.store.has(t)&&(this.ssp.removeObjectById(t),this.store.delete(t),!0)}createInitData(t){const e=this.hmInstance=new f(t||{});return{hmInstance:e,canvas:e.renderer.canvas}}_formatCanvasSize(t,e){const i=t/e;return t>this.maxCanvasSize&&(e=(t=this.maxCanvasSize)/i),e>this.maxCanvasSize&&(t=i*(e=this.maxCanvasSize)),{width:t,height:e}}_formatData(t,e,i,a){return t.map(t=>Object.assign(Object.assign({},t),{x:Math.trunc((t.x-e.x)/i.width*a.width),y:Math.trunc((t.z-e.z)/i.height*a.height)}))}_formatData_Polygon(t,i,a,n,s,o){const h=s&&o?o.clone().sub(s):new r(0,0,0);return t.map(t=>{const s=new r(t.x,t.y,t.z);s.sub(h),s.applyMatrix4(i);const{x:o,y:d}=a.getParameter(new e(s.x,s.y),new e);return Object.assign(Object.assign({},t),{x:Math.trunc(o*n.width),y:Math.trunc((1-d)*n.height)})})}}export{D as default};
|
|
1
|
+
import { Matrix4 as B, Vector2 as P, Shape as j, ShapeGeometry as T, Box2 as A, Plane as F, Vector3 as w, Matrix3 as O, PlaneGeometry as L, CanvasTexture as _, MeshStandardMaterial as z, Mesh as R, Box3 as k, DoubleSide as G } from "three";
|
|
2
|
+
var y = { defaultRadius: 40, defaultGradient: { 0.25: "rgb(0,0,255)", 0.55: "rgb(0,255,0)", 0.85: "yellow", 1: "rgb(255,0,0)" }, defaultMaxOpacity: 1, defaultMinOpacity: 0, defaultBlur: 0.85, defaultXField: "x", defaultYField: "y", defaultValueField: "value" }, U = (function() {
|
|
3
|
+
function s() {
|
|
4
|
+
this.eStore = {};
|
|
5
|
+
}
|
|
6
|
+
return s.prototype.on = function(t, e, a) {
|
|
7
|
+
this.eStore[t] || (this.eStore[t] = []), this.eStore[t].push((function(i) {
|
|
8
|
+
return e.call(a, i);
|
|
9
|
+
}));
|
|
10
|
+
}, s.prototype.emit = function(t, e) {
|
|
11
|
+
this.eStore[t] && this.eStore[t].forEach((function(a) {
|
|
12
|
+
return a(e);
|
|
13
|
+
}));
|
|
14
|
+
}, s;
|
|
15
|
+
})(), V = (function() {
|
|
16
|
+
function s(t) {
|
|
17
|
+
this.coordinator = new U(), this.data = [], this.radi = [], this.min = 10, this.max = 1, this.xField = t.xField || y.defaultXField, this.yField = t.yField || y.defaultYField, this.valueField = t.valueField || y.defaultValueField, this.radius = t.radius || y.defaultRadius;
|
|
18
|
+
}
|
|
19
|
+
return s.prototype._organiseData = function(t, e) {
|
|
20
|
+
var a = t[this.xField], i = t[this.yField], n = this.radi, r = this.data, o = this.max, h = this.min, d = t[this.valueField] || 1, c = t.radius || this.radius;
|
|
21
|
+
n[a] || (r[a] = [], n[a] = []), n[a][i] ? r[a][i] += d : (r[a][i] = d, n[a][i] = c);
|
|
22
|
+
var l = r[a][i];
|
|
23
|
+
return l ? l > o ? (e ? this.setDataMax(l) : this.max = l, !1) : l < h ? (e ? this.setDataMin(l) : this.min = l, !1) : void 0 : { x: a, y: i, value: d, radius: c, min: h, max: o };
|
|
24
|
+
}, s.prototype._unOrganizeData = function() {
|
|
25
|
+
for (var t = [], e = 0; e < this.radi.length; e++) for (var a = 0; a < this.radi[e].length; a++) t.push({ x: e, y: a, radius: this.radi[e][a], value: this.radi[e][a] });
|
|
26
|
+
return { min: this.min, max: this.max, data: t };
|
|
27
|
+
}, s.prototype._onExtremaChange = function() {
|
|
28
|
+
this.coordinator.emit("extremachange", { min: this.min, max: this.max });
|
|
29
|
+
}, s.prototype.addData = function(t) {
|
|
30
|
+
var e = this._organiseData(t, !0);
|
|
31
|
+
e && (this.data.length === 0 && (this.min = e.value, this.max = e.value), this.coordinator.emit("renderpartial", { min: this.min, max: this.max, data: [e] }));
|
|
32
|
+
}, s.prototype.setData = function(t) {
|
|
33
|
+
var e = t.data;
|
|
34
|
+
this.data = [], this.radi = [];
|
|
35
|
+
for (var a = 0; a < e.length; a++) this._organiseData(e[a], !1);
|
|
36
|
+
return this.min = t.min || 0, this.max = t.max || 100, this._onExtremaChange(), this.coordinator.emit("renderall", this._getInternalData()), this;
|
|
37
|
+
}, s.prototype.setDataMax = function(t) {
|
|
38
|
+
return this.max = t, this._onExtremaChange(), this.coordinator.emit("renderall", this._getInternalData()), this;
|
|
39
|
+
}, s.prototype.setDataMin = function(t) {
|
|
40
|
+
return this.min = t, this._onExtremaChange(), this.coordinator.emit("renderall", this._getInternalData()), this;
|
|
41
|
+
}, s.prototype._getInternalData = function() {
|
|
42
|
+
return { max: this.max, min: this.min, data: this.data, radi: this.radi };
|
|
43
|
+
}, s.prototype.getData = function() {
|
|
44
|
+
return this._unOrganizeData();
|
|
45
|
+
}, s;
|
|
46
|
+
})(), N = (function() {
|
|
47
|
+
function s(t) {
|
|
48
|
+
this.canvas = t.canvas || document.createElement("canvas"), this.ctx = this.canvas.getContext("2d"), this.shadowCanvas = t.shadowCanvas || document.createElement("canvas"), this.shadowCtx = this.shadowCanvas.getContext("2d"), this.width = t.width || 512, this.height = t.height || 512, this.max = 100, this.min = 1, this.blur = 1, this.opacity = 1, this.maxOpacity = 1, this.minOpacity = 0, this.useGradientOpacity = !1, this.canvas.style.cssText = this.shadowCanvas.style.cssText = "position:absolute;left:0;top:0;", t.container && (t.container.style.position = "relative", t.container.appendChild(this.canvas)), this.renderBoundaries = [1e4, 1e4, 0, 0], this.palette = this._getColorPalette(t), this.templates = [], this._setStyles(t);
|
|
49
|
+
}
|
|
50
|
+
return s.prototype.renderPartial = function(t) {
|
|
51
|
+
t.data.length > 0 && (this._drawAlpha(t), this._colorize());
|
|
52
|
+
}, s.prototype.renderAll = function(t) {
|
|
53
|
+
this._clear(), t.data.length > 0 && (this._drawAlpha(this._prepareData(t)), this._colorize());
|
|
54
|
+
}, s.prototype.updateConfig = function(t) {
|
|
55
|
+
t.gradient && this._updateGradient(t), this._setStyles(t);
|
|
56
|
+
}, s.prototype.setDimensions = function(t, e) {
|
|
57
|
+
this.width = this.canvas.width = this.shadowCanvas.width = t, this.height = this.canvas.height = this.shadowCanvas.height = e;
|
|
58
|
+
}, s.prototype.getValueAt = function(t) {
|
|
59
|
+
if (!this.shadowCtx) return 0;
|
|
60
|
+
var e = this.shadowCtx.getImageData(t.x, t.y, 1, 1);
|
|
61
|
+
return Math.abs(this.max - this.min) * (e.data[3] / 255) >> 0;
|
|
62
|
+
}, s.prototype.getDataURL = function() {
|
|
63
|
+
return this.canvas.toDataURL();
|
|
64
|
+
}, s.prototype._getColorPalette = function(t) {
|
|
65
|
+
var e = t.gradient || y.defaultGradient, a = document.createElement("canvas"), i = a.getContext("2d");
|
|
66
|
+
if (a.width = 256, a.height = 1, !i) return new Uint8ClampedArray(1024);
|
|
67
|
+
var n = i.createLinearGradient(0, 0, 256, 1);
|
|
68
|
+
for (var r in e) n.addColorStop(Number(r), e[r]);
|
|
69
|
+
return i.fillStyle = n, i.fillRect(0, 0, 256, 1), i.getImageData(0, 0, 256, 1).data;
|
|
70
|
+
}, s.prototype._getPointTemplate = function(t, e) {
|
|
71
|
+
var a = document.createElement("canvas"), i = a.getContext("2d");
|
|
72
|
+
if (!i) return a;
|
|
73
|
+
var n = t, r = t;
|
|
74
|
+
if (a.width = a.height = 2 * t, e === 1) i.beginPath(), i.arc(n, r, t, 0, 2 * Math.PI, !1), i.fillStyle = "rgba(0,0,0,1)", i.fill();
|
|
75
|
+
else {
|
|
76
|
+
var o = i.createRadialGradient(n, r, t * e, n, r, t);
|
|
77
|
+
o.addColorStop(0, "rgba(0,0,0,1)"), o.addColorStop(1, "rgba(0,0,0,0)"), i.fillStyle = o, i.fillRect(0, 0, 2 * t, 2 * t);
|
|
78
|
+
}
|
|
79
|
+
return a;
|
|
80
|
+
}, s.prototype._prepareData = function(t) {
|
|
81
|
+
for (var e = [], a = t.min, i = t.max, n = t.radi, r = t.data, o = Object.keys(r), h = o.length; h--; ) for (var d = o[h], c = Object.keys(r[d]), l = c.length; l--; ) {
|
|
82
|
+
var p = c[l], u = r[d][p], m = n[d][p];
|
|
83
|
+
e.push({ x: Number(d), y: Number(p), value: u, radius: m });
|
|
84
|
+
}
|
|
85
|
+
return { min: a, max: i, data: e };
|
|
86
|
+
}, s.prototype._setStyles = function(t) {
|
|
87
|
+
this.blur = t.blur === 0 ? 0 : t.blur || y.defaultBlur, t.backgroundColor && (this.canvas.style.backgroundColor = t.backgroundColor), this.width = this.canvas.width = this.shadowCanvas.width = t.width || this.width, this.height = this.canvas.height = this.shadowCanvas.height = t.height || this.height, this.opacity = 255 * (t.opacity || 0), this.maxOpacity = 255 * (t.maxOpacity || y.defaultMaxOpacity), this.minOpacity = 255 * (t.minOpacity || y.defaultMinOpacity), this.useGradientOpacity = !!t.useGradientOpacity;
|
|
88
|
+
}, s.prototype._updateGradient = function(t) {
|
|
89
|
+
this.palette = this._getColorPalette(t);
|
|
90
|
+
}, s.prototype._drawAlpha = function(t) {
|
|
91
|
+
for (var e = this.min = t.min || 0, a = this.max = t.max || 100, i = t.data || [], n = i.length, r = 1 - this.blur; n--; ) {
|
|
92
|
+
var o = i[n], h = o.x, d = o.y, c = o.radius, l = Math.min(o.value, a), p = h - c, u = d - c;
|
|
93
|
+
if (!this.shadowCtx) return;
|
|
94
|
+
var m = void 0;
|
|
95
|
+
this.templates[c] ? m = this.templates[c] : this.templates[c] = m = this._getPointTemplate(c, r);
|
|
96
|
+
var g = (l - e) / (a - e);
|
|
97
|
+
this.shadowCtx.globalAlpha = g < 0.01 ? 0.01 : g, this.shadowCtx.drawImage(m, p, u), p < this.renderBoundaries[0] && (this.renderBoundaries[0] = p), u < this.renderBoundaries[1] && (this.renderBoundaries[1] = u), p + 2 * c > this.renderBoundaries[2] && (this.renderBoundaries[2] = p + 2 * c), u + 2 * c > this.renderBoundaries[3] && (this.renderBoundaries[3] = u + 2 * c);
|
|
98
|
+
}
|
|
99
|
+
}, s.prototype._colorize = function() {
|
|
100
|
+
var t = this.renderBoundaries[0], e = this.renderBoundaries[1], a = this.renderBoundaries[2] - t, i = this.renderBoundaries[3] - e, n = this.width, r = this.height;
|
|
101
|
+
if (t < 0 && (t = 0), e < 0 && (e = 0), t + a > n && (a = n - t), e + i > r && (i = r - e), this.ctx && this.shadowCtx) {
|
|
102
|
+
for (var o = this.shadowCtx.getImageData(t, e, a, i), h = 3; h < o.data.length; h += 4) {
|
|
103
|
+
var d, c = o.data[h], l = 4 * c;
|
|
104
|
+
l && (d = this.opacity > 0 ? this.opacity : c < this.maxOpacity ? c < this.minOpacity ? this.minOpacity : c : this.maxOpacity, o.data[h - 3] = this.palette[l], o.data[h - 2] = this.palette[l + 1], o.data[h - 1] = this.palette[l + 2], o.data[h] = this.useGradientOpacity ? this.palette[l + 3] : d);
|
|
105
|
+
}
|
|
106
|
+
this.ctx.putImageData(o, t, e), this.renderBoundaries = [1e3, 1e3, 0, 0];
|
|
107
|
+
}
|
|
108
|
+
}, s.prototype._clear = function() {
|
|
109
|
+
this.ctx && this.shadowCtx && (this.ctx.clearRect(0, 0, this.width, this.height), this.shadowCtx.clearRect(0, 0, this.width, this.height));
|
|
110
|
+
}, s;
|
|
111
|
+
})(), $ = (function() {
|
|
112
|
+
function s(t) {
|
|
113
|
+
this.config = t, this.renderer = new N(this.config), this.store = new V(this.config), this._init();
|
|
114
|
+
}
|
|
115
|
+
return s.prototype._init = function() {
|
|
116
|
+
var t = this;
|
|
117
|
+
this.store.coordinator.on("renderpartial", this.renderer.renderPartial, this.renderer), this.store.coordinator.on("renderall", this.renderer.renderAll, this.renderer), this.store.coordinator.on("extremachange", (function(e) {
|
|
118
|
+
t.config.onExtremaChange && t.config.onExtremaChange({ min: e.min, max: e.max, gradient: t.config.gradient || y.defaultGradient });
|
|
119
|
+
}));
|
|
120
|
+
}, s.prototype.addData = function(t) {
|
|
121
|
+
return this.store.addData(t), this;
|
|
122
|
+
}, s.prototype.setData = function(t) {
|
|
123
|
+
return this.store.setData(t), this;
|
|
124
|
+
}, s.prototype.setDataMaxx = function(t) {
|
|
125
|
+
return this.store.setDataMax(t), this;
|
|
126
|
+
}, s.prototype.setDataMin = function(t) {
|
|
127
|
+
return this.store.setDataMin(t), this;
|
|
128
|
+
}, s.prototype.repaint = function() {
|
|
129
|
+
return this.store.coordinator.emit("renderall", this.store._getInternalData()), this;
|
|
130
|
+
}, s.prototype.getData = function() {
|
|
131
|
+
return this.store.getData();
|
|
132
|
+
}, s.prototype.getDataURL = function() {
|
|
133
|
+
return this.renderer.getDataURL();
|
|
134
|
+
}, s.prototype.getValueAt = function(t) {
|
|
135
|
+
return this.renderer.getValueAt(t);
|
|
136
|
+
}, s;
|
|
137
|
+
})();
|
|
138
|
+
function W(s) {
|
|
139
|
+
const t = H(s), e = new B();
|
|
140
|
+
e.setFromMatrix3(t);
|
|
141
|
+
const a = s[0], i = e.clone();
|
|
142
|
+
i.setPosition(a);
|
|
143
|
+
const n = i.clone().invert(), r = s.map((p) => {
|
|
144
|
+
const u = p.clone().applyMatrix4(n);
|
|
145
|
+
return new P(u.x, u.y);
|
|
146
|
+
}), o = new j(r), h = new T(o), d = new A();
|
|
147
|
+
d.setFromPoints(r);
|
|
148
|
+
const c = X(d);
|
|
149
|
+
return h.getAttribute("uv").applyMatrix3(c), h.applyMatrix4(e), { geometry: h, polygonBox: d, modelMatrix: e, planeMatrix: i, projectionMatrix: n, position: a };
|
|
150
|
+
}
|
|
151
|
+
function H(s) {
|
|
152
|
+
const [t, e, a] = s, i = new F();
|
|
153
|
+
i.setFromCoplanarPoints(e, t, a);
|
|
154
|
+
const n = i.normal, r = n.clone().cross(new w(0, 0, 1));
|
|
155
|
+
r.equals(new w()) && r.set(1, 0, 0);
|
|
156
|
+
const o = n.clone().cross(r);
|
|
157
|
+
r.normalize(), o.normalize(), n.normalize();
|
|
158
|
+
const h = new O();
|
|
159
|
+
return h.elements = [
|
|
160
|
+
r.x,
|
|
161
|
+
r.y,
|
|
162
|
+
r.z,
|
|
163
|
+
o.x,
|
|
164
|
+
o.y,
|
|
165
|
+
o.z,
|
|
166
|
+
n.x,
|
|
167
|
+
n.y,
|
|
168
|
+
n.z
|
|
169
|
+
], h;
|
|
170
|
+
}
|
|
171
|
+
function X(s) {
|
|
172
|
+
const t = s.min, e = s.getSize(new P()), a = new O();
|
|
173
|
+
return a.elements = [
|
|
174
|
+
e.x,
|
|
175
|
+
0,
|
|
176
|
+
0,
|
|
177
|
+
0,
|
|
178
|
+
e.y,
|
|
179
|
+
0,
|
|
180
|
+
t.x,
|
|
181
|
+
t.y,
|
|
182
|
+
1
|
|
183
|
+
], a.invert();
|
|
184
|
+
}
|
|
185
|
+
function K(s, t) {
|
|
186
|
+
if (s >= t)
|
|
187
|
+
throw new Error("Min value must be less than max value.");
|
|
188
|
+
return Math.floor(Math.random() * (t - s + 1)) + s;
|
|
189
|
+
}
|
|
190
|
+
function Y(s, t, e, a, i, n) {
|
|
191
|
+
const {
|
|
192
|
+
min: r,
|
|
193
|
+
max: o,
|
|
194
|
+
radius: h,
|
|
195
|
+
beforePointUpdate: d,
|
|
196
|
+
value: c,
|
|
197
|
+
distanceInterval: l
|
|
198
|
+
} = e, p = i.object, u = n.viewport.getIntersects(s, [p]);
|
|
199
|
+
if (!(u?.length > 0))
|
|
200
|
+
return null;
|
|
201
|
+
const m = u[0].point.clone();
|
|
202
|
+
if (a.length > 0 && l) {
|
|
203
|
+
const { x, y: D, z: M } = a[a.length - 1], C = new w(x, D, M);
|
|
204
|
+
if (l > C.distanceTo(m))
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
const g = Array.isArray(c) ? K(c[0], c[1]) : c, v = { ...m, radius: h, value: g }, f = d?.(t, v, a);
|
|
208
|
+
return f === !1 ? null : typeof f == "object" ? f : v;
|
|
209
|
+
}
|
|
210
|
+
class q {
|
|
211
|
+
constructor(t, e) {
|
|
212
|
+
this.heatMapPlugin = t;
|
|
213
|
+
const { data: a = [] } = e;
|
|
214
|
+
this.ssp = t.ssp, this.store = t.store, this.createDrawingParam = e, this.dataPoints = [...a], this.object = t.createPolygon(e);
|
|
215
|
+
}
|
|
216
|
+
store = /* @__PURE__ */ new Map();
|
|
217
|
+
ssp;
|
|
218
|
+
// 用时间形式加热力点
|
|
219
|
+
intervalId = null;
|
|
220
|
+
// 存储鼠标当前所在点事件
|
|
221
|
+
currentMouseEvent = null;
|
|
222
|
+
// 最后一次获取热力点的时间,用于节流
|
|
223
|
+
lastTime;
|
|
224
|
+
// 绑定事件
|
|
225
|
+
events = {};
|
|
226
|
+
// 拖拽
|
|
227
|
+
isDragging = !1;
|
|
228
|
+
// 开始绘制
|
|
229
|
+
isStarting = !1;
|
|
230
|
+
createDrawingParam;
|
|
231
|
+
// 所有热力点
|
|
232
|
+
dataPoints = [];
|
|
233
|
+
// 热力图实例
|
|
234
|
+
object;
|
|
235
|
+
startResolve;
|
|
236
|
+
startReject;
|
|
237
|
+
// 开始绘制热力点 绑定事件
|
|
238
|
+
start = () => {
|
|
239
|
+
const { addTriggerType: t, doneTriggerType: e, undoTriggerType: a } = this.createDrawingParam;
|
|
240
|
+
return new Promise((i, n) => {
|
|
241
|
+
if (this.startResolve = i, this.startReject = n, this.isStarting) {
|
|
242
|
+
console.warn("请先取消绘制再调用start方法");
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
this.isStarting = !0, this.handleEventListeners("add", t, this.handleAddPoint), this.handleEventListeners("add", e, this.done), this.handleEventListeners("add", a, this.popPoint);
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
// 取消
|
|
249
|
+
cancel = () => {
|
|
250
|
+
const { id: t } = this.createDrawingParam, e = [...this.dataPoints];
|
|
251
|
+
this.heatMapPlugin.setDataPolygon(t, []), this.remove(), this.startReject?.(e);
|
|
252
|
+
};
|
|
253
|
+
// 销毁
|
|
254
|
+
dispose = () => {
|
|
255
|
+
const { id: t } = this.createDrawingParam;
|
|
256
|
+
this.remove(), this.heatMapPlugin.removeById(t);
|
|
257
|
+
};
|
|
258
|
+
// 完成
|
|
259
|
+
done = () => {
|
|
260
|
+
const t = [...this.dataPoints];
|
|
261
|
+
this.remove(), this.startResolve?.(t);
|
|
262
|
+
};
|
|
263
|
+
// 移除监听
|
|
264
|
+
remove = () => {
|
|
265
|
+
const { addTriggerType: t, doneTriggerType: e, undoTriggerType: a } = this.createDrawingParam;
|
|
266
|
+
this.dataPoints = [], this.lastTime = void 0, this.setMouseEvent(null), this.handleEventListeners("remove", t, this.handleAddPoint), this.handleEventListeners("remove", e, this.done), this.handleEventListeners("remove", a, this.popPoint), this.events = {}, this.isDragging = !1, this.ssp.controls.enabled = !0, this.isStarting = !1;
|
|
267
|
+
};
|
|
268
|
+
// 增加热力点
|
|
269
|
+
pushPoint = (t) => {
|
|
270
|
+
if (!t)
|
|
271
|
+
return;
|
|
272
|
+
const { id: e, onAdd: a } = this.createDrawingParam, i = t;
|
|
273
|
+
this.dataPoints.push(i), this.heatMapPlugin.setDataPolygon(e, this.dataPoints), a?.(i, this.dataPoints);
|
|
274
|
+
};
|
|
275
|
+
// 删除上一个热力点
|
|
276
|
+
popPoint = () => {
|
|
277
|
+
const t = this.dataPoints?.length;
|
|
278
|
+
if (!(t > 0))
|
|
279
|
+
return;
|
|
280
|
+
const { id: e, beforePointUpdate: a, onUndo: i } = this.createDrawingParam, n = a?.(E.undo, this.dataPoints[t - 1], this.dataPoints);
|
|
281
|
+
if (n === !1)
|
|
282
|
+
return;
|
|
283
|
+
typeof n == "object" && (this.dataPoints[t - 1] = n);
|
|
284
|
+
const r = this.dataPoints.pop();
|
|
285
|
+
r && (this.heatMapPlugin.setDataPolygon(e, this.dataPoints), i?.(r, this.dataPoints));
|
|
286
|
+
};
|
|
287
|
+
handleAddPoint = (t) => {
|
|
288
|
+
if (!t?.clientX)
|
|
289
|
+
throw new Error("addTriggerType仅支持:time、drag、click、dblClick、rightClick、mouseDown、mouseMove、mouseUp、mouseWheel");
|
|
290
|
+
this.setMouseEvent(t);
|
|
291
|
+
const e = this.getPoint(t, E.add);
|
|
292
|
+
this.pushPoint(e);
|
|
293
|
+
};
|
|
294
|
+
// 设置鼠标事件
|
|
295
|
+
setMouseEvent = (t) => {
|
|
296
|
+
this.currentMouseEvent = t;
|
|
297
|
+
};
|
|
298
|
+
handleEventListeners = (t, e, a) => {
|
|
299
|
+
e?.length > 0 && (e.forEach((i) => {
|
|
300
|
+
if (typeof i == "object") {
|
|
301
|
+
for (const [n, r] of Object.entries(i)) {
|
|
302
|
+
const o = `${n}_${r.join("_")}`;
|
|
303
|
+
t === "add" && (this.events[o] = (h) => {
|
|
304
|
+
this.keyEvents(r, a, h);
|
|
305
|
+
}), this.ssp.signals[n]?.[t]?.(this.events[o]);
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
if (i === "time") {
|
|
310
|
+
if (t === "add") {
|
|
311
|
+
const { timeInterval: n } = this.createDrawingParam || {};
|
|
312
|
+
this.ssp.signals.mouseMove.add(this.setMouseEvent), this.intervalId = window.setInterval(() => {
|
|
313
|
+
this.currentMouseEvent && a(this.currentMouseEvent);
|
|
314
|
+
}, n);
|
|
315
|
+
} else
|
|
316
|
+
this.ssp.signals.mouseMove.remove(this.setMouseEvent);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (i === "drag") {
|
|
320
|
+
const n = this.ssp.viewport.container, r = i;
|
|
321
|
+
t === "add" ? (this.events[r] = (o) => {
|
|
322
|
+
this.onPointerMove(a, o);
|
|
323
|
+
}, n.addEventListener("pointerdown", this.onPointerdown), n.addEventListener("pointermove", this.events[r]), n.addEventListener("pointerup", this.onPointerUp)) : (n.removeEventListener("pointerdown", this.onPointerdown), n.removeEventListener("pointermove", this.events[r]), n.removeEventListener("pointerup", this.onPointerUp));
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
this.ssp.signals[i]?.[t]?.(a);
|
|
327
|
+
}), t === "remove" && this.intervalId && (clearInterval(this.intervalId), this.intervalId = null));
|
|
328
|
+
};
|
|
329
|
+
keyEvents(t, e, a) {
|
|
330
|
+
t?.includes(a.code) && e();
|
|
331
|
+
}
|
|
332
|
+
// 通过鼠标事件获取热力点
|
|
333
|
+
getPoint(t, e) {
|
|
334
|
+
const { id: a, timeInterval: i = 100 } = this.createDrawingParam;
|
|
335
|
+
if (this.lastTime && i && i > (/* @__PURE__ */ new Date()).getTime() - this.lastTime.getTime())
|
|
336
|
+
return null;
|
|
337
|
+
this.lastTime = /* @__PURE__ */ new Date();
|
|
338
|
+
const n = this.store.get(a);
|
|
339
|
+
return Y(t, e, this.createDrawingParam, this.dataPoints, n, this.ssp);
|
|
340
|
+
}
|
|
341
|
+
onPointerdown = (t) => {
|
|
342
|
+
this.ssp.controls.enabled = !1, this.isDragging = !0;
|
|
343
|
+
};
|
|
344
|
+
onPointerMove = (t, e) => {
|
|
345
|
+
e.preventDefault(), this.isDragging && t(e);
|
|
346
|
+
};
|
|
347
|
+
onPointerUp = (t) => {
|
|
348
|
+
this.isDragging = !1, this.ssp.controls.enabled = !0;
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
var E = /* @__PURE__ */ ((s) => (s.add = "add", s.undo = "undo", s))(E || {});
|
|
352
|
+
class Q {
|
|
353
|
+
constructor(t) {
|
|
354
|
+
this.ssp = t, this.hmInstance = null;
|
|
355
|
+
}
|
|
356
|
+
hmInstance;
|
|
357
|
+
store = /* @__PURE__ */ new Map();
|
|
358
|
+
maxCanvasSize = 512;
|
|
359
|
+
create(t) {
|
|
360
|
+
const {
|
|
361
|
+
id: e,
|
|
362
|
+
name: a,
|
|
363
|
+
yAxisHeight: i,
|
|
364
|
+
minPosition: n,
|
|
365
|
+
maxPosition: r,
|
|
366
|
+
data: o,
|
|
367
|
+
min: h = 0,
|
|
368
|
+
max: d = 100,
|
|
369
|
+
radius: c = 100,
|
|
370
|
+
canvasScalar: l = 1
|
|
371
|
+
} = t, p = new w((r.x + n.x) / 2, i, (r.z + n.z) / 2), u = r.x - n.x, m = r.z - n.z, g = this._formatCanvasSize(u * l, m * l), { canvas: v, hmInstance: f } = this.createInitData({ ...g, radius: c });
|
|
372
|
+
f.setData({
|
|
373
|
+
max: d,
|
|
374
|
+
min: h,
|
|
375
|
+
data: this._formatData(o, n, { width: u, height: m }, g)
|
|
376
|
+
});
|
|
377
|
+
const x = new L(u, m), D = new _(v), M = new z({
|
|
378
|
+
map: D,
|
|
379
|
+
depthWrite: !1,
|
|
380
|
+
transparent: !0
|
|
381
|
+
}), C = new R(x, M), b = this.ssp.createPluginObject({
|
|
382
|
+
id: e,
|
|
383
|
+
name: a,
|
|
384
|
+
position: p.clone(),
|
|
385
|
+
rotation: {
|
|
386
|
+
x: -Math.PI / 2,
|
|
387
|
+
y: 0,
|
|
388
|
+
z: 0
|
|
389
|
+
}
|
|
390
|
+
}, C);
|
|
391
|
+
return this.store.set(e, {
|
|
392
|
+
object: b,
|
|
393
|
+
canvas: v,
|
|
394
|
+
param: { ...t, min: h, max: d },
|
|
395
|
+
width: u,
|
|
396
|
+
height: m
|
|
397
|
+
}), b;
|
|
398
|
+
}
|
|
399
|
+
createPolygon(t) {
|
|
400
|
+
const {
|
|
401
|
+
id: e,
|
|
402
|
+
name: a,
|
|
403
|
+
points: i,
|
|
404
|
+
data: n,
|
|
405
|
+
min: r = 0,
|
|
406
|
+
max: o = 100,
|
|
407
|
+
radius: h = 100
|
|
408
|
+
} = t, d = i.map((I) => new w(I.x, I.y, I.z)), { geometry: c, projectionMatrix: l, polygonBox: p, position: u } = W(d);
|
|
409
|
+
new k().setFromPoints(d);
|
|
410
|
+
const { x: g, y: v } = p.getSize(new P()), f = this._formatCanvasSize(g, v), { canvas: x, hmInstance: D } = this.createInitData({ ...f, radius: h });
|
|
411
|
+
n && n.length > 0 && D.setData({
|
|
412
|
+
max: o,
|
|
413
|
+
min: r,
|
|
414
|
+
data: this._formatData_Polygon(n, l, p, f)
|
|
415
|
+
});
|
|
416
|
+
const M = new _(x), C = new z({
|
|
417
|
+
map: M,
|
|
418
|
+
depthWrite: !1,
|
|
419
|
+
transparent: !0,
|
|
420
|
+
side: G
|
|
421
|
+
}), b = new this.ssp.library.BaseMesh({ id: `${e}_mesh`, name: a }, c, C);
|
|
422
|
+
b.renderOrder = 0;
|
|
423
|
+
const S = this.ssp.createPluginObject({
|
|
424
|
+
id: e,
|
|
425
|
+
name: a,
|
|
426
|
+
position: u
|
|
427
|
+
}, b);
|
|
428
|
+
return this.store.set(e, {
|
|
429
|
+
object: S,
|
|
430
|
+
canvas: x,
|
|
431
|
+
param: { ...t, min: r, max: o },
|
|
432
|
+
width: g,
|
|
433
|
+
height: v,
|
|
434
|
+
projectionMatrix: l,
|
|
435
|
+
polygonBox: p,
|
|
436
|
+
position: u.clone()
|
|
437
|
+
}), S;
|
|
438
|
+
}
|
|
439
|
+
createDrawing(t) {
|
|
440
|
+
const {
|
|
441
|
+
data: e = [],
|
|
442
|
+
addTriggerType: a = ["click", "mouseMove"],
|
|
443
|
+
doneTriggerType: i = ["dblClick", { keyDown: ["Enter"] }],
|
|
444
|
+
undoTriggerType: n = ["rightClick", { keyDown: ["Backspace"] }],
|
|
445
|
+
timeInterval: r = 100,
|
|
446
|
+
min: o = 0,
|
|
447
|
+
max: h = 100,
|
|
448
|
+
radius: d = 100,
|
|
449
|
+
value: c = [o, h],
|
|
450
|
+
distanceInterval: l = 5,
|
|
451
|
+
...p
|
|
452
|
+
} = t, u = {
|
|
453
|
+
data: e,
|
|
454
|
+
addTriggerType: a,
|
|
455
|
+
doneTriggerType: i,
|
|
456
|
+
undoTriggerType: n,
|
|
457
|
+
timeInterval: r,
|
|
458
|
+
min: o,
|
|
459
|
+
max: h,
|
|
460
|
+
radius: d,
|
|
461
|
+
value: c,
|
|
462
|
+
distanceInterval: l,
|
|
463
|
+
...p
|
|
464
|
+
};
|
|
465
|
+
return new q(this, u);
|
|
466
|
+
}
|
|
467
|
+
setData(t, e) {
|
|
468
|
+
const a = this.store.get(t);
|
|
469
|
+
if (a) {
|
|
470
|
+
const { object: i, canvas: n, param: { minPosition: r, min: o, max: h }, width: d, height: c } = a, l = this.createInitData(), { canvas: p, hmInstance: u } = l;
|
|
471
|
+
u.renderer.updateConfig({
|
|
472
|
+
width: n.width,
|
|
473
|
+
height: n.height
|
|
474
|
+
}), u.setData({
|
|
475
|
+
max: h,
|
|
476
|
+
min: o,
|
|
477
|
+
data: this._formatData(e, r, { width: d, height: c }, this._formatCanvasSize(d, c))
|
|
478
|
+
});
|
|
479
|
+
const m = i.children[0].material;
|
|
480
|
+
return this.ssp.render(() => {
|
|
481
|
+
const g = new _(p);
|
|
482
|
+
m.map && m.map.dispose(), m.map = g;
|
|
483
|
+
}), i;
|
|
484
|
+
} else
|
|
485
|
+
return console.warn(`In soonspacejs: 插件(plugin-heat-map)未找到 id 为 '"${t}"' 的热力图对象!`);
|
|
486
|
+
}
|
|
487
|
+
setDataPolygon(t, e) {
|
|
488
|
+
const a = this.store.get(t);
|
|
489
|
+
if (a) {
|
|
490
|
+
const { object: i, canvas: n, param: { min: r, max: o }, projectionMatrix: h, polygonBox: d, position: c } = a;
|
|
491
|
+
if (!h) throw new Error(`${t} 不是多边形热力图类型`);
|
|
492
|
+
const p = this.getById(t)?.getWorldPosition(new w()), u = this.createInitData(), { canvas: m, hmInstance: g } = u;
|
|
493
|
+
g.renderer.updateConfig({
|
|
494
|
+
width: n.width,
|
|
495
|
+
height: n.height
|
|
496
|
+
});
|
|
497
|
+
const v = d.getSize(new P());
|
|
498
|
+
g.setData({
|
|
499
|
+
max: o,
|
|
500
|
+
min: r,
|
|
501
|
+
data: this._formatData_Polygon(e, h, d, this._formatCanvasSize(v.x, v.y), c, p)
|
|
502
|
+
});
|
|
503
|
+
const f = i.children[0].material;
|
|
504
|
+
return this.ssp.render(() => {
|
|
505
|
+
const x = new _(m);
|
|
506
|
+
f.map && f.map.dispose(), f.map = x;
|
|
507
|
+
}), i;
|
|
508
|
+
} else
|
|
509
|
+
return console.warn(`In soonspacejs: 插件(plugin-heat-map)未找到 id 为 '"${t}"' 的热力图对象!`);
|
|
510
|
+
}
|
|
511
|
+
getById(t) {
|
|
512
|
+
return this.ssp.getObjectById(t);
|
|
513
|
+
}
|
|
514
|
+
getByName(t) {
|
|
515
|
+
return this.ssp.getObjectByName(t);
|
|
516
|
+
}
|
|
517
|
+
removeById(t) {
|
|
518
|
+
return this.store.has(t) ? (this.ssp.removeObjectById(t), this.store.delete(t), !0) : !1;
|
|
519
|
+
}
|
|
520
|
+
createInitData(t) {
|
|
521
|
+
const e = this.hmInstance = new $(t || {});
|
|
522
|
+
return { hmInstance: e, canvas: e.renderer.canvas };
|
|
523
|
+
}
|
|
524
|
+
_formatCanvasSize(t, e) {
|
|
525
|
+
const a = t / e;
|
|
526
|
+
return t > this.maxCanvasSize && (t = this.maxCanvasSize, e = t / a), e > this.maxCanvasSize && (e = this.maxCanvasSize, t = a * e), { width: t, height: e };
|
|
527
|
+
}
|
|
528
|
+
_formatData(t, e, a, i) {
|
|
529
|
+
return t.map((n) => ({
|
|
530
|
+
...n,
|
|
531
|
+
// 取整,否则不生效
|
|
532
|
+
x: Math.trunc((n.x - e.x) / a.width * i.width),
|
|
533
|
+
y: Math.trunc((n.z - e.z) / a.height * i.height)
|
|
534
|
+
}));
|
|
535
|
+
}
|
|
536
|
+
_formatData_Polygon(t, e, a, i, n, r) {
|
|
537
|
+
const o = n && r ? r.clone().sub(n) : new w(0, 0, 0);
|
|
538
|
+
return t.map((h) => {
|
|
539
|
+
const d = new w(h.x, h.y, h.z);
|
|
540
|
+
d.sub(o), d.applyMatrix4(e);
|
|
541
|
+
const { x: c, y: l } = a.getParameter(new P(d.x, d.y), new P());
|
|
542
|
+
return {
|
|
543
|
+
...h,
|
|
544
|
+
// 取整,否则不生效
|
|
545
|
+
x: Math.trunc(c * i.width),
|
|
546
|
+
// 热力图图片的 y 轴的正方向是 从 图片上方 到 图片 下方
|
|
547
|
+
y: Math.trunc((1 - l) * i.height)
|
|
548
|
+
};
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
export {
|
|
553
|
+
E as StartEventType,
|
|
554
|
+
Q as default
|
|
555
|
+
};
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import SoonSpace from 'soonspacejs';
|
|
1
|
+
import { default as SoonSpace } from 'soonspacejs';
|
|
2
2
|
import { Matrix3, Vector3, Box2, Matrix4, ShapeGeometry } from 'three';
|
|
3
3
|
import { DrawingParam, ScenePolygonDataPoint, StartEventType, StoreValuePolygon } from '.';
|
|
4
4
|
export declare function getPolygonGeometryInfo(points: Vector3[]): {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soonspacejs/plugin-heat-map",
|
|
3
3
|
"pluginName": "HeatMapPlugin",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.14.1",
|
|
5
5
|
"description": "Haet-map plugin for SoonSpace.js",
|
|
6
6
|
"main": "dist/index.esm.js",
|
|
7
7
|
"module": "dist/index.esm.js",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"heatmap-ts": "^0.0.4"
|
|
18
18
|
},
|
|
19
|
-
"gitHead": "
|
|
19
|
+
"gitHead": "27d5e0bcd79ff71c8e2943a8420c39624ae6f8e6",
|
|
20
20
|
"peerDependencies": {
|
|
21
|
-
"soonspacejs": "2.
|
|
21
|
+
"soonspacejs": "2.14.1"
|
|
22
22
|
}
|
|
23
23
|
}
|