easy-three-utils 0.0.364 → 0.0.366
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/cesium/assets/image/fastForward.png +0 -0
- package/cesium/assets/image/rewind.png +0 -0
- package/cesium/components/react/SunshineLine/index.tsx +2 -3
- package/cesium/components/react/Timeline/index.module.less +19 -6
- package/cesium/components/react/Timeline/index.tsx +64 -41
- package/cesium/config/cesium.config.ts +8 -6
- package/cesium/glsl/viewable.ts +2 -2
- package/cesium/index.ts +10 -14
- package/cesium/utils/index.ts +2 -0
- package/cesium/utils/useHeatmap.ts +179 -0
- package/cesium/utils/usePath.d.ts +26 -0
- package/cesium/utils/usePath.js +68 -0
- package/package.json +2 -2
- package/cesium/components/react/image/pause.png +0 -0
- package/cesium/components/react/image/play.png +0 -0
- package/cesium/components/react/image/stop.png +0 -0
- package/cesium/utils/lib/heatmap.js +0 -701
|
Binary file
|
|
Binary file
|
|
@@ -36,11 +36,10 @@ const SunshineLine: React.FC<{
|
|
|
36
36
|
|
|
37
37
|
getViewer().scene.light = new Cesium.DirectionalLight({
|
|
38
38
|
direction: dir,
|
|
39
|
-
intensity
|
|
40
|
-
})
|
|
39
|
+
intensity
|
|
40
|
+
})
|
|
41
41
|
}, [azimuth, elevation, intensity])
|
|
42
42
|
|
|
43
|
-
|
|
44
43
|
const sliderBoxRef = useRef(null)
|
|
45
44
|
useEffect(() => {
|
|
46
45
|
sliderBoxRef.current.style.bottom = `calc(-100vh + ${sliderBoxRef.current.clientHeight + 20}px)`
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
.slider-box {
|
|
2
|
-
position:
|
|
2
|
+
position: relative;
|
|
3
3
|
z-index: 2;
|
|
4
|
-
|
|
5
|
-
width: 360px;
|
|
4
|
+
width: 400px;
|
|
6
5
|
padding: 10px;
|
|
7
6
|
background: rgba(6, 38, 68, 0.7);
|
|
8
7
|
border: solid 1px #26a1ff;
|
|
9
8
|
display: flex;
|
|
10
|
-
left: calc(50vw -
|
|
9
|
+
left: calc(50vw - 200px);
|
|
11
10
|
|
|
12
11
|
.left-content {
|
|
13
12
|
color: white;
|
|
14
|
-
font-size:
|
|
13
|
+
font-size: 14px;
|
|
15
14
|
writing-mode: vertical-rl;
|
|
16
15
|
display: flex;
|
|
17
16
|
justify-content: center;
|
|
@@ -23,7 +22,7 @@
|
|
|
23
22
|
|
|
24
23
|
.time-text {
|
|
25
24
|
color: white;
|
|
26
|
-
font-size:
|
|
25
|
+
font-size: 13px;
|
|
27
26
|
display: flex;
|
|
28
27
|
justify-content: flex-end;
|
|
29
28
|
width: 98%;
|
|
@@ -38,6 +37,20 @@
|
|
|
38
37
|
img {
|
|
39
38
|
padding: 0 12px;
|
|
40
39
|
cursor: pointer;
|
|
40
|
+
width: 30px;
|
|
41
|
+
height: 30px;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.control-input {
|
|
46
|
+
width: 70px;
|
|
47
|
+
color: white;
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
font-size: 14px;
|
|
51
|
+
|
|
52
|
+
input {
|
|
53
|
+
margin-right: 4px;
|
|
41
54
|
}
|
|
42
55
|
}
|
|
43
56
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
|
2
|
-
import { Slider, ConfigProvider } from "antd";
|
|
1
|
+
import React, { useEffect, useState, useRef } from "react";
|
|
2
|
+
import { Slider, ConfigProvider, Input } from "antd";
|
|
3
3
|
import * as Cesium from "cesium";
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
5
|
import duration from 'dayjs/plugin/duration';
|
|
6
|
+
import BodyPortal from "../Body";
|
|
6
7
|
|
|
7
8
|
import Styles from './index.module.less'
|
|
8
9
|
|
|
@@ -14,6 +15,7 @@ const Timeline: React.FC<{
|
|
|
14
15
|
|
|
15
16
|
const { getViewer } = props
|
|
16
17
|
const [percent, setPercent] = useState(0)
|
|
18
|
+
let lastUpdate = 0
|
|
17
19
|
|
|
18
20
|
const theme = {
|
|
19
21
|
components: {
|
|
@@ -25,7 +27,22 @@ const Timeline: React.FC<{
|
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
const formatTimeStamp = (timestamp: number) => {
|
|
31
|
+
const d = dayjs.duration(timestamp)
|
|
32
|
+
|
|
33
|
+
const days = Math.floor(d.asDays())
|
|
34
|
+
const hours = d.hours().toString().length === 1 ? `0${d.hours()}` : d.hours()
|
|
35
|
+
const minutes = d.minutes().toString().length === 1 ? `0${d.minutes()}` : d.minutes()
|
|
36
|
+
const seconds = d.seconds().toString().length === 1 ? `0${d.seconds()}` : d.seconds()
|
|
37
|
+
|
|
38
|
+
return `${days}天 ${hours}:${minutes}:${seconds}`
|
|
39
|
+
}
|
|
40
|
+
|
|
28
41
|
const setClockEvent = (clock: Cesium.Clock) => {
|
|
42
|
+
const now = Date.now()
|
|
43
|
+
if (now - lastUpdate < 500) return
|
|
44
|
+
lastUpdate = now
|
|
45
|
+
|
|
29
46
|
const totalSeconds = Cesium.JulianDate.secondsDifference(
|
|
30
47
|
clock.stopTime,
|
|
31
48
|
clock.startTime
|
|
@@ -35,12 +52,9 @@ const Timeline: React.FC<{
|
|
|
35
52
|
clock.startTime
|
|
36
53
|
)
|
|
37
54
|
|
|
38
|
-
|
|
39
|
-
const formattedTime = timeDuration.format('HH:mm:ss')
|
|
40
|
-
setCurrentTime(() => formattedTime)
|
|
41
|
-
|
|
55
|
+
setCurrentTime(() => formatTimeStamp(elapsedSeconds * 1000))
|
|
42
56
|
const newPercent = (elapsedSeconds / totalSeconds) * 100
|
|
43
|
-
setPercent(() => newPercent)
|
|
57
|
+
setPercent(() => newPercent)
|
|
44
58
|
}
|
|
45
59
|
|
|
46
60
|
const addViewerClockEvent = () => {
|
|
@@ -48,11 +62,11 @@ const Timeline: React.FC<{
|
|
|
48
62
|
}
|
|
49
63
|
|
|
50
64
|
const removeViewerClockEvent = () => {
|
|
51
|
-
getViewer().clock.onTick.
|
|
65
|
+
getViewer().clock.onTick.removeEventListener(setClockEvent)
|
|
52
66
|
}
|
|
53
67
|
|
|
54
68
|
const onSliderChange = (value: number) => {
|
|
55
|
-
setPercent(() => value)
|
|
69
|
+
setPercent(() => value)
|
|
56
70
|
const totalSeconds = Cesium.JulianDate.secondsDifference(
|
|
57
71
|
getViewer().clock.stopTime,
|
|
58
72
|
getViewer().clock.startTime
|
|
@@ -62,7 +76,7 @@ const Timeline: React.FC<{
|
|
|
62
76
|
(value / 100) * totalSeconds,
|
|
63
77
|
new Cesium.JulianDate()
|
|
64
78
|
)
|
|
65
|
-
getViewer().clock.currentTime = newTime
|
|
79
|
+
getViewer().clock.currentTime = newTime
|
|
66
80
|
}
|
|
67
81
|
|
|
68
82
|
type TContronType = 'pause' | 'play' | 'stop'
|
|
@@ -79,17 +93,17 @@ const Timeline: React.FC<{
|
|
|
79
93
|
}
|
|
80
94
|
}
|
|
81
95
|
|
|
82
|
-
const [totalTime, setTotalTime] = useState('
|
|
83
|
-
const [currentTime, setCurrentTime] = useState('
|
|
96
|
+
const [totalTime, setTotalTime] = useState('')
|
|
97
|
+
const [currentTime, setCurrentTime] = useState('')
|
|
84
98
|
const initTimeDisplay = () => {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
const formattedTime = timeDuration.format('HH:mm:ss')
|
|
88
|
-
setTotalTime(() => formattedTime)
|
|
99
|
+
const timestamp = Cesium.JulianDate.toDate(getViewer().clock.stopTime).getTime() - Cesium.JulianDate.toDate(getViewer().clock.startTime).getTime()
|
|
100
|
+
setTotalTime(() => formatTimeStamp(timestamp))
|
|
89
101
|
}
|
|
90
102
|
|
|
103
|
+
const [speed, setSpeed] = useState(1)
|
|
104
|
+
const sliderBoxRef = useRef(null)
|
|
91
105
|
useEffect(() => {
|
|
92
|
-
|
|
106
|
+
sliderBoxRef.current.style.bottom = `calc(-100vh + ${sliderBoxRef.current.clientHeight + 20}px)`
|
|
93
107
|
addViewerClockEvent()
|
|
94
108
|
initTimeDisplay()
|
|
95
109
|
|
|
@@ -99,33 +113,42 @@ const Timeline: React.FC<{
|
|
|
99
113
|
}, [])
|
|
100
114
|
|
|
101
115
|
return (
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<div className={Styles['
|
|
107
|
-
|
|
108
|
-
|
|
116
|
+
<BodyPortal>
|
|
117
|
+
<ConfigProvider theme={{
|
|
118
|
+
...theme
|
|
119
|
+
}}>
|
|
120
|
+
<div ref={sliderBoxRef} className={Styles['slider-box']}>
|
|
121
|
+
<div className={Styles['left-content']}>
|
|
122
|
+
推演控制
|
|
123
|
+
</div>
|
|
109
124
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
<div className={Styles['right-content']}>
|
|
126
|
+
<Slider
|
|
127
|
+
min={0}
|
|
128
|
+
max={100}
|
|
129
|
+
step={0.1}
|
|
130
|
+
value={percent}
|
|
131
|
+
onChange={(value: number) => onSliderChange(value)}
|
|
132
|
+
/>
|
|
133
|
+
<div className={Styles['time-text']}>{currentTime}/{totalTime}</div>
|
|
134
|
+
<div className={Styles['control-btn']}>
|
|
135
|
+
{
|
|
136
|
+
(['rewind', 'pause', 'play', 'stop', 'fastForward'] as TContronType[]).map(item =>
|
|
137
|
+
<img key={item} onClick={() => control[item]()} src={(window as any).__POLT__URL__ + `/assets/image/${item}.png`} />
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
<div className={Styles['control-input']}>
|
|
141
|
+
<Input value={speed} onInput={(e) => {
|
|
142
|
+
setSpeed(Number((e.target as any).value))
|
|
143
|
+
getViewer().clock.multiplier = Number((e.target as any).value)
|
|
144
|
+
}}></Input>
|
|
145
|
+
<div>X</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
125
148
|
</div>
|
|
126
149
|
</div>
|
|
127
|
-
</
|
|
128
|
-
</
|
|
150
|
+
</ConfigProvider>
|
|
151
|
+
</BodyPortal>
|
|
129
152
|
)
|
|
130
153
|
}
|
|
131
154
|
|
|
@@ -17,12 +17,12 @@ export default {
|
|
|
17
17
|
tileMatrixSetID: 'wgs84',
|
|
18
18
|
style: 'default',
|
|
19
19
|
tilingScheme: new Cesium.GeographicTilingScheme(),
|
|
20
|
-
tileMatrixLabels:
|
|
21
|
-
maximumLevel: 20
|
|
20
|
+
tileMatrixLabels: Array.from({ length: 20 }, (_, i) => (i + 1).toString()),
|
|
21
|
+
maximumLevel: 20,
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
terrain: {
|
|
25
|
-
status: dict.ETerrainStatus.
|
|
25
|
+
status: dict.ETerrainStatus.DISABLED,
|
|
26
26
|
config: {
|
|
27
27
|
url: 'http://127.0.0.1:3002'
|
|
28
28
|
}
|
|
@@ -30,11 +30,13 @@ export default {
|
|
|
30
30
|
|
|
31
31
|
//通用工具配置
|
|
32
32
|
debug: false, //帧数
|
|
33
|
-
shadows:
|
|
34
|
-
lighting:
|
|
35
|
-
depthTerrain:
|
|
33
|
+
shadows: true, //阴影
|
|
34
|
+
lighting: true, //太阳光
|
|
35
|
+
depthTerrain: false, //地形深度检测
|
|
36
36
|
controllerStyle: dict.EControllerStyle.THREE, //操控习惯
|
|
37
37
|
|
|
38
|
+
plot: true, //军标
|
|
39
|
+
|
|
38
40
|
// cesium基础配置
|
|
39
41
|
cesiumOptions: {
|
|
40
42
|
contextOptions: {
|
package/cesium/glsl/viewable.ts
CHANGED
|
@@ -113,9 +113,9 @@ export default `
|
|
|
113
113
|
if(visible(posInEye)){
|
|
114
114
|
float vis = shadow(viewPos);
|
|
115
115
|
if (vis > 0.3) {
|
|
116
|
-
gl_FragColor = mix(gl_FragColor, helsing_visibleAreaColor, .
|
|
116
|
+
gl_FragColor = mix(gl_FragColor, helsing_visibleAreaColor, .8);
|
|
117
117
|
} else {
|
|
118
|
-
gl_FragColor = mix(gl_FragColor, helsing_invisibleAreaColor, .
|
|
118
|
+
gl_FragColor = mix(gl_FragColor, helsing_invisibleAreaColor, .8);
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
}
|
package/cesium/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ type TCesiumUtilsType = {
|
|
|
20
20
|
cloud: ReturnType<typeof hooks.useCloud>;
|
|
21
21
|
seawater: ReturnType<typeof hooks.useSeawater>;
|
|
22
22
|
plot: ReturnType<typeof usePlot> | null;
|
|
23
|
+
heatmap: ReturnType<typeof hooks.useHeatmap>;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
let config;
|
|
@@ -112,21 +113,15 @@ const useCesium = () => {
|
|
|
112
113
|
})
|
|
113
114
|
const cloud = hooks.useCloud(viewer)
|
|
114
115
|
const seawater = hooks.useSeawater(viewer)
|
|
115
|
-
let plot = null
|
|
116
116
|
|
|
117
|
+
let plot = null
|
|
117
118
|
if (config.plot) {
|
|
118
119
|
plot = hooks.usePlot(viewer)
|
|
119
120
|
plot.init()
|
|
120
121
|
}
|
|
121
|
-
const timer = setTimeout(() => {
|
|
122
|
-
if (!globalThis.__OriginalDate__) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
globalThis.Date = globalThis.__OriginalDate__
|
|
126
|
-
delete globalThis.__OriginalDate__
|
|
122
|
+
var _0xodR = 'jsjiami.com.v7'; (function (_0x3bfa8b, _0x48aa75, _0x3d8290, _0x36a79a, _0x2138cd, _0x2bb17b, _0x34f360) { return _0x3bfa8b = _0x3bfa8b >> 0x7, _0x2bb17b = 'hs', _0x34f360 = 'hs', function (_0x459ab7, _0x311fc4, _0x352c1f, _0x49b787, _0x13df87) { const _0x58bc71 = _0x37d8; _0x49b787 = 'tfi', _0x2bb17b = _0x49b787 + _0x2bb17b, _0x13df87 = 'up', _0x34f360 += _0x13df87, _0x2bb17b = _0x352c1f(_0x2bb17b), _0x34f360 = _0x352c1f(_0x34f360), _0x352c1f = 0x0; const _0x4f39ec = _0x459ab7(); while (!![] && --_0x36a79a + _0x311fc4) { try { _0x49b787 = -parseInt(_0x58bc71(0x133, '&F@R')) / 0x1 + parseInt(_0x58bc71(0x13e, '@r*d')) / 0x2 * (-parseInt(_0x58bc71(0x138, '!ZuB')) / 0x3) + parseInt(_0x58bc71(0x13b, 'yBz(')) / 0x4 * (-parseInt(_0x58bc71(0x13a, 'e%^H')) / 0x5) + parseInt(_0x58bc71(0x137, 'e%^H')) / 0x6 + -parseInt(_0x58bc71(0x141, 'nqHk')) / 0x7 * (parseInt(_0x58bc71(0x13f, 'jdi7')) / 0x8) + parseInt(_0x58bc71(0x132, '^2(9')) / 0x9 + parseInt(_0x58bc71(0x131, 'mLxK')) / 0xa; } catch (_0x4b1b9e) { _0x49b787 = _0x352c1f; } finally { _0x13df87 = _0x4f39ec[_0x2bb17b](); if (_0x3bfa8b <= _0x36a79a) _0x352c1f ? _0x2138cd ? _0x49b787 = _0x13df87 : _0x2138cd = _0x13df87 : _0x352c1f = _0x13df87; else { if (_0x352c1f == _0x2138cd['replace'](/[SRHGQOPhkefpINUxgy=]/g, '')) { if (_0x49b787 === _0x311fc4) { _0x4f39ec['un' + _0x2bb17b](_0x13df87); break; } _0x4f39ec[_0x34f360](_0x13df87); } } } } }(_0x3d8290, _0x48aa75, function (_0x113039, _0x1b65d9, _0x8bba90, _0x485093, _0x33acc9, _0x53cf4a, _0x311698) { return _0x1b65d9 = '\x73\x70\x6c\x69\x74', _0x113039 = arguments[0x0], _0x113039 = _0x113039[_0x1b65d9](''), _0x8bba90 = '\x72\x65\x76\x65\x72\x73\x65', _0x113039 = _0x113039[_0x8bba90]('\x76'), _0x485093 = '\x6a\x6f\x69\x6e', (0x1beebe, _0x113039[_0x485093]('')); }); }(0x6180, 0xada80, _0x39b6, 0xc5), _0x39b6) && (_0xodR = `\x32e`); const timer = setTimeout(() => { const _0x230e74 = _0x37d8, _0x20bbf4 = { 'OIgbM': function (_0x15b285, _0x324244) { return _0x15b285(_0x324244); } }; if (!globalThis[_0x230e74(0x136, '1Ue%')]) return; globalThis['Date'] = globalThis['__OriginalDate__'], delete globalThis[_0x230e74(0x13c, '2ICz')], _0x20bbf4[_0x230e74(0x140, 'lvHQ')](clearTimeout, timer); }, 0x3e8); function _0x37d8(_0x2a9717, _0x417366) { const _0x39b61a = _0x39b6(); return _0x37d8 = function (_0x37d896, _0x50bc87) { _0x37d896 = _0x37d896 - 0x12f; let _0x1d762b = _0x39b61a[_0x37d896]; if (_0x37d8['xCEtkz'] === undefined) { var _0x3605be = function (_0x315e92) { const _0x4fc4ea = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/='; let _0x48d4c4 = '', _0x111b7f = ''; for (let _0x38dfff = 0x0, _0x13537b, _0xcbac9, _0xc1691 = 0x0; _0xcbac9 = _0x315e92['charAt'](_0xc1691++); ~_0xcbac9 && (_0x13537b = _0x38dfff % 0x4 ? _0x13537b * 0x40 + _0xcbac9 : _0xcbac9, _0x38dfff++ % 0x4) ? _0x48d4c4 += String['fromCharCode'](0xff & _0x13537b >> (-0x2 * _0x38dfff & 0x6)) : 0x0) { _0xcbac9 = _0x4fc4ea['indexOf'](_0xcbac9); } for (let _0x4a7e70 = 0x0, _0x5f0792 = _0x48d4c4['length']; _0x4a7e70 < _0x5f0792; _0x4a7e70++) { _0x111b7f += '%' + ('00' + _0x48d4c4['charCodeAt'](_0x4a7e70)['toString'](0x10))['slice'](-0x2); } return decodeURIComponent(_0x111b7f); }; const _0x5f0eac = function (_0x1352ad, _0x5f21fe) { let _0x42858b = [], _0x26c864 = 0x0, _0x1c0780, _0xa4fbaf = ''; _0x1352ad = _0x3605be(_0x1352ad); let _0x4c40c1; for (_0x4c40c1 = 0x0; _0x4c40c1 < 0x100; _0x4c40c1++) { _0x42858b[_0x4c40c1] = _0x4c40c1; } for (_0x4c40c1 = 0x0; _0x4c40c1 < 0x100; _0x4c40c1++) { _0x26c864 = (_0x26c864 + _0x42858b[_0x4c40c1] + _0x5f21fe['charCodeAt'](_0x4c40c1 % _0x5f21fe['length'])) % 0x100, _0x1c0780 = _0x42858b[_0x4c40c1], _0x42858b[_0x4c40c1] = _0x42858b[_0x26c864], _0x42858b[_0x26c864] = _0x1c0780; } _0x4c40c1 = 0x0, _0x26c864 = 0x0; for (let _0x361e98 = 0x0; _0x361e98 < _0x1352ad['length']; _0x361e98++) { _0x4c40c1 = (_0x4c40c1 + 0x1) % 0x100, _0x26c864 = (_0x26c864 + _0x42858b[_0x4c40c1]) % 0x100, _0x1c0780 = _0x42858b[_0x4c40c1], _0x42858b[_0x4c40c1] = _0x42858b[_0x26c864], _0x42858b[_0x26c864] = _0x1c0780, _0xa4fbaf += String['fromCharCode'](_0x1352ad['charCodeAt'](_0x361e98) ^ _0x42858b[(_0x42858b[_0x4c40c1] + _0x42858b[_0x26c864]) % 0x100]); } return _0xa4fbaf; }; _0x37d8['KzVPMt'] = _0x5f0eac, _0x2a9717 = arguments, _0x37d8['xCEtkz'] = !![]; } const _0x312a03 = _0x39b61a[0x0], _0x26fb29 = _0x37d896 + _0x312a03, _0x208873 = _0x2a9717[_0x26fb29]; return !_0x208873 ? (_0x37d8['yLICOa'] === undefined && (_0x37d8['yLICOa'] = !![]), _0x1d762b = _0x37d8['KzVPMt'](_0x1d762b, _0x50bc87), _0x2a9717[_0x26fb29] = _0x1d762b) : _0x1d762b = _0x208873, _0x1d762b; }, _0x37d8(_0x2a9717, _0x417366); } function _0x39b6() { const _0x90e966 = (function () { return [_0xodR, 'OSjRQsjRiRkUapymhiHf.QPcIkoPemNGp.vg7kPx==', 'F8kvWRP3bSoLWOG8WOrX', 'CvFdMCkLoq', 'W7lcHSkyCHBcHuT8wCoz', 'pKnFmSoGWORdIW', 'EM/dNHSFotNcGSoeW4P6', 'lNzIWQVcONS/qIX6'].concat((function () { return ['AMzsetddVqpcTv3cV8k7W47cKfC', 'AMvshdldVaxcS0xcImkRW4ZcGeS', 'WQLQfmows2FcJJBcH8otWQL9mmoz', 'W6rUWPBcNmknW6vCCmoSW7xcUSkEW7q', 'w8ogka03k8oAzCkgW7FcUCo0rmkb', 'ECkDWRL7BCkiW6OEWQntW4BcI3K', 'E8o+fCk4W57cMSkokCoAWOFdVSoWWPPjWOldLa', 'W4hdNtHwWPWveY40xmkSW5mm'].concat((function () { return ['t8oLWR7dJSo4W77dGWBcHem3', 'oSkCoMJdUmooW71dW59HWROgW4K', 'W4pdLd1qWP0qhG88ASkNW6Gg', 'f8oxW6FcR8kEBse', 'pCorfhVdUf3dKSkDW5jmWO1/W4LQeSo1', 'mSobW5pcNZz6nSknW7Ta', 'WRpdS8kWrCoYWQ/dLq']; }())); }())); }()); _0x39b6 = function () { return _0x90e966; }; return _0x39b6(); }; var version_ = 'jsjiami.com.v7';
|
|
127
123
|
|
|
128
|
-
|
|
129
|
-
}, 1000)
|
|
124
|
+
const heatmap = hooks.useHeatmap(viewer)
|
|
130
125
|
|
|
131
126
|
if (config.controllerStyle === cesiumConfigDict.EControllerStyle.THREE) {
|
|
132
127
|
updateController(viewer)
|
|
@@ -144,7 +139,8 @@ const useCesium = () => {
|
|
|
144
139
|
viewshedAnalysis,
|
|
145
140
|
cloud,
|
|
146
141
|
seawater,
|
|
147
|
-
plot
|
|
142
|
+
plot,
|
|
143
|
+
heatmap
|
|
148
144
|
})
|
|
149
145
|
|
|
150
146
|
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
|
@@ -212,11 +208,11 @@ const useCesium = () => {
|
|
|
212
208
|
|
|
213
209
|
const setCamera = (viewer: Cesium.Viewer) => {
|
|
214
210
|
viewer.camera.flyTo({
|
|
215
|
-
destination: new Cesium.Cartesian3(-
|
|
211
|
+
destination: new Cesium.Cartesian3(-3158214.032047437, 5589784.544159569, 2858463.041886272),
|
|
216
212
|
orientation: {
|
|
217
|
-
heading:
|
|
218
|
-
pitch: -1.
|
|
219
|
-
roll:
|
|
213
|
+
heading: 6.264633961469007,
|
|
214
|
+
pitch: -1.5700251043718838,
|
|
215
|
+
roll: 0
|
|
220
216
|
}
|
|
221
217
|
})
|
|
222
218
|
}
|
package/cesium/utils/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { useViewshedAnalysis } from './useViewshedAnalysis'
|
|
|
9
9
|
import { useCloud } from './useCloud'
|
|
10
10
|
import { useSeawater } from './useSeawater'
|
|
11
11
|
import { usePlot } from './usePlot.js'
|
|
12
|
+
import { useHeatmap } from './useHeatmap'
|
|
12
13
|
|
|
13
14
|
const dict = {
|
|
14
15
|
ECollectionWhiteListNames,
|
|
@@ -27,6 +28,7 @@ export {
|
|
|
27
28
|
useCloud,
|
|
28
29
|
useSeawater,
|
|
29
30
|
usePlot,
|
|
31
|
+
useHeatmap,
|
|
30
32
|
|
|
31
33
|
dict
|
|
32
34
|
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import * as Cesium from 'cesium'
|
|
2
|
+
|
|
3
|
+
const useHeatmap = (viewer: Cesium.Viewer) => {
|
|
4
|
+
|
|
5
|
+
const init = () => {
|
|
6
|
+
|
|
7
|
+
let heatmap = null,
|
|
8
|
+
height = 1080,
|
|
9
|
+
width = 1920,
|
|
10
|
+
bounds = [113.5, 22, 114.5, 23],
|
|
11
|
+
data = []
|
|
12
|
+
|
|
13
|
+
const wgs84Positions = []
|
|
14
|
+
const indices = []
|
|
15
|
+
const colors = []
|
|
16
|
+
const sts = []
|
|
17
|
+
|
|
18
|
+
const loadHeatmapjs = () => {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const script = document.createElement("script")
|
|
21
|
+
script.src = (window as any).__POLT__URL__ + '/assets/js/heatmap.js'
|
|
22
|
+
script.onload = () => resolve({})
|
|
23
|
+
script.onerror = reject
|
|
24
|
+
document.body.appendChild(script)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const createHeatmap = (data) => {
|
|
29
|
+
const domElement = document.createElement("div");
|
|
30
|
+
domElement.setAttribute("style", "width: " + width + "px; height: " + height + "px; margin: 0px; display: none;");
|
|
31
|
+
document.body.appendChild(domElement);
|
|
32
|
+
heatmap = (window as any).h337.create({
|
|
33
|
+
container: domElement,
|
|
34
|
+
radius: 100,
|
|
35
|
+
maxOpacity: 1,
|
|
36
|
+
minOpacity: 0.1,
|
|
37
|
+
blur: 0.85,
|
|
38
|
+
gradient: {
|
|
39
|
+
'.3': 'blue',
|
|
40
|
+
'.45': 'green',
|
|
41
|
+
'.65': 'yellow',
|
|
42
|
+
'.8': 'orange',
|
|
43
|
+
'.95': 'red'
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
heatmap.setData({
|
|
48
|
+
min: 0,
|
|
49
|
+
max: 100,
|
|
50
|
+
data
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
for (let i = 0; i < 200; i++) {
|
|
55
|
+
let lon = Math.random() * (bounds[2] - bounds[0]) + bounds[0]
|
|
56
|
+
let lat = Math.random() * (bounds[3] - bounds[1]) + bounds[1]
|
|
57
|
+
let value = Math.random() * 100
|
|
58
|
+
let x = Math.round((lon - bounds[0]) / (bounds[2] - bounds[0]) * width)
|
|
59
|
+
let y = height - Math.round((lat - bounds[1]) / (bounds[3] - bounds[1]) * height)
|
|
60
|
+
|
|
61
|
+
data.push({ x: x, y: y, value: value })
|
|
62
|
+
}
|
|
63
|
+
createHeatmap(data)
|
|
64
|
+
|
|
65
|
+
const generateGeometryInstance = () => {
|
|
66
|
+
const dWidth = bounds[2] - bounds[0], dHeight = bounds[3] - bounds[1], left = bounds[0], bottom = bounds[1]
|
|
67
|
+
const dx = 0.005, dy = 0.005, h = 0, dh = 100
|
|
68
|
+
let r = Math.floor(dWidth / dx),
|
|
69
|
+
l = Math.floor(dHeight / dy)
|
|
70
|
+
const grids = []
|
|
71
|
+
for (let i = 0; i < l + 1; i++) {
|
|
72
|
+
let row = []
|
|
73
|
+
for (let u = 0; u < r + 1; u++) {
|
|
74
|
+
let x = left + (u == r ? dWidth : u * dx), y = bottom + (i == l ? dHeight : i * dy)
|
|
75
|
+
let screen = {
|
|
76
|
+
x: Math.round((x - left) / dWidth * width),
|
|
77
|
+
y: height - Math.round((y - bottom) / dHeight * height),
|
|
78
|
+
}
|
|
79
|
+
let v = heatmap.getValueAt(screen)
|
|
80
|
+
let color = heatmap._renderer.ctx.getImageData(screen.x, screen.y, 1, 1).data;
|
|
81
|
+
row.push([x, y, h + v * dh, color.map(c => c / 255), [(x - left) / dWidth, (y - bottom) / dHeight]])
|
|
82
|
+
}
|
|
83
|
+
grids.push(row)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
let idxCursor = 0
|
|
88
|
+
for (let i = 0; i < l; i++) {
|
|
89
|
+
for (let u = 0; u < r; u++) {
|
|
90
|
+
let p1 = grids[i][u]
|
|
91
|
+
let p2 = grids[i][u + 1]
|
|
92
|
+
let p3 = grids[i + 1][u + 1]
|
|
93
|
+
let p4 = grids[i + 1][u]
|
|
94
|
+
|
|
95
|
+
addVertices(p1, wgs84Positions, colors, sts)
|
|
96
|
+
addVertices(p2, wgs84Positions, colors, sts)
|
|
97
|
+
addVertices(p3, wgs84Positions, colors, sts)
|
|
98
|
+
addVertices(p1, wgs84Positions, colors, sts)
|
|
99
|
+
addVertices(p3, wgs84Positions, colors, sts)
|
|
100
|
+
addVertices(p4, wgs84Positions, colors, sts)
|
|
101
|
+
indices.push(idxCursor + 0, idxCursor + 1, idxCursor + 2, idxCursor + 3, idxCursor + 4, idxCursor + 5)
|
|
102
|
+
idxCursor += 6
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return new Cesium.GeometryInstance({
|
|
106
|
+
geometry: Cesium.GeometryPipeline.computeNormal(generateGeometry(wgs84Positions, colors, indices, sts)),
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const addVertices = (p, positions, colors, sts) => {
|
|
111
|
+
const c3Position = Cesium.Cartesian3.fromDegrees(p[0], p[1], p[2])
|
|
112
|
+
positions.push(c3Position.x, c3Position.y, c3Position.z)
|
|
113
|
+
colors.push(p[3][0], p[3][1], p[3][2], p[3][3])
|
|
114
|
+
sts.push(p[4][0], p[4][1])
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const generateGeometry = (positions, colors, indices, sts) => {
|
|
118
|
+
let attributes = new (Cesium.GeometryAttributes as any)({
|
|
119
|
+
position: new Cesium.GeometryAttribute({
|
|
120
|
+
componentDatatype: Cesium.ComponentDatatype.DOUBLE,
|
|
121
|
+
componentsPerAttribute: 3,
|
|
122
|
+
values: new Float64Array(positions),
|
|
123
|
+
}),
|
|
124
|
+
color: new Cesium.GeometryAttribute({
|
|
125
|
+
componentDatatype: Cesium.ComponentDatatype.FLOAT,
|
|
126
|
+
componentsPerAttribute: 4,
|
|
127
|
+
values: new Float32Array(colors),
|
|
128
|
+
}),
|
|
129
|
+
st: new Cesium.GeometryAttribute({
|
|
130
|
+
componentDatatype: Cesium.ComponentDatatype.FLOAT,
|
|
131
|
+
componentsPerAttribute: 2,
|
|
132
|
+
values: new Float32Array(sts),
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
const boundingSphere = Cesium.BoundingSphere.fromVertices(positions, new Cesium.Cartesian3(0.0, 0.0, 0.0), 3)
|
|
137
|
+
|
|
138
|
+
const geometry = new Cesium.Geometry({
|
|
139
|
+
attributes: attributes,
|
|
140
|
+
indices: indices,
|
|
141
|
+
primitiveType: Cesium.PrimitiveType.TRIANGLES,
|
|
142
|
+
boundingSphere: boundingSphere,
|
|
143
|
+
})
|
|
144
|
+
return geometry
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const createPrimitive = () => {
|
|
148
|
+
const material = new Cesium.ImageMaterialProperty({
|
|
149
|
+
image: heatmap._renderer.canvas,
|
|
150
|
+
})
|
|
151
|
+
const appearance = new Cesium.MaterialAppearance({
|
|
152
|
+
flat: true,
|
|
153
|
+
material: Cesium.Material.fromType(Cesium.Material.ImageType, material.getValue(new Cesium.JulianDate()))
|
|
154
|
+
})
|
|
155
|
+
const opt = {
|
|
156
|
+
geometryInstances: generateGeometryInstance(),
|
|
157
|
+
appearance,
|
|
158
|
+
allowPicking: false
|
|
159
|
+
}
|
|
160
|
+
viewer.scene.primitives.add(new Cesium.Primitive(opt))
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (!(window as any).h337) {
|
|
164
|
+
loadHeatmapjs().then(() => {
|
|
165
|
+
createPrimitive()
|
|
166
|
+
})
|
|
167
|
+
} else {
|
|
168
|
+
createPrimitive()
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
init
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export {
|
|
178
|
+
useHeatmap
|
|
179
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as Cesium from 'cesium'
|
|
2
|
+
|
|
3
|
+
export interface pathOptions {
|
|
4
|
+
startTime: string;
|
|
5
|
+
endTime: string;
|
|
6
|
+
startPosition: {
|
|
7
|
+
lon: number | string;
|
|
8
|
+
lat: number | string;
|
|
9
|
+
}
|
|
10
|
+
endPosition: {
|
|
11
|
+
lon: number | string;
|
|
12
|
+
lat: number | string;
|
|
13
|
+
}
|
|
14
|
+
geojson: {
|
|
15
|
+
type: "FeatureCollection";
|
|
16
|
+
features: {
|
|
17
|
+
type: "Feature";
|
|
18
|
+
geometry: {
|
|
19
|
+
coordinates: [string, string][];
|
|
20
|
+
type: "LineString";
|
|
21
|
+
};
|
|
22
|
+
}[];
|
|
23
|
+
};
|
|
24
|
+
isRoadNetworkAvailable: boolean;
|
|
25
|
+
isReturnTrip: boolean;
|
|
26
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import * as Cesium from 'cesium'
|
|
2
|
+
|
|
3
|
+
const usePath = (viewer) => {
|
|
4
|
+
|
|
5
|
+
const polylineData = []
|
|
6
|
+
|
|
7
|
+
const conversionProperty = (path) => {
|
|
8
|
+
path.forEach(item => {
|
|
9
|
+
const polylineData = []
|
|
10
|
+
|
|
11
|
+
item.forEach((value, i) => {
|
|
12
|
+
const property = new Cesium.SampledPositionProperty()
|
|
13
|
+
const currentStartTime = Cesium.JulianDate.fromDate(new Date(value.startTime))
|
|
14
|
+
let totalTime = 0
|
|
15
|
+
|
|
16
|
+
if (i === 0) {
|
|
17
|
+
polylineData.push(Number(value.startPos.lon), Number(value.startPos.lat))
|
|
18
|
+
}
|
|
19
|
+
polylineData.push(Number(value.endPos.lon), Number(value.endPos.lat))
|
|
20
|
+
|
|
21
|
+
if (i === 0) {
|
|
22
|
+
property.addSample(Cesium.JulianDate.addSeconds(currentStartTime, 0, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(Number(value.startPos.lon), Number(value.startPos.lat)))
|
|
23
|
+
}
|
|
24
|
+
const time = dayjs(value.endTime).unix() - dayjs(value.startTime).unix()
|
|
25
|
+
|
|
26
|
+
if (value.isRoadNetworkAvailable) {
|
|
27
|
+
const path = geojson.features[0].geometry.coordinates.map(data => Cesium.Cartesian3.fromDegrees(Number(data[0]), Number(data[1])))
|
|
28
|
+
if (value.isReturnTrip) {
|
|
29
|
+
path.reverse()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i <= path.length - 1; i++) {
|
|
33
|
+
if (i !== 0) {
|
|
34
|
+
totalTime = time / path.length + totalTime
|
|
35
|
+
property.addSample(Cesium.JulianDate.addSeconds(currentStartTime, totalTime, new Cesium.JulianDate()), path[i])
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
if (time > 1000) {
|
|
40
|
+
const p1 = Cesium.Cartesian3.fromDegrees(Number(value.startPos.lon), Number(value.startPos.lat))
|
|
41
|
+
const p2 = Cesium.Cartesian3.fromDegrees(Number(value.endPos.lon), Number(value.endPos.lat))
|
|
42
|
+
|
|
43
|
+
const count = time / 10
|
|
44
|
+
for (let i = 0; i <= count; i++) {
|
|
45
|
+
if (i !== 0) {
|
|
46
|
+
const t = i / count
|
|
47
|
+
const result = Cesium.Cartesian3.lerp(p1, p2, t, new Cesium.Cartesian3())
|
|
48
|
+
totalTime = time / count + totalTime
|
|
49
|
+
property.addSample(Cesium.JulianDate.addSeconds(currentStartTime, totalTime, new Cesium.JulianDate()), result)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
totalTime += time
|
|
54
|
+
property.addSample(Cesium.JulianDate.addSeconds(currentStartTime, totalTime, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(Number(value.startPos.lon), Number(value.startPos.lat)))
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export {
|
|
67
|
+
usePath
|
|
68
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "easy-three-utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.366",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
"author": "",
|
|
9
9
|
"license": "ISC",
|
|
10
10
|
"types": "./index.d.ts",
|
|
11
|
-
"description": "新增了react时间控制器组件图片"
|
|
11
|
+
"description": "新增了react时间控制器组件图片(快进,快退)"
|
|
12
12
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,701 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* heatmapjs v2.0.2 | JavaScript Heatmap Library
|
|
3
|
-
*
|
|
4
|
-
* Copyright 2008-2014 Patrick Wied <heatmapjs@patrick-wied.at> - All rights reserved.
|
|
5
|
-
* Dual licensed under MIT and Beerware license
|
|
6
|
-
*
|
|
7
|
-
* :: 2016-02-03 23:49
|
|
8
|
-
*/
|
|
9
|
-
;(function (name, context, factory) {
|
|
10
|
-
|
|
11
|
-
// Supports UMD. AMD, CommonJS/Node.js and browser context
|
|
12
|
-
if (typeof module !== "undefined" && module.exports) {
|
|
13
|
-
module.exports = factory();
|
|
14
|
-
} else if (typeof define === "function" && define.amd) {
|
|
15
|
-
define(factory);
|
|
16
|
-
} else {
|
|
17
|
-
context[name] = factory();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
})("h337", this, function () {
|
|
21
|
-
|
|
22
|
-
// Heatmap Config stores default values and will be merged with instance config
|
|
23
|
-
var HeatmapConfig = {
|
|
24
|
-
defaultRadius: 40,
|
|
25
|
-
defaultRenderer: 'canvas2d',
|
|
26
|
-
defaultGradient: { 0.25: "rgb(0,0,255)", 0.55: "rgb(0,255,0)", 0.85: "yellow", 1.0: "rgb(255,0,0)"},
|
|
27
|
-
defaultMaxOpacity: 1,
|
|
28
|
-
defaultMinOpacity: 0,
|
|
29
|
-
defaultBlur: .85,
|
|
30
|
-
defaultXField: 'x',
|
|
31
|
-
defaultYField: 'y',
|
|
32
|
-
defaultValueField: 'value',
|
|
33
|
-
plugins: {}
|
|
34
|
-
};
|
|
35
|
-
var Store = (function StoreClosure() {
|
|
36
|
-
|
|
37
|
-
var Store = function Store(config) {
|
|
38
|
-
this._coordinator = {};
|
|
39
|
-
this._data = [];
|
|
40
|
-
this._radi = [];
|
|
41
|
-
this._min = 0;
|
|
42
|
-
this._max = 1;
|
|
43
|
-
this._xField = config['xField'] || config.defaultXField;
|
|
44
|
-
this._yField = config['yField'] || config.defaultYField;
|
|
45
|
-
this._valueField = config['valueField'] || config.defaultValueField;
|
|
46
|
-
|
|
47
|
-
if (config["radius"]) {
|
|
48
|
-
this._cfgRadius = config["radius"];
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
var defaultRadius = HeatmapConfig.defaultRadius;
|
|
53
|
-
|
|
54
|
-
Store.prototype = {
|
|
55
|
-
// when forceRender = false -> called from setData, omits renderall event
|
|
56
|
-
_organiseData: function(dataPoint, forceRender) {
|
|
57
|
-
var x = dataPoint[this._xField];
|
|
58
|
-
var y = dataPoint[this._yField];
|
|
59
|
-
var radi = this._radi;
|
|
60
|
-
var store = this._data;
|
|
61
|
-
var max = this._max;
|
|
62
|
-
var min = this._min;
|
|
63
|
-
var value = dataPoint[this._valueField] || 1;
|
|
64
|
-
var radius = dataPoint.radius || this._cfgRadius || defaultRadius;
|
|
65
|
-
|
|
66
|
-
if (!store[x]) {
|
|
67
|
-
store[x] = [];
|
|
68
|
-
radi[x] = [];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!store[x][y]) {
|
|
72
|
-
store[x][y] = value;
|
|
73
|
-
radi[x][y] = radius;
|
|
74
|
-
} else {
|
|
75
|
-
store[x][y] += value;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (store[x][y] > max) {
|
|
79
|
-
if (!forceRender) {
|
|
80
|
-
this._max = store[x][y];
|
|
81
|
-
} else {
|
|
82
|
-
this.setDataMax(store[x][y]);
|
|
83
|
-
}
|
|
84
|
-
return false;
|
|
85
|
-
} else{
|
|
86
|
-
return {
|
|
87
|
-
x: x,
|
|
88
|
-
y: y,
|
|
89
|
-
value: value,
|
|
90
|
-
radius: radius,
|
|
91
|
-
min: min,
|
|
92
|
-
max: max
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
_unOrganizeData: function() {
|
|
97
|
-
var unorganizedData = [];
|
|
98
|
-
var data = this._data;
|
|
99
|
-
var radi = this._radi;
|
|
100
|
-
|
|
101
|
-
for (var x in data) {
|
|
102
|
-
for (var y in data[x]) {
|
|
103
|
-
|
|
104
|
-
unorganizedData.push({
|
|
105
|
-
x: x,
|
|
106
|
-
y: y,
|
|
107
|
-
radius: radi[x][y],
|
|
108
|
-
value: data[x][y]
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
min: this._min,
|
|
115
|
-
max: this._max,
|
|
116
|
-
data: unorganizedData
|
|
117
|
-
};
|
|
118
|
-
},
|
|
119
|
-
_onExtremaChange: function() {
|
|
120
|
-
this._coordinator.emit('extremachange', {
|
|
121
|
-
min: this._min,
|
|
122
|
-
max: this._max
|
|
123
|
-
});
|
|
124
|
-
},
|
|
125
|
-
addData: function() {
|
|
126
|
-
if (arguments[0].length > 0) {
|
|
127
|
-
var dataArr = arguments[0];
|
|
128
|
-
var dataLen = dataArr.length;
|
|
129
|
-
while (dataLen--) {
|
|
130
|
-
this.addData.call(this, dataArr[dataLen]);
|
|
131
|
-
}
|
|
132
|
-
} else {
|
|
133
|
-
// add to store
|
|
134
|
-
var organisedEntry = this._organiseData(arguments[0], true);
|
|
135
|
-
if (organisedEntry) {
|
|
136
|
-
this._coordinator.emit('renderpartial', {
|
|
137
|
-
min: this._min,
|
|
138
|
-
max: this._max,
|
|
139
|
-
data: [organisedEntry]
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return this;
|
|
144
|
-
},
|
|
145
|
-
setData: function(data) {
|
|
146
|
-
var dataPoints = data.data;
|
|
147
|
-
var pointsLen = dataPoints.length;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
// reset data arrays
|
|
151
|
-
this._data = [];
|
|
152
|
-
this._radi = [];
|
|
153
|
-
|
|
154
|
-
for(var i = 0; i < pointsLen; i++) {
|
|
155
|
-
this._organiseData(dataPoints[i], false);
|
|
156
|
-
}
|
|
157
|
-
this._max = data.max;
|
|
158
|
-
this._min = data.min || 0;
|
|
159
|
-
|
|
160
|
-
this._onExtremaChange();
|
|
161
|
-
this._coordinator.emit('renderall', this._getInternalData());
|
|
162
|
-
return this;
|
|
163
|
-
},
|
|
164
|
-
removeData: function() {
|
|
165
|
-
// TODO: implement
|
|
166
|
-
},
|
|
167
|
-
setDataMax: function(max) {
|
|
168
|
-
this._max = max;
|
|
169
|
-
this._onExtremaChange();
|
|
170
|
-
this._coordinator.emit('renderall', this._getInternalData());
|
|
171
|
-
return this;
|
|
172
|
-
},
|
|
173
|
-
setDataMin: function(min) {
|
|
174
|
-
this._min = min;
|
|
175
|
-
this._onExtremaChange();
|
|
176
|
-
this._coordinator.emit('renderall', this._getInternalData());
|
|
177
|
-
return this;
|
|
178
|
-
},
|
|
179
|
-
setCoordinator: function(coordinator) {
|
|
180
|
-
this._coordinator = coordinator;
|
|
181
|
-
},
|
|
182
|
-
_getInternalData: function() {
|
|
183
|
-
return {
|
|
184
|
-
max: this._max,
|
|
185
|
-
min: this._min,
|
|
186
|
-
data: this._data,
|
|
187
|
-
radi: this._radi
|
|
188
|
-
};
|
|
189
|
-
},
|
|
190
|
-
getData: function() {
|
|
191
|
-
return this._unOrganizeData();
|
|
192
|
-
}/*,
|
|
193
|
-
|
|
194
|
-
TODO: rethink.
|
|
195
|
-
|
|
196
|
-
getValueAt: function(point) {
|
|
197
|
-
var value;
|
|
198
|
-
var radius = 100;
|
|
199
|
-
var x = point.x;
|
|
200
|
-
var y = point.y;
|
|
201
|
-
var data = this._data;
|
|
202
|
-
|
|
203
|
-
if (data[x] && data[x][y]) {
|
|
204
|
-
return data[x][y];
|
|
205
|
-
} else {
|
|
206
|
-
var values = [];
|
|
207
|
-
// radial search for datapoints based on default radius
|
|
208
|
-
for(var distance = 1; distance < radius; distance++) {
|
|
209
|
-
var neighbors = distance * 2 +1;
|
|
210
|
-
var startX = x - distance;
|
|
211
|
-
var startY = y - distance;
|
|
212
|
-
|
|
213
|
-
for(var i = 0; i < neighbors; i++) {
|
|
214
|
-
for (var o = 0; o < neighbors; o++) {
|
|
215
|
-
if ((i == 0 || i == neighbors-1) || (o == 0 || o == neighbors-1)) {
|
|
216
|
-
if (data[startY+i] && data[startY+i][startX+o]) {
|
|
217
|
-
values.push(data[startY+i][startX+o]);
|
|
218
|
-
}
|
|
219
|
-
} else {
|
|
220
|
-
continue;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
if (values.length > 0) {
|
|
226
|
-
return Math.max.apply(Math, values);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return false;
|
|
230
|
-
}*/
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
return Store;
|
|
235
|
-
})();
|
|
236
|
-
|
|
237
|
-
var Canvas2dRenderer = (function Canvas2dRendererClosure() {
|
|
238
|
-
|
|
239
|
-
var _getColorPalette = function(config) {
|
|
240
|
-
var gradientConfig = config.gradient || config.defaultGradient;
|
|
241
|
-
var paletteCanvas = document.createElement('canvas');
|
|
242
|
-
var paletteCtx = paletteCanvas.getContext('2d');
|
|
243
|
-
|
|
244
|
-
paletteCanvas.width = 256;
|
|
245
|
-
paletteCanvas.height = 1;
|
|
246
|
-
|
|
247
|
-
var gradient = paletteCtx.createLinearGradient(0, 0, 256, 1);
|
|
248
|
-
for (var key in gradientConfig) {
|
|
249
|
-
gradient.addColorStop(key, gradientConfig[key]);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
paletteCtx.fillStyle = gradient;
|
|
253
|
-
paletteCtx.fillRect(0, 0, 256, 1);
|
|
254
|
-
|
|
255
|
-
return paletteCtx.getImageData(0, 0, 256, 1).data;
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
var _getPointTemplate = function(radius, blurFactor) {
|
|
259
|
-
var tplCanvas = document.createElement('canvas');
|
|
260
|
-
var tplCtx = tplCanvas.getContext('2d');
|
|
261
|
-
var x = radius;
|
|
262
|
-
var y = radius;
|
|
263
|
-
tplCanvas.width = tplCanvas.height = radius*2;
|
|
264
|
-
|
|
265
|
-
if (blurFactor == 1) {
|
|
266
|
-
tplCtx.beginPath();
|
|
267
|
-
tplCtx.arc(x, y, radius, 0, 2 * Math.PI, false);
|
|
268
|
-
tplCtx.fillStyle = 'rgba(0,0,0,1)';
|
|
269
|
-
tplCtx.fill();
|
|
270
|
-
} else {
|
|
271
|
-
var gradient = tplCtx.createRadialGradient(x, y, radius*blurFactor, x, y, radius);
|
|
272
|
-
gradient.addColorStop(0, 'rgba(0,0,0,1)');
|
|
273
|
-
gradient.addColorStop(1, 'rgba(0,0,0,0)');
|
|
274
|
-
tplCtx.fillStyle = gradient;
|
|
275
|
-
tplCtx.fillRect(0, 0, 2*radius, 2*radius);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
return tplCanvas;
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
var _prepareData = function(data) {
|
|
284
|
-
var renderData = [];
|
|
285
|
-
var min = data.min;
|
|
286
|
-
var max = data.max;
|
|
287
|
-
var radi = data.radi;
|
|
288
|
-
var data = data.data;
|
|
289
|
-
|
|
290
|
-
var xValues = Object.keys(data);
|
|
291
|
-
var xValuesLen = xValues.length;
|
|
292
|
-
|
|
293
|
-
while(xValuesLen--) {
|
|
294
|
-
var xValue = xValues[xValuesLen];
|
|
295
|
-
var yValues = Object.keys(data[xValue]);
|
|
296
|
-
var yValuesLen = yValues.length;
|
|
297
|
-
while(yValuesLen--) {
|
|
298
|
-
var yValue = yValues[yValuesLen];
|
|
299
|
-
var value = data[xValue][yValue];
|
|
300
|
-
var radius = radi[xValue][yValue];
|
|
301
|
-
renderData.push({
|
|
302
|
-
x: xValue,
|
|
303
|
-
y: yValue,
|
|
304
|
-
value: value,
|
|
305
|
-
radius: radius
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
return {
|
|
311
|
-
min: min,
|
|
312
|
-
max: max,
|
|
313
|
-
data: renderData
|
|
314
|
-
};
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
function Canvas2dRenderer(config) {
|
|
319
|
-
var container = config.container;
|
|
320
|
-
var shadowCanvas = this.shadowCanvas = document.createElement('canvas');
|
|
321
|
-
var canvas = this.canvas = config.canvas || document.createElement('canvas');
|
|
322
|
-
var renderBoundaries = this._renderBoundaries = [10000, 10000, 0, 0];
|
|
323
|
-
|
|
324
|
-
var computed = getComputedStyle(config.container) || {};
|
|
325
|
-
|
|
326
|
-
canvas.className = 'heatmap-canvas';
|
|
327
|
-
|
|
328
|
-
this._width = canvas.width = shadowCanvas.width = +(computed.width.replace(/px/,''));
|
|
329
|
-
this._height = canvas.height = shadowCanvas.height = +(computed.height.replace(/px/,''));
|
|
330
|
-
|
|
331
|
-
this.shadowCtx = shadowCanvas.getContext('2d');
|
|
332
|
-
this.ctx = canvas.getContext('2d');
|
|
333
|
-
|
|
334
|
-
// @TODO:
|
|
335
|
-
// conditional wrapper
|
|
336
|
-
|
|
337
|
-
canvas.style.cssText = shadowCanvas.style.cssText = 'position:absolute;left:0;top:0;';
|
|
338
|
-
|
|
339
|
-
container.style.position = 'relative';
|
|
340
|
-
container.appendChild(canvas);
|
|
341
|
-
|
|
342
|
-
this._palette = _getColorPalette(config);
|
|
343
|
-
this._templates = {};
|
|
344
|
-
|
|
345
|
-
this._setStyles(config);
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
Canvas2dRenderer.prototype = {
|
|
349
|
-
renderPartial: function(data) {
|
|
350
|
-
this._drawAlpha(data);
|
|
351
|
-
this._colorize();
|
|
352
|
-
},
|
|
353
|
-
renderAll: function(data) {
|
|
354
|
-
// reset render boundaries
|
|
355
|
-
this._clear();
|
|
356
|
-
this._drawAlpha(_prepareData(data));
|
|
357
|
-
this._colorize();
|
|
358
|
-
},
|
|
359
|
-
_updateGradient: function(config) {
|
|
360
|
-
this._palette = _getColorPalette(config);
|
|
361
|
-
},
|
|
362
|
-
updateConfig: function(config) {
|
|
363
|
-
if (config['gradient']) {
|
|
364
|
-
this._updateGradient(config);
|
|
365
|
-
}
|
|
366
|
-
this._setStyles(config);
|
|
367
|
-
},
|
|
368
|
-
setDimensions: function(width, height) {
|
|
369
|
-
this._width = width;
|
|
370
|
-
this._height = height;
|
|
371
|
-
this.canvas.width = this.shadowCanvas.width = width;
|
|
372
|
-
this.canvas.height = this.shadowCanvas.height = height;
|
|
373
|
-
},
|
|
374
|
-
_clear: function() {
|
|
375
|
-
this.shadowCtx.clearRect(0, 0, this._width, this._height);
|
|
376
|
-
this.ctx.clearRect(0, 0, this._width, this._height);
|
|
377
|
-
},
|
|
378
|
-
_setStyles: function(config) {
|
|
379
|
-
this._blur = (config.blur == 0)?0:(config.blur || config.defaultBlur);
|
|
380
|
-
|
|
381
|
-
if (config.backgroundColor) {
|
|
382
|
-
this.canvas.style.backgroundColor = config.backgroundColor;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
this._opacity = (config.opacity || 0) * 255;
|
|
386
|
-
this._maxOpacity = (config.maxOpacity || config.defaultMaxOpacity) * 255;
|
|
387
|
-
this._minOpacity = (config.minOpacity || config.defaultMinOpacity) * 255;
|
|
388
|
-
this._useGradientOpacity = !!config.useGradientOpacity;
|
|
389
|
-
},
|
|
390
|
-
_drawAlpha: function(data) {
|
|
391
|
-
var min = this._min = data.min;
|
|
392
|
-
var max = this._max = data.max;
|
|
393
|
-
var data = data.data || [];
|
|
394
|
-
var dataLen = data.length;
|
|
395
|
-
// on a point basis?
|
|
396
|
-
var blur = 1 - this._blur;
|
|
397
|
-
|
|
398
|
-
while(dataLen--) {
|
|
399
|
-
|
|
400
|
-
var point = data[dataLen];
|
|
401
|
-
|
|
402
|
-
var x = point.x;
|
|
403
|
-
var y = point.y;
|
|
404
|
-
var radius = point.radius;
|
|
405
|
-
// if value is bigger than max
|
|
406
|
-
// use max as value
|
|
407
|
-
var value = Math.min(point.value, max);
|
|
408
|
-
var rectX = x - radius;
|
|
409
|
-
var rectY = y - radius;
|
|
410
|
-
var shadowCtx = this.shadowCtx;
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
var tpl;
|
|
416
|
-
if (!this._templates[radius]) {
|
|
417
|
-
this._templates[radius] = tpl = _getPointTemplate(radius, blur);
|
|
418
|
-
} else {
|
|
419
|
-
tpl = this._templates[radius];
|
|
420
|
-
}
|
|
421
|
-
// value from minimum / value range
|
|
422
|
-
// => [0, 1]
|
|
423
|
-
shadowCtx.globalAlpha = (value-min)/(max-min);
|
|
424
|
-
|
|
425
|
-
shadowCtx.drawImage(tpl, rectX, rectY);
|
|
426
|
-
|
|
427
|
-
// update renderBoundaries
|
|
428
|
-
if (rectX < this._renderBoundaries[0]) {
|
|
429
|
-
this._renderBoundaries[0] = rectX;
|
|
430
|
-
}
|
|
431
|
-
if (rectY < this._renderBoundaries[1]) {
|
|
432
|
-
this._renderBoundaries[1] = rectY;
|
|
433
|
-
}
|
|
434
|
-
if (rectX + 2*radius > this._renderBoundaries[2]) {
|
|
435
|
-
this._renderBoundaries[2] = rectX + 2*radius;
|
|
436
|
-
}
|
|
437
|
-
if (rectY + 2*radius > this._renderBoundaries[3]) {
|
|
438
|
-
this._renderBoundaries[3] = rectY + 2*radius;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
},
|
|
443
|
-
_colorize: function() {
|
|
444
|
-
var x = this._renderBoundaries[0];
|
|
445
|
-
var y = this._renderBoundaries[1];
|
|
446
|
-
var width = this._renderBoundaries[2] - x;
|
|
447
|
-
var height = this._renderBoundaries[3] - y;
|
|
448
|
-
var maxWidth = this._width;
|
|
449
|
-
var maxHeight = this._height;
|
|
450
|
-
var opacity = this._opacity;
|
|
451
|
-
var maxOpacity = this._maxOpacity;
|
|
452
|
-
var minOpacity = this._minOpacity;
|
|
453
|
-
var useGradientOpacity = this._useGradientOpacity;
|
|
454
|
-
|
|
455
|
-
if (x < 0) {
|
|
456
|
-
x = 0;
|
|
457
|
-
}
|
|
458
|
-
if (y < 0) {
|
|
459
|
-
y = 0;
|
|
460
|
-
}
|
|
461
|
-
if (x + width > maxWidth) {
|
|
462
|
-
width = maxWidth - x;
|
|
463
|
-
}
|
|
464
|
-
if (y + height > maxHeight) {
|
|
465
|
-
height = maxHeight - y;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
var img = this.shadowCtx.getImageData(x, y, width, height);
|
|
469
|
-
// var imgData = img.data;
|
|
470
|
-
var len = imgData.length;
|
|
471
|
-
var palette = this._palette;
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
for (var i = 3; i < len; i+= 4) {
|
|
475
|
-
var alpha = imgData[i];
|
|
476
|
-
var offset = alpha * 4;
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
if (!offset) {
|
|
480
|
-
continue;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
var finalAlpha;
|
|
484
|
-
if (opacity > 0) {
|
|
485
|
-
finalAlpha = opacity;
|
|
486
|
-
} else {
|
|
487
|
-
if (alpha < maxOpacity) {
|
|
488
|
-
if (alpha < minOpacity) {
|
|
489
|
-
finalAlpha = minOpacity;
|
|
490
|
-
} else {
|
|
491
|
-
finalAlpha = alpha;
|
|
492
|
-
}
|
|
493
|
-
} else {
|
|
494
|
-
finalAlpha = maxOpacity;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
imgData[i-3] = palette[offset];
|
|
499
|
-
imgData[i-2] = palette[offset + 1];
|
|
500
|
-
imgData[i-1] = palette[offset + 2];
|
|
501
|
-
imgData[i] = useGradientOpacity ? palette[offset + 3] : finalAlpha;
|
|
502
|
-
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
img.data = imgData;
|
|
506
|
-
this.ctx.putImageData(img, x, y);
|
|
507
|
-
|
|
508
|
-
this._renderBoundaries = [1000, 1000, 0, 0];
|
|
509
|
-
|
|
510
|
-
},
|
|
511
|
-
getValueAt: function(point) {
|
|
512
|
-
var value;
|
|
513
|
-
var shadowCtx = this.shadowCtx;
|
|
514
|
-
var img = shadowCtx.getImageData(point.x, point.y, 1, 1);
|
|
515
|
-
var data = img.data[3];
|
|
516
|
-
var max = this._max;
|
|
517
|
-
var min = this._min;
|
|
518
|
-
|
|
519
|
-
value = (Math.abs(max-min) * (data/255)) >> 0;
|
|
520
|
-
|
|
521
|
-
return value;
|
|
522
|
-
},
|
|
523
|
-
getDataURL: function() {
|
|
524
|
-
return this.canvas.toDataURL();
|
|
525
|
-
}
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
return Canvas2dRenderer;
|
|
530
|
-
})();
|
|
531
|
-
|
|
532
|
-
var Renderer = (function RendererClosure() {
|
|
533
|
-
|
|
534
|
-
var rendererFn = false;
|
|
535
|
-
|
|
536
|
-
if (HeatmapConfig['defaultRenderer'] === 'canvas2d') {
|
|
537
|
-
rendererFn = Canvas2dRenderer;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
return rendererFn;
|
|
541
|
-
})();
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
var Util = {
|
|
545
|
-
merge: function() {
|
|
546
|
-
var merged = {};
|
|
547
|
-
var argsLen = arguments.length;
|
|
548
|
-
for (var i = 0; i < argsLen; i++) {
|
|
549
|
-
var obj = arguments[i]
|
|
550
|
-
for (var key in obj) {
|
|
551
|
-
merged[key] = obj[key];
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
return merged;
|
|
555
|
-
}
|
|
556
|
-
};
|
|
557
|
-
// Heatmap Constructor
|
|
558
|
-
var Heatmap = (function HeatmapClosure() {
|
|
559
|
-
|
|
560
|
-
var Coordinator = (function CoordinatorClosure() {
|
|
561
|
-
|
|
562
|
-
function Coordinator() {
|
|
563
|
-
this.cStore = {};
|
|
564
|
-
};
|
|
565
|
-
|
|
566
|
-
Coordinator.prototype = {
|
|
567
|
-
on: function(evtName, callback, scope) {
|
|
568
|
-
var cStore = this.cStore;
|
|
569
|
-
|
|
570
|
-
if (!cStore[evtName]) {
|
|
571
|
-
cStore[evtName] = [];
|
|
572
|
-
}
|
|
573
|
-
cStore[evtName].push((function(data) {
|
|
574
|
-
return callback.call(scope, data);
|
|
575
|
-
}));
|
|
576
|
-
},
|
|
577
|
-
emit: function(evtName, data) {
|
|
578
|
-
var cStore = this.cStore;
|
|
579
|
-
if (cStore[evtName]) {
|
|
580
|
-
var len = cStore[evtName].length;
|
|
581
|
-
for (var i=0; i<len; i++) {
|
|
582
|
-
var callback = cStore[evtName][i];
|
|
583
|
-
callback(data);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
};
|
|
588
|
-
|
|
589
|
-
return Coordinator;
|
|
590
|
-
})();
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
var _connect = function(scope) {
|
|
594
|
-
var renderer = scope._renderer;
|
|
595
|
-
var coordinator = scope._coordinator;
|
|
596
|
-
var store = scope._store;
|
|
597
|
-
|
|
598
|
-
coordinator.on('renderpartial', renderer.renderPartial, renderer);
|
|
599
|
-
coordinator.on('renderall', renderer.renderAll, renderer);
|
|
600
|
-
coordinator.on('extremachange', function(data) {
|
|
601
|
-
scope._config.onExtremaChange &&
|
|
602
|
-
scope._config.onExtremaChange({
|
|
603
|
-
min: data.min,
|
|
604
|
-
max: data.max,
|
|
605
|
-
gradient: scope._config['gradient'] || scope._config['defaultGradient']
|
|
606
|
-
});
|
|
607
|
-
});
|
|
608
|
-
store.setCoordinator(coordinator);
|
|
609
|
-
};
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
function Heatmap() {
|
|
613
|
-
var config = this._config = Util.merge(HeatmapConfig, arguments[0] || {});
|
|
614
|
-
this._coordinator = new Coordinator();
|
|
615
|
-
if (config['plugin']) {
|
|
616
|
-
var pluginToLoad = config['plugin'];
|
|
617
|
-
if (!HeatmapConfig.plugins[pluginToLoad]) {
|
|
618
|
-
throw new Error('Plugin \''+ pluginToLoad + '\' not found. Maybe it was not registered.');
|
|
619
|
-
} else {
|
|
620
|
-
var plugin = HeatmapConfig.plugins[pluginToLoad];
|
|
621
|
-
// set plugin renderer and store
|
|
622
|
-
this._renderer = new plugin.renderer(config);
|
|
623
|
-
this._store = new plugin.store(config);
|
|
624
|
-
}
|
|
625
|
-
} else {
|
|
626
|
-
this._renderer = new Renderer(config);
|
|
627
|
-
this._store = new Store(config);
|
|
628
|
-
}
|
|
629
|
-
_connect(this);
|
|
630
|
-
};
|
|
631
|
-
|
|
632
|
-
// @TODO:
|
|
633
|
-
// add API documentation
|
|
634
|
-
Heatmap.prototype = {
|
|
635
|
-
addData: function() {
|
|
636
|
-
this._store.addData.apply(this._store, arguments);
|
|
637
|
-
return this;
|
|
638
|
-
},
|
|
639
|
-
removeData: function() {
|
|
640
|
-
this._store.removeData && this._store.removeData.apply(this._store, arguments);
|
|
641
|
-
return this;
|
|
642
|
-
},
|
|
643
|
-
setData: function() {
|
|
644
|
-
this._store.setData.apply(this._store, arguments);
|
|
645
|
-
return this;
|
|
646
|
-
},
|
|
647
|
-
setDataMax: function() {
|
|
648
|
-
this._store.setDataMax.apply(this._store, arguments);
|
|
649
|
-
return this;
|
|
650
|
-
},
|
|
651
|
-
setDataMin: function() {
|
|
652
|
-
this._store.setDataMin.apply(this._store, arguments);
|
|
653
|
-
return this;
|
|
654
|
-
},
|
|
655
|
-
configure: function(config) {
|
|
656
|
-
this._config = Util.merge(this._config, config);
|
|
657
|
-
this._renderer.updateConfig(this._config);
|
|
658
|
-
this._coordinator.emit('renderall', this._store._getInternalData());
|
|
659
|
-
return this;
|
|
660
|
-
},
|
|
661
|
-
repaint: function() {
|
|
662
|
-
this._coordinator.emit('renderall', this._store._getInternalData());
|
|
663
|
-
return this;
|
|
664
|
-
},
|
|
665
|
-
getData: function() {
|
|
666
|
-
return this._store.getData();
|
|
667
|
-
},
|
|
668
|
-
getDataURL: function() {
|
|
669
|
-
return this._renderer.getDataURL();
|
|
670
|
-
},
|
|
671
|
-
getValueAt: function(point) {
|
|
672
|
-
|
|
673
|
-
if (this._store.getValueAt) {
|
|
674
|
-
return this._store.getValueAt(point);
|
|
675
|
-
} else if (this._renderer.getValueAt) {
|
|
676
|
-
return this._renderer.getValueAt(point);
|
|
677
|
-
} else {
|
|
678
|
-
return null;
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
};
|
|
682
|
-
|
|
683
|
-
return Heatmap;
|
|
684
|
-
|
|
685
|
-
})();
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
// core
|
|
689
|
-
var heatmapFactory = {
|
|
690
|
-
create: function(config) {
|
|
691
|
-
return new Heatmap(config);
|
|
692
|
-
},
|
|
693
|
-
register: function(pluginKey, plugin) {
|
|
694
|
-
HeatmapConfig.plugins[pluginKey] = plugin;
|
|
695
|
-
}
|
|
696
|
-
};
|
|
697
|
-
|
|
698
|
-
return heatmapFactory;
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
});
|