@avs/go 0.14.72008 → 0.14.72037
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/LICENSE +195 -0
- package/NOTICE +5 -0
- package/README.md +2 -2
- package/dist/avs-element-mixin.d.ts +3 -3
- package/dist/avs-element-mixin.d.ts.map +1 -1
- package/dist/avs-element-mixin.js +1 -1
- package/dist/avs-go-dataviz.d.ts +34 -44
- package/dist/avs-go-dataviz.d.ts.map +1 -1
- package/dist/avs-go-dataviz.js +49 -66
- package/dist/avs-go-dynamic-html.d.ts +1 -1
- package/dist/avs-go-dynamic-html.d.ts.map +1 -1
- package/dist/avs-go-dynamic-html.js +8 -3
- package/dist/avs-go-info.d.ts +1 -1
- package/dist/avs-go-info.d.ts.map +1 -1
- package/dist/avs-go-info.js +7 -2
- package/dist/avs-go.min.js +36 -57
- package/dist/avs-renderer.d.ts +2 -2
- package/dist/avs-renderer.d.ts.map +1 -1
- package/dist/avs-renderer.js +5 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +2 -2
- package/dist/icons.d.ts +1 -1
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +4 -15
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -18
- package/licenses/lit.BSD-3 +28 -0
- package/{lib/LICENSE-avsthreejs → licenses/three.MIT} +1 -21
- package/package.json +14 -4
- package/demo/data/scene.json +0 -1
- package/demo/img/avs.png +0 -0
- package/demo/jsonView.html +0 -36
- package/dist/avs-go.min.js.LICENSE.txt +0 -61
- package/rollup.config.js +0 -26
- package/src/avs-element-mixin.ts +0 -126
- package/src/avs-go-dataviz.ts +0 -2400
- package/src/avs-go-dynamic-html.ts +0 -138
- package/src/avs-go-info.ts +0 -141
- package/src/avs-renderer.ts +0 -44
- package/src/constants.ts +0 -21
- package/src/icons.ts +0 -29
- package/src/index.ts +0 -23
- package/src/types.ts +0 -160
- package/tsconfig.json +0 -16
package/src/avs-go-dataviz.ts
DELETED
|
@@ -1,2400 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2018 Advanced Visual Systems Inc.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*
|
|
17
|
-
* This product includes software developed at
|
|
18
|
-
* Advanced Visual Systems Inc. (http://www.avs.com)
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
import { AvsElementMixin } from './avs-element-mixin.js';
|
|
22
|
-
import { LitElement, html, PropertyValues } from 'lit';
|
|
23
|
-
import { customElement, property } from 'lit/decorators.js';
|
|
24
|
-
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
25
|
-
import { AvsRenderer } from './avs-renderer.js';
|
|
26
|
-
import { Viewer, TransformInteractor, PanInteractor, ZoomRectangleInteractor, PickDepthEnum, Animator } from '../lib/avs-three.module.min.js';
|
|
27
|
-
import { AVS, PLAY, CAMERA, TIMELAPSE, HOME, DELETE, COPY, LINK } from './icons.js';
|
|
28
|
-
import { Euler, Vector3, Quaternion } from 'three';
|
|
29
|
-
import { DataVizModel, DataVizResponse, MotionCaptureFrame, PickDepth, PickDetail, PickLevel, PickProperties, Renderer, RendererProperties, SelectedInfo } from './types.js';
|
|
30
|
-
|
|
31
|
-
const ro = new ResizeObserver((entries: ResizeObserverEntry[], observer: ResizeObserver) => {
|
|
32
|
-
entries.forEach((entry: ResizeObserverEntry) => {
|
|
33
|
-
const target = entry.target as AvsGoDataViz;
|
|
34
|
-
target._onResize(entry.contentRect);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* `avs-go-dataviz` is a Lit element which requests a data visualization
|
|
40
|
-
* from either the `sceneName` class on the AVS/Go server application running at `url`,
|
|
41
|
-
* or from a JSON file at `url` when `urlLoadJsonFile` is set.
|
|
42
|
-
*
|
|
43
|
-
* The request occurs upon:
|
|
44
|
-
* * An explicit call to `updateViewer()`
|
|
45
|
-
* * A change in `renderer`
|
|
46
|
-
* * Additionally if `manualUpdate` is false:
|
|
47
|
-
* * * Initialization of this element has completed
|
|
48
|
-
* * * This element is resized outside of the `resizeThresold` percentage
|
|
49
|
-
*
|
|
50
|
-
* @customElement
|
|
51
|
-
* @lit
|
|
52
|
-
* @applysMixin AvsElementMixin
|
|
53
|
-
*/
|
|
54
|
-
@customElement('avs-go-dataviz')
|
|
55
|
-
export class AvsGoDataViz extends AvsElementMixin(LitElement) {
|
|
56
|
-
render() {
|
|
57
|
-
return html`
|
|
58
|
-
<style>
|
|
59
|
-
:host {
|
|
60
|
-
display:block;
|
|
61
|
-
width:100%;
|
|
62
|
-
height:100%;
|
|
63
|
-
overflow:hidden;
|
|
64
|
-
position:relative;
|
|
65
|
-
letter-spacing:normal;
|
|
66
|
-
word-spacing:normal;
|
|
67
|
-
line-height:normal;
|
|
68
|
-
text-indent:0;
|
|
69
|
-
text-transform:none;
|
|
70
|
-
direction:ltr;
|
|
71
|
-
}
|
|
72
|
-
#dataVizDiv {
|
|
73
|
-
position:relative;
|
|
74
|
-
width:100%;
|
|
75
|
-
height:100%;
|
|
76
|
-
}
|
|
77
|
-
#motionCapture {
|
|
78
|
-
display: none;
|
|
79
|
-
position:absolute;
|
|
80
|
-
top: 8px;
|
|
81
|
-
left: 8px;
|
|
82
|
-
padding: 8px;
|
|
83
|
-
background-color: rgba(128, 128, 128, 0.8);
|
|
84
|
-
font-size: 10pt;
|
|
85
|
-
border-radius: 8px;
|
|
86
|
-
background:var(--avs-motion-capture-background, rgba(80,80,80,0.75));
|
|
87
|
-
color:var(--avs-motion-capture-color, #ffffff);
|
|
88
|
-
font-family:var(--avs-motion-capture-font-family);
|
|
89
|
-
box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
|
|
90
|
-
user-select: none;
|
|
91
|
-
}
|
|
92
|
-
#motionCaptureTitle {
|
|
93
|
-
margin-bottom: 4px;
|
|
94
|
-
font-weight: 700;
|
|
95
|
-
}
|
|
96
|
-
.btn {
|
|
97
|
-
padding: 4px;
|
|
98
|
-
border-radius: 4px;
|
|
99
|
-
margin: 2px;
|
|
100
|
-
background:var(--avs-motion-capture-control-background, white);
|
|
101
|
-
color:var(--avs-motion-capture-control-color, black);
|
|
102
|
-
display: inline-flex;
|
|
103
|
-
align-items: center;
|
|
104
|
-
box-shadow: 0 2px 2px #00000024,0 3px 1px -2px #0000001f,0 1px 5px #0003;
|
|
105
|
-
}
|
|
106
|
-
a.btn {
|
|
107
|
-
cursor: pointer;
|
|
108
|
-
}
|
|
109
|
-
.btn.disabled {
|
|
110
|
-
cursor: default;
|
|
111
|
-
pointer-events: none;
|
|
112
|
-
box-shadow: none;
|
|
113
|
-
background-color: darkgrey;
|
|
114
|
-
color: grey;
|
|
115
|
-
}
|
|
116
|
-
#motionCaptureSnapshotIcon, #motionCaptureDelayIcon {
|
|
117
|
-
height: 24px;
|
|
118
|
-
}
|
|
119
|
-
#motionCaptureSnapshotLabel, #motionCaptureDelayLabel {
|
|
120
|
-
margin-left: 4px;
|
|
121
|
-
height: 14px;
|
|
122
|
-
}
|
|
123
|
-
#motionCaptureDelayWheel {
|
|
124
|
-
display: flex;
|
|
125
|
-
flex-direction: column;
|
|
126
|
-
margin: 0 4px;
|
|
127
|
-
height: 24px;
|
|
128
|
-
gap: 2px;
|
|
129
|
-
}
|
|
130
|
-
#motionCaptureDelayIncrease, #motionCaptureDelayDecrease {
|
|
131
|
-
height: 8px;
|
|
132
|
-
text-align: center;
|
|
133
|
-
font-weight: 700;
|
|
134
|
-
cursor: pointer;
|
|
135
|
-
}
|
|
136
|
-
#motionCaptureReset, #motionCaptureCopyData {
|
|
137
|
-
margin-left: 12px;
|
|
138
|
-
}
|
|
139
|
-
#sceneImage {
|
|
140
|
-
width:100%;
|
|
141
|
-
height:100%;
|
|
142
|
-
position:absolute;
|
|
143
|
-
outline:none;
|
|
144
|
-
}
|
|
145
|
-
#rectCanvas {
|
|
146
|
-
position:absolute;
|
|
147
|
-
top:0px;
|
|
148
|
-
left:0px;
|
|
149
|
-
}
|
|
150
|
-
#zoomOverlay {
|
|
151
|
-
position:absolute;
|
|
152
|
-
opacity:0;
|
|
153
|
-
transition:opacity ease 0.3s;
|
|
154
|
-
pointer-events:none;
|
|
155
|
-
background:var(--avs-zoom-overlay-background, rgba(80,80,80,0.75));
|
|
156
|
-
color:var(--avs-zoom-overlay-color, #ffffff);
|
|
157
|
-
border-radius:5px;
|
|
158
|
-
padding:5px;
|
|
159
|
-
transform:translate(-50%, -100%);
|
|
160
|
-
font-size:var(--avs-zoom-overlay-font-size, 10pt);
|
|
161
|
-
font-family:var(--avs-zoom-overlay-font-family);
|
|
162
|
-
font-weight:var(--avs-zoom-overlay-font-weight, bold);
|
|
163
|
-
font-style:var(--avs-zoom-overlay-font-style);
|
|
164
|
-
}
|
|
165
|
-
#tooltip, #motionCaptureTooltip, #motionCaptureAlert {
|
|
166
|
-
position:absolute;
|
|
167
|
-
opacity:0;
|
|
168
|
-
transition:opacity ease 0.3s;
|
|
169
|
-
pointer-events:none;
|
|
170
|
-
padding:5px;
|
|
171
|
-
border-radius:5px;
|
|
172
|
-
background:var(--avs-tooltip-background, rgb(80,80,80));
|
|
173
|
-
color:var(--avs-tooltip-color, #ffffff);
|
|
174
|
-
box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
|
|
175
|
-
font-size:var(--avs-tooltip-font-size, 10pt);
|
|
176
|
-
font-family:var(--avs-tooltip-font-family);
|
|
177
|
-
font-weight:var(--avs-tooltip-font-weight);
|
|
178
|
-
font-style:var(--avs-tooltip-font-style);
|
|
179
|
-
}
|
|
180
|
-
#motionCaptureAlert {
|
|
181
|
-
left: 50%;
|
|
182
|
-
top: 50%;
|
|
183
|
-
transform: translate(-50%, -50%);
|
|
184
|
-
}
|
|
185
|
-
#spinnerDiv {
|
|
186
|
-
position:absolute;
|
|
187
|
-
left:var(--avs-spinner-left, 50%);
|
|
188
|
-
top:var(--avs-spinner-top, 50%);
|
|
189
|
-
transform:var(--avs-spinner-transform, translate(-50%,-50%));
|
|
190
|
-
}
|
|
191
|
-
#spinner {
|
|
192
|
-
display:none;
|
|
193
|
-
}
|
|
194
|
-
.spin {
|
|
195
|
-
-webkit-animation:spin 2s ease-in-out infinite;
|
|
196
|
-
-moz-animation:spin 2s ease-in-out infinite;
|
|
197
|
-
animation:spin 2s ease-in-out infinite;
|
|
198
|
-
}
|
|
199
|
-
.spinnerBackground {
|
|
200
|
-
fill:var(--avs-spinner-background-color, rgb(0,0,0,0));
|
|
201
|
-
stroke-width:0.0160303
|
|
202
|
-
}
|
|
203
|
-
@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
|
|
204
|
-
@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
|
|
205
|
-
@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
|
|
206
|
-
</style>
|
|
207
|
-
<div id="dataVizDiv"></div>
|
|
208
|
-
<div id="motionCapture">
|
|
209
|
-
<div style="display: flex; justify-content: center" id="motionCaptureTitle">Motion Capture</div>
|
|
210
|
-
<div>
|
|
211
|
-
<a class="btn disabled" id="motionCapturePlay" data-tooltip="Play motion capture" @click="${this.runAnimation}" @pointermove="${this._handlePointerEnterMotionCaptureControl}" @pointerout="${this._handlePointerLeaveMotionCaptureControl}">${unsafeSVG(PLAY)}</a>
|
|
212
|
-
<a class="btn" id="motionCaptureSnapshot" data-tooltip="Take snapshot" @click="${this._handleMotionCaptureSnapshot}" @pointermove="${this._handlePointerEnterMotionCaptureControl}" @pointerout="${this._handlePointerLeaveMotionCaptureControl}">
|
|
213
|
-
<div id="motionCaptureSnapshotIcon">${unsafeSVG(CAMERA)}</div>
|
|
214
|
-
<div id="motionCaptureSnapshotLabel">0</div>
|
|
215
|
-
</a>
|
|
216
|
-
<div class="btn disabled" id="motionCaptureDelay" data-tooltip="Frame delay (seconds)" @pointermove="${this._handlePointerEnterMotionCaptureControl}" @pointerout="${this._handlePointerLeaveMotionCaptureControl}">
|
|
217
|
-
<div id="motionCaptureDelayIcon">${unsafeSVG(TIMELAPSE)}</div>
|
|
218
|
-
<div id="motionCaptureDelayLabel">0</div>
|
|
219
|
-
<div id="motionCaptureDelayWheel">
|
|
220
|
-
<a id="motionCaptureDelayIncrease" @click="${this._handleMotionCaptureDelayIncrease}">+</a>
|
|
221
|
-
<a id="motionCaptureDelayDecrease" @click="${this._handleMotionCaptureDelayDecrease}">-</a>
|
|
222
|
-
</div>
|
|
223
|
-
</div>
|
|
224
|
-
<a class="btn" id="motionCaptureReset" data-tooltip="Reset transform" @click="${this.resetTransform}" @pointermove="${this._handlePointerEnterMotionCaptureControl}" @pointerout="${this._handlePointerLeaveMotionCaptureControl}">${unsafeSVG(HOME)}</a>
|
|
225
|
-
<a class="btn disabled" id="motionCaptureClear" data-tooltip="Clear motion capture frames" @click="${this._handleMotionCaptureClear}" @pointermove="${this._handlePointerEnterMotionCaptureControl}" @pointerout="${this._handlePointerLeaveMotionCaptureControl}">${unsafeSVG(DELETE)}</a>
|
|
226
|
-
<a class="btn disabled" id="motionCaptureCopyData" data-tooltip="Copy motion capture data to clipboard" @click="${this._handleMotionCaptureCopyData}" @pointermove="${this._handlePointerEnterMotionCaptureControl}" @pointerout="${this._handlePointerLeaveMotionCaptureControl}">${unsafeSVG(COPY)}</a>
|
|
227
|
-
<a class="btn disabled" id="motionCaptureCopyUrl" data-tooltip="Copy motion capture URL to clipboard" @click="${this._handleMotionCaptureCopyUrl}" @pointermove="${this._handlePointerEnterMotionCaptureControl}" @pointerout="${this._handlePointerLeaveMotionCaptureControl}">${unsafeSVG(LINK)}</a>
|
|
228
|
-
</div>
|
|
229
|
-
</div>
|
|
230
|
-
<div id="motionCaptureTooltip"></div>
|
|
231
|
-
<div id="motionCaptureAlert"></div>
|
|
232
|
-
<div id="zoomOverlay"></div>
|
|
233
|
-
<div id="spinnerDiv">
|
|
234
|
-
<div id="spinner"></div>
|
|
235
|
-
</div>
|
|
236
|
-
<div id="tooltip"></div>
|
|
237
|
-
`;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/** Don't request a new scene upon initialization or resize. */
|
|
241
|
-
@property({ attribute: 'manual-update', type: Boolean })
|
|
242
|
-
manualUpdate?: boolean;
|
|
243
|
-
|
|
244
|
-
/** Highlight canvas elements when using the `THREEJS` renderer. */
|
|
245
|
-
@property({ attribute: 'display-canvas', type: Boolean })
|
|
246
|
-
displayCanvas: boolean;
|
|
247
|
-
|
|
248
|
-
/** The URL to an instance of AVS/Go server application or file. */
|
|
249
|
-
@property()
|
|
250
|
-
url: string;
|
|
251
|
-
|
|
252
|
-
/** Enables loading JSON from a file. */
|
|
253
|
-
@property({ attribute: 'url-load-json-file', type: Boolean })
|
|
254
|
-
urlLoadJsonFile?: boolean;
|
|
255
|
-
|
|
256
|
-
/** Name of the data source registered in the library map on the server. */
|
|
257
|
-
@property({ attribute: 'data-source-name' })
|
|
258
|
-
dataSourceName?: string;
|
|
259
|
-
|
|
260
|
-
/** User properties as JSON passed directly to the data source on the server. */
|
|
261
|
-
@property({ attribute: 'data-source-user-properties' })
|
|
262
|
-
dataSourceUserProperties?: string;
|
|
263
|
-
|
|
264
|
-
/** Name of the scene registered in the library map on the server. */
|
|
265
|
-
@property({ attribute: 'scene-name' })
|
|
266
|
-
sceneName?: string;
|
|
267
|
-
|
|
268
|
-
/** User properties as JSON passed directly to the scene on the server. */
|
|
269
|
-
@property({ attribute: 'scene-user-properties' })
|
|
270
|
-
sceneUserProperties?: string;
|
|
271
|
-
|
|
272
|
-
/** Name of the renderer registered in the library map on the server. */
|
|
273
|
-
@property({ attribute: 'renderer-name' })
|
|
274
|
-
rendererName?: string;
|
|
275
|
-
|
|
276
|
-
/** User properties as JSON passed directly to the renderer on the server. */
|
|
277
|
-
@property({ attribute: 'renderer-user-properties' })
|
|
278
|
-
rendererUserProperties?: string;
|
|
279
|
-
|
|
280
|
-
/** The type of renderer to be used to display a scene: `IMAGE`, `SVG` or `THREEJS` */
|
|
281
|
-
@property()
|
|
282
|
-
renderer: Renderer;
|
|
283
|
-
|
|
284
|
-
/** Enables streaming of objects from the server. Only available when `renderer` is `THREEJS` */
|
|
285
|
-
@property({ attribute: 'stream-enable', type: Boolean })
|
|
286
|
-
streamEnable?: boolean;
|
|
287
|
-
|
|
288
|
-
/** The number of objects streamed for the first chunk. */
|
|
289
|
-
@property({ attribute: 'stream-chunk-size-first' })
|
|
290
|
-
streamChunkSizeFirst?: number;
|
|
291
|
-
|
|
292
|
-
/** The number of objects streamed per chunk. */
|
|
293
|
-
@property({ attribute: 'stream-chunk-size' })
|
|
294
|
-
streamChunkSize?: number;
|
|
295
|
-
|
|
296
|
-
/** The name of the theme registered in the library map on the server, or undefined to use CSS, or one of the branded themes: `DEFAULT`, `AVS_LIGHT`, `AVS_DARK` or `AVS_BLACK` */
|
|
297
|
-
@property({ attribute: 'theme-name' })
|
|
298
|
-
themeName?: string;
|
|
299
|
-
|
|
300
|
-
/** Resize threshold (percent) to determine when the update is performed on the client or the server.
|
|
301
|
-
Default is 10%. Set to zero to disable resize on the server. */
|
|
302
|
-
@property({ attribute: 'resize-threshold' })
|
|
303
|
-
resizeThreshold?: number;
|
|
304
|
-
|
|
305
|
-
/** Number of seconds between pointer moves before an `avs-pointer-timeout` event is dispatched. */
|
|
306
|
-
@property({ attribute: 'pointer-timeout' })
|
|
307
|
-
pointerTimeout?: number;
|
|
308
|
-
|
|
309
|
-
/** Enables the `avs-tap` event. */
|
|
310
|
-
@property({ attribute: 'tap-enable', type: Boolean })
|
|
311
|
-
tapEnable?: boolean;
|
|
312
|
-
|
|
313
|
-
/** The level of geometry within the scene to be modified by the tap event: `CELL`, `CELL_SET` or `SCENE_NODE` */
|
|
314
|
-
@property({ attribute: 'tap-level' })
|
|
315
|
-
tapLevel?: PickLevel;
|
|
316
|
-
|
|
317
|
-
/** The depth at which an object is selected: `ALL` or `CLOSEST` */
|
|
318
|
-
@property({ attribute: 'tap-depth' })
|
|
319
|
-
tapDepth?: PickDepth;
|
|
320
|
-
|
|
321
|
-
/** Enables highlight of selected geometry in the scene. */
|
|
322
|
-
@property({ attribute: 'tap-highlight-enable', type: Boolean })
|
|
323
|
-
tapHighlightEnable?: boolean;
|
|
324
|
-
|
|
325
|
-
/** The color to used to highlight the selected objects in the scene. */
|
|
326
|
-
@property({ attribute: 'tap-highlight-color' })
|
|
327
|
-
tapHighlightColor?: string;
|
|
328
|
-
|
|
329
|
-
/** Enables drawing highlighted objects in front of all objects in the scene. This results in faster rendering in a 2D viewport when using the `THREEJS` renderer. */
|
|
330
|
-
@property({ attribute: 'tap-highlight-layer-enable', type: Boolean })
|
|
331
|
-
tapHighlightLayerEnable?: boolean;
|
|
332
|
-
|
|
333
|
-
/** Enables the processing of tap events on the client. Only available when `renderer` is `THREEJS` */
|
|
334
|
-
@property({ attribute: 'tap-process-event-on-client', type: Boolean })
|
|
335
|
-
tapProcessEventOnClient?: boolean;
|
|
336
|
-
|
|
337
|
-
/** Enables the `avs-track` event. */
|
|
338
|
-
@property({ attribute: 'track-enable', type: Boolean })
|
|
339
|
-
trackEnable?: boolean;
|
|
340
|
-
|
|
341
|
-
/** The level of geometry within the scene to be modified by the track event: `CELL`, `CELL_SET` or `SCENE_NODE` */
|
|
342
|
-
@property({ attribute: 'track-level' })
|
|
343
|
-
trackLevel?: PickLevel;
|
|
344
|
-
|
|
345
|
-
/** The depth at which an object is selected: `ALL` or `CLOSEST` */
|
|
346
|
-
@property({ attribute: 'track-depth' })
|
|
347
|
-
trackDepth?: PickDepth;
|
|
348
|
-
|
|
349
|
-
/** Enables highlight of selected geometry in the scene. */
|
|
350
|
-
@property({ attribute: 'track-highlight-enable', type: Boolean })
|
|
351
|
-
trackHighlightEnable?: boolean;
|
|
352
|
-
|
|
353
|
-
/** The color to used to highlight the selected objects in the scene. */
|
|
354
|
-
@property({ attribute: 'track-highlight-color' })
|
|
355
|
-
trackHighlightColor?: string;
|
|
356
|
-
|
|
357
|
-
/** Enables drawing highlighted objects in front of all objects in the scene. This results in faster rendering in a 2D viewport when using the `THREEJS` renderer. */
|
|
358
|
-
@property({ attribute: 'track-highlight-layer-enable', type: Boolean })
|
|
359
|
-
trackHighlightLayerEnable?: boolean;
|
|
360
|
-
|
|
361
|
-
/** Enables the processing of track events on the client. Only available when `renderer` is `THREEJS` */
|
|
362
|
-
@property({ attribute: 'track-process-event-on-client', type: Boolean })
|
|
363
|
-
trackProcessEventOnClient?: boolean;
|
|
364
|
-
|
|
365
|
-
/** Enables the `avs-hover` event. */
|
|
366
|
-
@property({ attribute: 'hover-enable', type: Boolean })
|
|
367
|
-
hoverEnable?: boolean;
|
|
368
|
-
|
|
369
|
-
/** The level of geometry within the scene to be modified by the hover event: `CELL`, `CELL_SET` or `SCENE_NODE` */
|
|
370
|
-
@property({ attribute: 'hover-level' })
|
|
371
|
-
hoverLevel?: PickLevel;
|
|
372
|
-
|
|
373
|
-
/** The depth at which an object is selected: `ALL` or `CLOSEST` */
|
|
374
|
-
@property({ attribute: 'hover-depth' })
|
|
375
|
-
hoverDepth?: PickDepth;
|
|
376
|
-
|
|
377
|
-
/** Enables highlight of selected geometry in the scene. */
|
|
378
|
-
@property({ attribute: 'hover-highlight-enable', type: Boolean })
|
|
379
|
-
hoverHighlightEnable?: boolean;
|
|
380
|
-
|
|
381
|
-
/** The color to used to highlight the selected objects in the scene. */
|
|
382
|
-
@property({ attribute: 'hover-highlight-color' })
|
|
383
|
-
hoverHighlightColor?: string;
|
|
384
|
-
|
|
385
|
-
/** Enables drawing highlighted objects in front of all objects in the scene. This results in faster rendering in a 2D viewport when using the `THREEJS` renderer. */
|
|
386
|
-
@property({ attribute: 'hover-highlight-layer-enable', type: Boolean })
|
|
387
|
-
hoverHighlightLayerEnable?: boolean;
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Enable the transform interactor. Only available when `renderer` is `THREEJS`
|
|
391
|
-
*
|
|
392
|
-
* Create an interactor for transforming a particular scene object on the client.
|
|
393
|
-
* Use the IGoRenderer.addInteractor() method on the server to select which object to transform.
|
|
394
|
-
*/
|
|
395
|
-
@property({ attribute: 'transform-enable', type: Boolean })
|
|
396
|
-
transformEnable?: boolean;
|
|
397
|
-
|
|
398
|
-
/** Transform on the client only, do not update the transform matrix on the server. */
|
|
399
|
-
@property({ attribute: 'transform-client-only', type: Boolean })
|
|
400
|
-
transformClientOnly?: boolean;
|
|
401
|
-
|
|
402
|
-
/** Disables rotation of the object. */
|
|
403
|
-
@property({ attribute: 'transform-rotate-disable', type: Boolean })
|
|
404
|
-
transformRotateDisable?: boolean;
|
|
405
|
-
|
|
406
|
-
/** Disables zooming of the object. */
|
|
407
|
-
@property({ attribute: 'transform-zoom-disable', type: Boolean })
|
|
408
|
-
transformZoomDisable?: boolean;
|
|
409
|
-
|
|
410
|
-
/** Disables panning of the object. */
|
|
411
|
-
@property({ attribute: 'transform-pan-disable', type: Boolean })
|
|
412
|
-
transformPanDisable?: boolean;
|
|
413
|
-
|
|
414
|
-
/** The twist angle of the object in degrees. */
|
|
415
|
-
@property({ attribute: 'transform-twist-angle' })
|
|
416
|
-
transformTwistAngle?: number;
|
|
417
|
-
|
|
418
|
-
/** The tilt angle of the object in degrees. */
|
|
419
|
-
@property({ attribute: 'transform-tilt-angle' })
|
|
420
|
-
transformTiltAngle?: number;
|
|
421
|
-
|
|
422
|
-
/** The scale of the object in percent. */
|
|
423
|
-
@property({ attribute: 'transform-scale' })
|
|
424
|
-
transformScale?: number;
|
|
425
|
-
|
|
426
|
-
/** Motion capture data or URL. */
|
|
427
|
-
@property({ attribute: 'motion-capture' })
|
|
428
|
-
motionCapture?: string;
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Enable the zoom rectangle interactor. Only available when `renderer` is `THREEJS`
|
|
432
|
-
*
|
|
433
|
-
* Create an interactor for scaling an object by drawing a rectangle.
|
|
434
|
-
* Use the IGoRenderer.addInteractor() method on the server to select which object to transform.
|
|
435
|
-
*/
|
|
436
|
-
@property({ attribute: 'zoom-rectangle-enable', type: Boolean })
|
|
437
|
-
zoomRectangleEnable?: boolean;
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* Enable the pan interactor. Only available when `renderer` is `THREEJS`
|
|
441
|
-
*
|
|
442
|
-
* Create an interactor for panning an OpenViz domain (axes and charts) on the client.
|
|
443
|
-
*/
|
|
444
|
-
@property({ attribute: 'pan-enable', type: Boolean })
|
|
445
|
-
panEnable?: boolean;
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Use mousewheel or pinch zoom to adjust the pan interactor's zoom level.
|
|
449
|
-
* Otherwise the zoom level must be set using `pan-width-zoom-level` and `pan-height-zoom-level`.
|
|
450
|
-
*/
|
|
451
|
-
@property({ attribute: 'pan-zoom-enable', type: Boolean })
|
|
452
|
-
panZoomEnable?: boolean;
|
|
453
|
-
|
|
454
|
-
/** The width zoom level in percent of the original scene greater than 100% */
|
|
455
|
-
@property({ attribute: 'pan-width-zoom-level' })
|
|
456
|
-
panWidthZoomLevel?: number;
|
|
457
|
-
|
|
458
|
-
/** The height zoom level in percent of the original scene greater than 100% */
|
|
459
|
-
@property({ attribute: 'pan-height-zoom-level' })
|
|
460
|
-
panHeightZoomLevel?: number;
|
|
461
|
-
|
|
462
|
-
/** The maximum zoom level in percent of the original scene greater than 100% Default is 1000% */
|
|
463
|
-
@property({ attribute: 'pan-maximum-zoom-level' })
|
|
464
|
-
panMaximumZoomLevel?: number;
|
|
465
|
-
|
|
466
|
-
/** Show animated glyphs. Only available when `renderer` is `THREEJS` */
|
|
467
|
-
@property({ attribute: 'animated-glyphs-visible', type: Boolean })
|
|
468
|
-
animatedGlyphsVisible?: boolean;
|
|
469
|
-
|
|
470
|
-
/** Enable animated glyphs. Only available when `renderer` is `THREEJS` */
|
|
471
|
-
@property({ attribute: 'animated-glyphs-enable', type: Boolean })
|
|
472
|
-
animatedGlyphsEnable?: boolean;
|
|
473
|
-
|
|
474
|
-
/** Enable motion capture controls. Only available when `renderer` is `THREEJS` */
|
|
475
|
-
@property({ attribute: 'motion-capture-controls-enable', type: Boolean })
|
|
476
|
-
motionCaptureControlsEnable?: boolean;
|
|
477
|
-
|
|
478
|
-
// Local variables
|
|
479
|
-
width: number;
|
|
480
|
-
height: number;
|
|
481
|
-
lowResizeWidth: number;
|
|
482
|
-
highResizeWidth: number;
|
|
483
|
-
lowResizeHeight: number;
|
|
484
|
-
highResizeHeight: number;
|
|
485
|
-
forceUpdate: boolean;
|
|
486
|
-
chunkFile: number;
|
|
487
|
-
model: DataVizModel;
|
|
488
|
-
tapping: boolean;
|
|
489
|
-
tracking: number;
|
|
490
|
-
threeViewer: Viewer;
|
|
491
|
-
transformInteractor: TransformInteractor;
|
|
492
|
-
transformMatrix: Array<number>;
|
|
493
|
-
animator: Animator;
|
|
494
|
-
panInteractor: PanInteractor;
|
|
495
|
-
zoomRectangleInteractor: ZoomRectangleInteractor;
|
|
496
|
-
highlightSvg: Array<any>;
|
|
497
|
-
pointerDown: boolean;
|
|
498
|
-
pointerDownX: number;
|
|
499
|
-
pointerDownY: number;
|
|
500
|
-
imageMapData: Array<any>;
|
|
501
|
-
rectCanvas: HTMLCanvasElement;
|
|
502
|
-
rectCtx: CanvasRenderingContext2D;
|
|
503
|
-
sceneImage: HTMLImageElement;
|
|
504
|
-
sceneImageMap: HTMLMapElement;
|
|
505
|
-
svgDiv: HTMLDivElement;
|
|
506
|
-
motionCaptureDelay: number;
|
|
507
|
-
motionCaptureTime: number;
|
|
508
|
-
motionCaptureFrames: Array<MotionCaptureFrame>;
|
|
509
|
-
showMotionCaptureTooltip: boolean;
|
|
510
|
-
zoomOverlayTimeoutId: number;
|
|
511
|
-
timer: number;
|
|
512
|
-
|
|
513
|
-
/**
|
|
514
|
-
* Default line style and color
|
|
515
|
-
*/
|
|
516
|
-
_rectangleStyle() {
|
|
517
|
-
this.rectCtx.setLineDash([3]);
|
|
518
|
-
this.rectCtx.strokeStyle="#ff0000";
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Assemble the model from our properties to send to the server.
|
|
523
|
-
*/
|
|
524
|
-
_assembleModel(fullReset?: boolean): DataVizModel {
|
|
525
|
-
if (!this.sceneName) {
|
|
526
|
-
this._dispatchErrorEvent("'scene-name' property must be set to the name of the scene registered in the library map on the AVS/Go server.");
|
|
527
|
-
return undefined;
|
|
528
|
-
}
|
|
529
|
-
if (!this.width || !this.height) {
|
|
530
|
-
return undefined;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
// Scene Properties
|
|
534
|
-
const model: DataVizModel = {
|
|
535
|
-
sceneProperties: {
|
|
536
|
-
name: this.sceneName
|
|
537
|
-
}
|
|
538
|
-
};
|
|
539
|
-
if (this.sceneUserProperties) {
|
|
540
|
-
let sceneUserProperties;
|
|
541
|
-
try {
|
|
542
|
-
sceneUserProperties = JSON.parse(this.sceneUserProperties);
|
|
543
|
-
}
|
|
544
|
-
catch (error) {
|
|
545
|
-
this._dispatchErrorEvent("Can't parse 'scene-user-properties'. " + error.message);
|
|
546
|
-
return undefined;
|
|
547
|
-
}
|
|
548
|
-
model.sceneProperties.userProperties = sceneUserProperties;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// Renderer Properties
|
|
552
|
-
const rendererProperties: RendererProperties = {
|
|
553
|
-
width: this.width,
|
|
554
|
-
height: this.height,
|
|
555
|
-
name: this.rendererName,
|
|
556
|
-
type: this.renderer
|
|
557
|
-
};
|
|
558
|
-
if (this.rendererUserProperties) {
|
|
559
|
-
let rendererUserProperties;
|
|
560
|
-
try {
|
|
561
|
-
rendererUserProperties = JSON.parse(this.rendererUserProperties);
|
|
562
|
-
}
|
|
563
|
-
catch (error) {
|
|
564
|
-
this._dispatchErrorEvent("Can't parse 'renderer-user-properties'. " + error.message);
|
|
565
|
-
return undefined;
|
|
566
|
-
}
|
|
567
|
-
rendererProperties.userProperties = rendererUserProperties;
|
|
568
|
-
}
|
|
569
|
-
model.rendererProperties = rendererProperties;
|
|
570
|
-
|
|
571
|
-
// Transform Properties
|
|
572
|
-
if (this.transformInteractor) {
|
|
573
|
-
// Update the local transform matrix from the transform interactor, we may have transformed since the last request
|
|
574
|
-
this.transformMatrix = this.transformInteractor.object.matrix.elements.slice();
|
|
575
|
-
// this.transformClientOnly = this.transformInteractor.clientOnly;
|
|
576
|
-
}
|
|
577
|
-
if (this.transformMatrix && !this.transformClientOnly) {
|
|
578
|
-
rendererProperties.transformMatrix = this.transformMatrix;
|
|
579
|
-
}
|
|
580
|
-
if (fullReset) {
|
|
581
|
-
if (this.transformClientOnly && this.transformInteractor) {
|
|
582
|
-
this.transformInteractor.fullReset = fullReset;
|
|
583
|
-
}
|
|
584
|
-
else {
|
|
585
|
-
rendererProperties.fullReset = true;
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
// PanInteractor
|
|
590
|
-
if (this.panEnable) {
|
|
591
|
-
rendererProperties.panProperties = {
|
|
592
|
-
widthZoomLevel: Math.min(this.panWidthZoomLevel, this.panMaximumZoomLevel),
|
|
593
|
-
heightZoomLevel: Math.min(this.panHeightZoomLevel, this.panMaximumZoomLevel)
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
// Base theme to use from themeName property
|
|
598
|
-
rendererProperties.themeName = this.themeName;
|
|
599
|
-
|
|
600
|
-
var style = window.getComputedStyle(this, null);
|
|
601
|
-
|
|
602
|
-
// Theme Properties from page CSS
|
|
603
|
-
var cssBackgroundColor = style.getPropertyValue("background-color").trim();
|
|
604
|
-
var cssColor = style.getPropertyValue("color").trim();
|
|
605
|
-
var cssFontFamily = style.getPropertyValue("font-family").trim().replace(/['"]+/g, '');
|
|
606
|
-
rendererProperties.cssProperties = {
|
|
607
|
-
sceneBackgroundType: "Solid",
|
|
608
|
-
sceneBackgroundColor: cssBackgroundColor,
|
|
609
|
-
sceneLineColor: cssColor,
|
|
610
|
-
sceneTextColor: cssColor,
|
|
611
|
-
sceneFontFamily: cssFontFamily,
|
|
612
|
-
sceneSurfaceColor: cssColor
|
|
613
|
-
};
|
|
614
|
-
|
|
615
|
-
// Theme Properties from custom CSS
|
|
616
|
-
this._applyCustomCssProperties(rendererProperties.cssProperties, style,
|
|
617
|
-
{
|
|
618
|
-
// Scene
|
|
619
|
-
"sceneBackgroundType": "--avs-scene-background-type",
|
|
620
|
-
"sceneBackgroundColor": "--avs-scene-background-color",
|
|
621
|
-
"sceneBackgroundStartColor": "--avs-scene-background-start-color",
|
|
622
|
-
"sceneBackgroundEndColor": "--avs-scene-background-end-color",
|
|
623
|
-
"sceneBackgroundGradientStyle": "--avs-scene-background-gradient-style",
|
|
624
|
-
"sceneBackgroundGradientInterpolation": "--avs-scene-background-gradient-interpolation",
|
|
625
|
-
"sceneBackgroundGradientColorRepeat": "--avs-scene-background-gradient-color-repeat",
|
|
626
|
-
"sceneHighlightColor": "--avs-scene-highlight-color",
|
|
627
|
-
"sceneSurfaceColor": "--avs-scene-surface-color",
|
|
628
|
-
"scenePointColor": "--avs-scene-point-color",
|
|
629
|
-
"sceneLineColor": "--avs-scene-line-color",
|
|
630
|
-
"sceneLineWidth": "--avs-scene-line-width",
|
|
631
|
-
"sceneTextColor": "--avs-scene-text-color",
|
|
632
|
-
"sceneTextRotation": "--avs-scene-text-rotation",
|
|
633
|
-
"sceneFontFamily": "--avs-scene-font-family",
|
|
634
|
-
"sceneFontStyle": "--avs-scene-font-style",
|
|
635
|
-
"sceneFontWeight": "--avs-scene-font-weight",
|
|
636
|
-
"sceneFontSize": "--avs-scene-font-size",
|
|
637
|
-
// Scene title
|
|
638
|
-
"sceneTitleTextColor": "--avs-scene-title-text-color",
|
|
639
|
-
"sceneTitleTextRotation": "--avs-scene-title-text-rotation",
|
|
640
|
-
"sceneTitleFontFamily": "--avs-scene-title-font-family",
|
|
641
|
-
"sceneTitleFontStyle": "--avs-scene-title-font-style",
|
|
642
|
-
"sceneTitleFontWeight": "--avs-scene-title-font-weight",
|
|
643
|
-
"sceneTitleFontSize": "--avs-scene-title-font-size",
|
|
644
|
-
// Chart
|
|
645
|
-
"chartBackgroundType": "--avs-chart-background-type",
|
|
646
|
-
"chartBackgroundColor": "--avs-chart-background-color",
|
|
647
|
-
"chartBackgroundStartColor": "--avs-chart-background-start-color",
|
|
648
|
-
"chartBackgroundEndColor": "--avs-chart-background-end-color",
|
|
649
|
-
"chartBackgroundGradientStyle": "--avs-chart-background-gradient-style",
|
|
650
|
-
"chartBackgroundGradientInterpolation": "--avs-chart-background-gradient-interpolation",
|
|
651
|
-
"chartBackgroundGradientColorRepeat": "--avs-chart-background-gradient-color-repeat",
|
|
652
|
-
"chartHighlightColor": "--avs-chart-highlight-color",
|
|
653
|
-
"chartSurfaceColor": "--avs-chart-surface-color",
|
|
654
|
-
"chartPointColor": "--avs-chart-point-color",
|
|
655
|
-
"chartLineColor": "--avs-chart-line-color",
|
|
656
|
-
"chartLineWidth": "--avs-chart-line-width",
|
|
657
|
-
"chartLinePattern": "--avs-chart-line-pattern",
|
|
658
|
-
"chartTextColor": "--avs-chart-text-color",
|
|
659
|
-
"chartTextRotation": "--avs-chart-text-rotation",
|
|
660
|
-
"chartFontFamily": "--avs-chart-font-family",
|
|
661
|
-
"chartFontStyle": "--avs-chart-font-style",
|
|
662
|
-
"chartFontWeight": "--avs-chart-font-weight",
|
|
663
|
-
"chartFontSize": "--avs-chart-font-size",
|
|
664
|
-
// Chart title
|
|
665
|
-
"chartTitleTextColor": "--avs-chart-title-text-color",
|
|
666
|
-
"chartTitleTextRotation": "--avs-chart-title-text-rotation",
|
|
667
|
-
"chartTitleFontFamily": "--avs-chart-title-font-family",
|
|
668
|
-
"chartTitleFontStyle": "--avs-chart-title-font-style",
|
|
669
|
-
"chartTitleFontWeight": "--avs-chart-title-font-weight",
|
|
670
|
-
"chartTitleFontSize": "--avs-chart-title-font-size",
|
|
671
|
-
// Axis
|
|
672
|
-
"axisLineColor": "--avs-axis-line-color",
|
|
673
|
-
"axisLineWidth": "--avs-axis-line-width",
|
|
674
|
-
"axisTextColor": "--avs-axis-text-color",
|
|
675
|
-
"axisTextRotation": "--avs-axis-text-rotation",
|
|
676
|
-
"axisFontFamily": "--avs-axis-font-family",
|
|
677
|
-
"axisFontStyle": "--avs-axis-font-style",
|
|
678
|
-
"axisFontWeight": "--avs-axis-font-weight",
|
|
679
|
-
"axisFontSize": "--avs-axis-font-size",
|
|
680
|
-
// Axis axle
|
|
681
|
-
"axisAxleColor": "--avs-axis-axle-color",
|
|
682
|
-
"axisAxleWidth": "--avs-axis-axle-width",
|
|
683
|
-
// Axis major tick marks
|
|
684
|
-
"axisMajorTickMarkColor": "--avs-axis-major-tick-mark-color",
|
|
685
|
-
"axisMajorTickMarkWidth": "--avs-axis-major-tick-mark-width",
|
|
686
|
-
// Axis major tick lines
|
|
687
|
-
"axisMajorTickLineColor": "--avs-axis-major-tick-line-color",
|
|
688
|
-
"axisMajorTickLineWidth": "--avs-axis-major-tick-line-width",
|
|
689
|
-
"axisMajorTickLineStyle": "--avs-axis-major-tick-line-style",
|
|
690
|
-
// Axis major unlabeled tick marks
|
|
691
|
-
"axisMajorUnlabeledTickMarkColor": "--avs-axis-major-unlabeled-tick-mark-color",
|
|
692
|
-
"axisMajorUnlabeledTickMarkWidth": "--avs-axis-major-unlabeled-tick-mark-width",
|
|
693
|
-
// Axis major unlabeled tick lines
|
|
694
|
-
"axisMajorUnlabeledTickLineColor": "--avs-axis-major-unlabeled-tick-line-color",
|
|
695
|
-
"axisMajorUnlabeledTickLineWidth": "--avs-axis-major-unlabeled-tick-line-width",
|
|
696
|
-
"axisMajorUnlabeledTickLineStyle": "--avs-axis-major-unlabeled-tick-line-style",
|
|
697
|
-
// Axis minor tick marks
|
|
698
|
-
"axisMinorTickMarkColor": "--avs-axis-minor-tick-mark-color",
|
|
699
|
-
"axisMinorTickMarkWidth": "--avs-axis-minor-tick-mark-width",
|
|
700
|
-
// Axis minor tick lines
|
|
701
|
-
"axisMinorTickLineColor": "--avs-axis-minor-tick-line-color",
|
|
702
|
-
"axisMinorTickLineWidth": "--avs-axis-minor-tick-line-width",
|
|
703
|
-
"axisMinorTickLineStyle": "--avs-axis-minor-tick-line-style",
|
|
704
|
-
// Axis title
|
|
705
|
-
"axisTitleTextColor": "--avs-axis-title-text-color",
|
|
706
|
-
"axisTitleTextRotation": "--avs-axis-title-text-rotation",
|
|
707
|
-
"axisTitleFontFamily": "--avs-axis-title-font-family",
|
|
708
|
-
"axisTitleFontStyle": "--avs-axis-title-font-style",
|
|
709
|
-
"axisTitleFontWeight": "--avs-axis-title-font-weight",
|
|
710
|
-
"axisTitleFontSize": "--avs-axis-title-font-size",
|
|
711
|
-
// Axis unit
|
|
712
|
-
"axisUnitTextColor": "--avs-axis-unit-text-color",
|
|
713
|
-
"axisUnitTextRotation": "--avs-axis-unit-text-rotation",
|
|
714
|
-
"axisUnitFontFamily": "--avs-axis-unit-font-family",
|
|
715
|
-
"axisUnitFontStyle": "--avs-axis-unit-font-style",
|
|
716
|
-
"axisUnitFontWeight": "--avs-axis-unit-font-weight",
|
|
717
|
-
"axisUnitFontSize": "--avs-axis-unit-font-size",
|
|
718
|
-
// Axis labels
|
|
719
|
-
"axisLabelTextColor": "--avs-axis-label-text-color",
|
|
720
|
-
"axisLabelTextRotation": "--avs-axis-label-text-rotation",
|
|
721
|
-
"axisLabelFontFamily": "--avs-axis-label-font-family",
|
|
722
|
-
"axisLabelFontStyle": "--avs-axis-label-font-style",
|
|
723
|
-
"axisLabelFontWeight": "--avs-axis-label-font-weight",
|
|
724
|
-
"axisLabelFontSize": "--avs-axis-label-font-size",
|
|
725
|
-
// Legend
|
|
726
|
-
"legendBackgroundColor": "--avs-legend-background-color",
|
|
727
|
-
"legendTextColor": "--avs-legend-text-color",
|
|
728
|
-
"legendTextRotation": "--avs-legend-text-rotation",
|
|
729
|
-
"legendFontFamily": "--avs-legend-font-family",
|
|
730
|
-
"legendFontStyle": "--avs-legend-font-style",
|
|
731
|
-
"legendFontWeight": "--avs-legend-font-weight",
|
|
732
|
-
"legendFontSize": "--avs-legend-font-size",
|
|
733
|
-
"legendPointColor": "--avs-legend-point-color",
|
|
734
|
-
// Legend title
|
|
735
|
-
"legendTitleTextColor": "--avs-legend-title-text-color",
|
|
736
|
-
"legendTitleTextRotation": "--avs-legend-title-text-rotation",
|
|
737
|
-
"legendTitleFontFamily": "--avs-legend-title-font-family",
|
|
738
|
-
"legendTitleFontStyle": "--avs-legend-title-font-style",
|
|
739
|
-
"legendTitleFontWeight": "--avs-legend-title-font-weight",
|
|
740
|
-
"legendTitleFontSize": "--avs-legend-title-font-size"
|
|
741
|
-
} );
|
|
742
|
-
|
|
743
|
-
// Data source properties
|
|
744
|
-
if (this.dataSourceName) {
|
|
745
|
-
model.dataSourceProperties = {
|
|
746
|
-
name: this.dataSourceName
|
|
747
|
-
}
|
|
748
|
-
if (this.dataSourceUserProperties) {
|
|
749
|
-
let dataSourceUserProperties;
|
|
750
|
-
try {
|
|
751
|
-
dataSourceUserProperties = JSON.parse(this.dataSourceUserProperties);
|
|
752
|
-
}
|
|
753
|
-
catch (error) {
|
|
754
|
-
this._dispatchErrorEvent("Can't parse 'data-source-user-properties'. " + error.message);
|
|
755
|
-
return undefined;
|
|
756
|
-
}
|
|
757
|
-
model.dataSourceProperties.userProperties = dataSourceUserProperties;
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
// Stream properties
|
|
762
|
-
if (this.threeViewer) {
|
|
763
|
-
if (this.streamEnable) {
|
|
764
|
-
rendererProperties.streamProperties = {
|
|
765
|
-
chunkSizeFirst: this.streamChunkSizeFirst,
|
|
766
|
-
chunkSize: this.streamChunkSize
|
|
767
|
-
};
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
return model;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
/**
|
|
775
|
-
*
|
|
776
|
-
*/
|
|
777
|
-
_applyCustomCssProperties(cssProperties, style, values) {
|
|
778
|
-
for (var key in values) {
|
|
779
|
-
if (values.hasOwnProperty(key)) {
|
|
780
|
-
var css = style.getPropertyValue(values[key]).trim();
|
|
781
|
-
if (css.length > 0) {
|
|
782
|
-
cssProperties[key] = css;
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
/**
|
|
789
|
-
*
|
|
790
|
-
*/
|
|
791
|
-
_onResize(contentRect: DOMRect) {
|
|
792
|
-
// Get the width & height provided by our container
|
|
793
|
-
this.width = Math.round(contentRect.width);
|
|
794
|
-
this.height = Math.round(contentRect.height);
|
|
795
|
-
|
|
796
|
-
if (this.rectCanvas) {
|
|
797
|
-
this.rectCanvas.width = this.width;
|
|
798
|
-
this.rectCanvas.height = this.height;
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
// Check if we need to acquire a new scene due to
|
|
802
|
-
// the size change and other properties
|
|
803
|
-
if (!this.urlLoadJsonFile &&
|
|
804
|
-
!this.manualUpdate &&
|
|
805
|
-
this.resizeThreshold > 0 &&
|
|
806
|
-
(!this.lowResizeWidth ||
|
|
807
|
-
this.width < this.lowResizeWidth ||
|
|
808
|
-
this.width > this.highResizeWidth ||
|
|
809
|
-
this.height < this.lowResizeHeight ||
|
|
810
|
-
this.height > this.highResizeHeight)) {
|
|
811
|
-
|
|
812
|
-
this._updateResizeLimits();
|
|
813
|
-
this.updateViewer();
|
|
814
|
-
}
|
|
815
|
-
else {
|
|
816
|
-
if (this.threeViewer) {
|
|
817
|
-
this.threeViewer.render(true);
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
_updateResizeLimits() {
|
|
823
|
-
this.lowResizeWidth = (100 - this.resizeThreshold) / 100 * this.width;
|
|
824
|
-
this.highResizeWidth = (100 + this.resizeThreshold) / 100 * this.width;
|
|
825
|
-
this.lowResizeHeight = (100 - this.resizeThreshold) / 100 * this.height;
|
|
826
|
-
this.highResizeHeight = (100 + this.resizeThreshold) / 100 * this.height;
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
showSpinner() {
|
|
830
|
-
var spinner = window.getComputedStyle(this, null).getPropertyValue("--avs-spinner").trim().replace(/['"]+/g, '');
|
|
831
|
-
if (spinner.length > 0) {
|
|
832
|
-
fetch(spinner)
|
|
833
|
-
.then((response) => {
|
|
834
|
-
if (response.ok) {
|
|
835
|
-
return response.text();
|
|
836
|
-
}
|
|
837
|
-
})
|
|
838
|
-
.then((html) => {
|
|
839
|
-
this.renderRoot.querySelector('#spinner').innerHTML = html;
|
|
840
|
-
})
|
|
841
|
-
.catch((error) => {
|
|
842
|
-
this.renderRoot.querySelector('#spinner').innerHTML = AVS;
|
|
843
|
-
});
|
|
844
|
-
}
|
|
845
|
-
else {
|
|
846
|
-
this.renderRoot.querySelector('#spinner').innerHTML = AVS;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
const spinnerEl = this.renderRoot.querySelector('#spinner') as HTMLDivElement;
|
|
850
|
-
spinnerEl.style.display = 'block';
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
hideSpinner() {
|
|
854
|
-
const spinnerEl = this.renderRoot.querySelector('#spinner') as HTMLDivElement;
|
|
855
|
-
spinnerEl.style.display = 'none';
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
startSpinner() {
|
|
859
|
-
this.renderRoot.querySelector('#spinner').className = 'spin';
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
stopSpinner() {
|
|
863
|
-
this.renderRoot.querySelector('#spinner').className = '';
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
/**
|
|
867
|
-
* At least one of the properties was changed.
|
|
868
|
-
*/
|
|
869
|
-
updated(changedProperties: PropertyValues<this>) {
|
|
870
|
-
if (!Object.values(Renderer)?.includes(this.renderer)) {
|
|
871
|
-
this._dispatchErrorEvent("'renderer' property must be 'IMAGE', 'SVG' or 'THREEJS'.");
|
|
872
|
-
return;
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
if (changedProperties.has('renderer')) {
|
|
876
|
-
this._rendererChanged(this.renderer, changedProperties['renderer']);
|
|
877
|
-
}
|
|
878
|
-
if (changedProperties.has('transformEnable')) {
|
|
879
|
-
this._transformEnableChanged(this.transformEnable, changedProperties['transformEnable']);
|
|
880
|
-
}
|
|
881
|
-
if (changedProperties.has('transformClientOnly')) {
|
|
882
|
-
this._transformClientOnlyChanged(this.transformClientOnly, changedProperties['transformClientOnly']);
|
|
883
|
-
}
|
|
884
|
-
if (changedProperties.has('transformRotateDisable')) {
|
|
885
|
-
this._transformRotateDisableChanged(this.transformRotateDisable, changedProperties['transformRotateDisable']);
|
|
886
|
-
}
|
|
887
|
-
if (changedProperties.has('transformZoomDisable')) {
|
|
888
|
-
this._transformZoomDisableChanged(this.transformZoomDisable, changedProperties['transformZoomDisable']);
|
|
889
|
-
}
|
|
890
|
-
if (changedProperties.has('transformPanDisable')) {
|
|
891
|
-
this._transformPanDisableChanged(this.transformPanDisable, changedProperties['transformPanDisable']);
|
|
892
|
-
}
|
|
893
|
-
if (changedProperties.has('animatedGlyphsVisible')) {
|
|
894
|
-
this._animatedGlyphsVisibleChanged(this.animatedGlyphsVisible, changedProperties['animatedGlyphsVisible']);
|
|
895
|
-
}
|
|
896
|
-
if (changedProperties.has('animatedGlyphsEnable')) {
|
|
897
|
-
this._animatedGlyphsEnableChanged(this.animatedGlyphsEnable, changedProperties['animatedGlyphsEnable']);
|
|
898
|
-
}
|
|
899
|
-
if (changedProperties.has('transformTwistAngle') || changedProperties.has('transformTiltAngle') || changedProperties.has('transformScale')) {
|
|
900
|
-
this._transformValueChanged();
|
|
901
|
-
}
|
|
902
|
-
if (changedProperties.has('animatedGlyphsEnable')) {
|
|
903
|
-
this._animatedGlyphsEnableChanged(this.animatedGlyphsEnable, changedProperties['animatedGlyphsEnable']);
|
|
904
|
-
}
|
|
905
|
-
if (changedProperties.has('zoomRectangleEnable')) {
|
|
906
|
-
this._zoomRectangleEnableChanged(this.zoomRectangleEnable, changedProperties['zoomRectangleEnable']);
|
|
907
|
-
}
|
|
908
|
-
if (changedProperties.has('panEnable')) {
|
|
909
|
-
this._panEnableChanged(this.panEnable, changedProperties['panEnable']);
|
|
910
|
-
}
|
|
911
|
-
if (changedProperties.has('panZoomEnable')) {
|
|
912
|
-
this._panZoomEnableChanged(this.panZoomEnable, changedProperties['panZoomEnable']);
|
|
913
|
-
}
|
|
914
|
-
if (changedProperties.has('panWidthZoomLevel')) {
|
|
915
|
-
this._panWidthZoomLevelChanged(this.panWidthZoomLevel, changedProperties['panWidthZoomLevel']);
|
|
916
|
-
}
|
|
917
|
-
if (changedProperties.has('panHeightZoomLevel')) {
|
|
918
|
-
this._panHeightZoomLevelChanged(this.panHeightZoomLevel, changedProperties['panHeightZoomLevel']);
|
|
919
|
-
}
|
|
920
|
-
if (changedProperties.has('panMaximumZoomLevel')) {
|
|
921
|
-
this._panMaximumZoomLevelChanged(this.panMaximumZoomLevel, changedProperties['panMaximumZoomLevel']);
|
|
922
|
-
}
|
|
923
|
-
if (changedProperties.has('trackEnable')) {
|
|
924
|
-
this._trackEnableChanged(this.trackEnable, changedProperties['trackEnable']);
|
|
925
|
-
}
|
|
926
|
-
if (changedProperties.has('displayCanvas')) {
|
|
927
|
-
this._displayCanvasChanged(this.displayCanvas, changedProperties['displayCanvas']);
|
|
928
|
-
}
|
|
929
|
-
if (changedProperties.has('motionCaptureControlsEnable')) {
|
|
930
|
-
this._motionCaptureControlsEnableChanged(this.motionCaptureControlsEnable, changedProperties['motionCaptureControlsEnable']);
|
|
931
|
-
}
|
|
932
|
-
if (changedProperties.has('motionCapture')) {
|
|
933
|
-
this._motionCaptureValueChanged(this.motionCapture, changedProperties['motionCapture']);
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
if (!this.url) {
|
|
937
|
-
//this._dispatchErrorEvent(''url' property must point to an instance of AVS/Go server.');
|
|
938
|
-
return;
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
let doUpdate = false;
|
|
942
|
-
if (this.manualUpdate) {
|
|
943
|
-
if (this.forceUpdate) {
|
|
944
|
-
doUpdate = true;
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
else {
|
|
948
|
-
if (this.forceUpdate ||
|
|
949
|
-
changedProperties.has('url') ||
|
|
950
|
-
changedProperties.has('renderer') ||
|
|
951
|
-
changedProperties.has('urlLoadJsonFile') ||
|
|
952
|
-
changedProperties.has('sceneName') ||
|
|
953
|
-
changedProperties.has('sceneUserProperties') ||
|
|
954
|
-
changedProperties.has('dataSourceName') ||
|
|
955
|
-
changedProperties.has('dataSourceUserProperties') ||
|
|
956
|
-
changedProperties.has('rendererName') ||
|
|
957
|
-
changedProperties.has('rendererUserProperties') ||
|
|
958
|
-
changedProperties.has('streamEnable') ||
|
|
959
|
-
(this.panEnable && changedProperties.has('panWidthZoomLevel')) ||
|
|
960
|
-
(this.panEnable && changedProperties.has('panHeightZoomLevel'))) {
|
|
961
|
-
doUpdate = true;
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
if (doUpdate) {
|
|
966
|
-
this.forceUpdate = false;
|
|
967
|
-
|
|
968
|
-
// Send the model to the server
|
|
969
|
-
if (this.urlLoadJsonFile) {
|
|
970
|
-
this.chunkFile = 0;
|
|
971
|
-
this.showSpinner();
|
|
972
|
-
this.startSpinner();
|
|
973
|
-
this._httpRequest(this.url, this._handleHttpResponse.bind(this), this._handleHttpError.bind(this));
|
|
974
|
-
}
|
|
975
|
-
else {
|
|
976
|
-
this.model = this._assembleModel(/*fullReset*/);
|
|
977
|
-
if (this.model) {
|
|
978
|
-
this.showSpinner();
|
|
979
|
-
this.startSpinner();
|
|
980
|
-
this._httpRequest(this.url, this._handleHttpResponse.bind(this), this._handleHttpError.bind(this), this.model);
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
/**
|
|
987
|
-
* HTTP error handler.
|
|
988
|
-
*/
|
|
989
|
-
_handleHttpError() {
|
|
990
|
-
this.hideSpinner();
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
/**
|
|
994
|
-
*
|
|
995
|
-
*/
|
|
996
|
-
updateViewer() {
|
|
997
|
-
this.forceUpdate = true;
|
|
998
|
-
this.requestUpdate();
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
/**
|
|
1002
|
-
*
|
|
1003
|
-
*/
|
|
1004
|
-
clear() {
|
|
1005
|
-
if (this.threeViewer) {
|
|
1006
|
-
this.threeViewer.clearGeometry();
|
|
1007
|
-
this.threeViewer.render();
|
|
1008
|
-
}
|
|
1009
|
-
else if (this.renderer === 'SVG') {
|
|
1010
|
-
var el = this.svgDiv;
|
|
1011
|
-
while (el.firstChild) el.removeChild(el.firstChild);
|
|
1012
|
-
}
|
|
1013
|
-
else {
|
|
1014
|
-
this.sceneImage.src = 'data:,';
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
this.showSpinner();
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
/**
|
|
1021
|
-
* HTTP response handler.
|
|
1022
|
-
* @param response Response parsed from HTTP or file.
|
|
1023
|
-
*/
|
|
1024
|
-
_handleHttpResponse(response: DataVizResponse) {
|
|
1025
|
-
if (response) {
|
|
1026
|
-
if (response.selectionInfo) {
|
|
1027
|
-
this._dispatchPickEvents(response.selectionInfo);
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
if (response.sceneInfo) {
|
|
1031
|
-
/**
|
|
1032
|
-
* Scene info from the server.
|
|
1033
|
-
* @event avs-scene-info
|
|
1034
|
-
*/
|
|
1035
|
-
this.dispatchEvent(new CustomEvent('avs-scene-info', { detail: response.sceneInfo }));
|
|
1036
|
-
|
|
1037
|
-
const motionCapture = this.renderRoot.querySelector('#motionCapture') as HTMLDivElement;
|
|
1038
|
-
const zoomOverlay = this.renderRoot.querySelector('#zoomOverlay') as HTMLDivElement;
|
|
1039
|
-
const tooltip = this.renderRoot.querySelector('#tooltip') as HTMLDivElement;
|
|
1040
|
-
const motionCaptureTooltip = this.renderRoot.querySelector('#motionCaptureTooltip') as HTMLDivElement;
|
|
1041
|
-
|
|
1042
|
-
// Set animation controls, tooltip and zoom overlay style to reversed theme
|
|
1043
|
-
if (response.sceneInfo.backgroundColor) {
|
|
1044
|
-
var col = response.sceneInfo.backgroundColor.match(/[0-9.]+/gi);
|
|
1045
|
-
var bgCol = this.getInheritedBackgroundCol(this).trim().match(/[0-9.]+/gi);
|
|
1046
|
-
var blendedR = (Number(col[0]) * Number(col[3]));
|
|
1047
|
-
var blendedG = (Number(col[1]) * Number(col[3]));
|
|
1048
|
-
var blendedB = (Number(col[2]) * Number(col[3]));
|
|
1049
|
-
if (Number(col[3]) == 0) {
|
|
1050
|
-
// In case sceneInfo.backgroundColor is transparent, blend with inherited background color
|
|
1051
|
-
blendedR += (bgCol[0] * (1 - Number(col[3])));
|
|
1052
|
-
blendedG += (bgCol[1] * (1 - Number(col[3])));
|
|
1053
|
-
blendedB += (bgCol[2] * (1 - Number(col[3])));
|
|
1054
|
-
}
|
|
1055
|
-
motionCapture.style.color = "var(--avs-motion-capture-color, rgb(" + blendedR + ", " + blendedG + ", " + blendedB + "))";
|
|
1056
|
-
zoomOverlay.style.color = "var(--avs-zoom-overlay-color, rgb(" + blendedR + "," + blendedG + "," + blendedB + "))";
|
|
1057
|
-
tooltip.style.color = "var(--avs-tooltip-color, rgb(" + blendedR + "," + blendedG + "," + blendedB + "))";
|
|
1058
|
-
motionCaptureTooltip.style.color = "var(--avs-tooltip-color, rgb(" + blendedR + "," + blendedG + "," + blendedB + "))";
|
|
1059
|
-
}
|
|
1060
|
-
if (response.sceneInfo.color) {
|
|
1061
|
-
var col = response.sceneInfo.color.match(/[0-9.]+/gi);
|
|
1062
|
-
motionCapture.style.background = "var(--avs-motion-capture-background, rgba(" + col[0] + "," + col[1] + "," + col[2] + ",0.75))";
|
|
1063
|
-
zoomOverlay.style.background = "var(--avs-zoom-overlay-background, rgba(" + col[0] + "," + col[1] + "," + col[2] + ",0.75))";
|
|
1064
|
-
tooltip.style.background = "var(--avs-tooltip-background, rgb(" + col[0] + "," + col[1] + "," + col[2] + "))";
|
|
1065
|
-
motionCaptureTooltip.style.background = "var(--avs-tooltip-background, rgb(" + col[0] + "," + col[1] + "," + col[2] + "))";
|
|
1066
|
-
}
|
|
1067
|
-
if (response.sceneInfo.fontFamily) {
|
|
1068
|
-
motionCapture.style.fontFamily = "var(--avs-motion-capture-font-family, " + response.sceneInfo.fontFamily + ")";
|
|
1069
|
-
zoomOverlay.style.fontFamily = "var(--avs-zoom-overlay-font-family, " + response.sceneInfo.fontFamily + ")";
|
|
1070
|
-
tooltip.style.fontFamily = "var(--avs-tooltip-font-family, " + response.sceneInfo.fontFamily + ")";
|
|
1071
|
-
motionCaptureTooltip.style.fontFamily = "var(--avs-tooltip-font-family, " + response.sceneInfo.fontFamily + ")";
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
if (response.image) {
|
|
1076
|
-
this.sceneImage.src = response.image;
|
|
1077
|
-
|
|
1078
|
-
if (response.imagemap) {
|
|
1079
|
-
this.sceneImageMap.innerHTML = decodeURIComponent(response.imagemap.replace(/\+/g, '%20'));
|
|
1080
|
-
|
|
1081
|
-
this.imageMapData = Array.from(this.sceneImageMap.querySelectorAll('area')).map(area => {
|
|
1082
|
-
return {
|
|
1083
|
-
shape: area.getAttribute('shape'),
|
|
1084
|
-
coords: area.getAttribute('coords').split(',').map(Number),
|
|
1085
|
-
seriesIndex: area.getAttribute('series-index'),
|
|
1086
|
-
itemIndex: area.getAttribute('item-index'),
|
|
1087
|
-
componentInfo: area.getAttribute('component-info')
|
|
1088
|
-
};
|
|
1089
|
-
});
|
|
1090
|
-
}
|
|
1091
|
-
else {
|
|
1092
|
-
this.sceneImageMap.innerHTML = "";
|
|
1093
|
-
this.imageMapData = undefined;
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
if (!this.urlLoadJsonFile) {
|
|
1097
|
-
this._dispatchSceneData(response);
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
this._handleLoadComplete();
|
|
1101
|
-
}
|
|
1102
|
-
else if (response.svg) {
|
|
1103
|
-
this.svgDiv.innerHTML = decodeURIComponent(response.svg.replace(/\+/g, '%20'));
|
|
1104
|
-
|
|
1105
|
-
if (!this.urlLoadJsonFile) {
|
|
1106
|
-
this._dispatchSceneData(response);
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
this._handleLoadComplete();
|
|
1110
|
-
}
|
|
1111
|
-
else if (response.threejs) {
|
|
1112
|
-
if (!this.urlLoadJsonFile) {
|
|
1113
|
-
this._dispatchSceneData(response);
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
if (response.threejs.chunkId) {
|
|
1117
|
-
this.threeViewer.loadGeometryAsEvents(response.threejs, this._handleLoadComplete.bind(this));
|
|
1118
|
-
|
|
1119
|
-
if (response.threejs.moreChunks) {
|
|
1120
|
-
if (this.urlLoadJsonFile) {
|
|
1121
|
-
// Load the next chunk file
|
|
1122
|
-
this.chunkFile++;
|
|
1123
|
-
const urlBase = this.url.substring(0, this.url.lastIndexOf('.')) || this.url;
|
|
1124
|
-
const ext = this.url.split('.').pop();
|
|
1125
|
-
this._httpRequest(urlBase + '-' + this.chunkFile + '.' + ext, this._handleHttpResponse.bind(this), this._handleHttpError.bind(this));
|
|
1126
|
-
}
|
|
1127
|
-
else {
|
|
1128
|
-
// Get the next chunk from the server
|
|
1129
|
-
this.model.rendererProperties.streamProperties.chunkId = response.threejs.chunkId;
|
|
1130
|
-
this._httpRequest(this.url, this._handleHttpResponse.bind(this), this._handleHttpError.bind(this), this.model);
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1134
|
-
else {
|
|
1135
|
-
this.threeViewer.loadGeometryAsJson(response.threejs, this._handleLoadComplete.bind(this));
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
else {
|
|
1139
|
-
this._dispatchErrorEvent("No image, SVG, or ThreeJS found in response.");
|
|
1140
|
-
this._handleLoadComplete();
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
getInheritedBackgroundCol(el: HTMLElement) {
|
|
1146
|
-
var defaultStyle = this.getDefaultBackground();
|
|
1147
|
-
|
|
1148
|
-
var bgCol = window.getComputedStyle(el).backgroundColor;
|
|
1149
|
-
if (bgCol != defaultStyle) {
|
|
1150
|
-
return bgCol;
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
if (!el.parentElement) {
|
|
1154
|
-
return defaultStyle;
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
return this.getInheritedBackgroundCol(el.parentElement);
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
getDefaultBackground() {
|
|
1161
|
-
// have to add to the document in order to use getComputedStyle
|
|
1162
|
-
var div = document.createElement("div");
|
|
1163
|
-
document.head.appendChild(div);
|
|
1164
|
-
var bg = window.getComputedStyle(div).backgroundColor;
|
|
1165
|
-
document.head.removeChild(div);
|
|
1166
|
-
return bg;
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
/**
|
|
1170
|
-
*
|
|
1171
|
-
*/
|
|
1172
|
-
_handleLoadComplete() {
|
|
1173
|
-
// Stop and hide the spinner
|
|
1174
|
-
this.hideSpinner();
|
|
1175
|
-
this.stopSpinner();
|
|
1176
|
-
|
|
1177
|
-
/**
|
|
1178
|
-
* Scene load has completed.
|
|
1179
|
-
* @event avs-load-complete
|
|
1180
|
-
*/
|
|
1181
|
-
this.dispatchEvent(new CustomEvent('avs-load-complete'));
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
/**
|
|
1185
|
-
*
|
|
1186
|
-
*/
|
|
1187
|
-
_dispatchSceneData(data: DataVizResponse) {
|
|
1188
|
-
/**
|
|
1189
|
-
* Scene data from server.
|
|
1190
|
-
* @event avs-scene-data
|
|
1191
|
-
*/
|
|
1192
|
-
this.dispatchEvent(new CustomEvent('avs-scene-data', { detail: data }));
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
/**
|
|
1196
|
-
* @param e
|
|
1197
|
-
*/
|
|
1198
|
-
_handleTap(x: number, y: number, currentTarget: EventTarget) {
|
|
1199
|
-
const adjustedCoords = this._getAdjustedCoords(x, y);
|
|
1200
|
-
const pickProperties: PickProperties = {
|
|
1201
|
-
type: "TAP",
|
|
1202
|
-
x: adjustedCoords.x,
|
|
1203
|
-
y: adjustedCoords.y,
|
|
1204
|
-
level: this.tapLevel,
|
|
1205
|
-
depth: this.tapDepth,
|
|
1206
|
-
highlight: this.tapHighlightEnable,
|
|
1207
|
-
highlightColor: this.tapHighlightColor,
|
|
1208
|
-
highlightLayer: this.tapHighlightLayerEnable
|
|
1209
|
-
};
|
|
1210
|
-
|
|
1211
|
-
this._processPick( pickProperties, this.tapProcessEventOnClient, currentTarget );
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
/**
|
|
1215
|
-
* @param e
|
|
1216
|
-
*/
|
|
1217
|
-
_handleTrack(state: string, x: number, y: number, dx: number, dy: number) {
|
|
1218
|
-
var adjustedCoords = this._getAdjustedRectangleCoords(x, y, dx, dy);
|
|
1219
|
-
|
|
1220
|
-
switch(state) {
|
|
1221
|
-
case 'start':
|
|
1222
|
-
break;
|
|
1223
|
-
|
|
1224
|
-
case 'track':
|
|
1225
|
-
this.rectCtx.clearRect(0,0,this.width,this.height);
|
|
1226
|
-
this._rectangleStyle();
|
|
1227
|
-
this.rectCtx.strokeRect(adjustedCoords.left, adjustedCoords.top, adjustedCoords.right - adjustedCoords.left, adjustedCoords.bottom - adjustedCoords.top);
|
|
1228
|
-
break;
|
|
1229
|
-
|
|
1230
|
-
case 'end':
|
|
1231
|
-
this.rectCtx.clearRect(0,0,this.width,this.height);
|
|
1232
|
-
|
|
1233
|
-
const pickProperties: PickProperties = {
|
|
1234
|
-
type: "TRACK",
|
|
1235
|
-
left: adjustedCoords.left,
|
|
1236
|
-
right: adjustedCoords.right,
|
|
1237
|
-
top: adjustedCoords.top,
|
|
1238
|
-
bottom: adjustedCoords.bottom,
|
|
1239
|
-
level: this.trackLevel,
|
|
1240
|
-
depth: this.trackDepth,
|
|
1241
|
-
highlight: this.trackHighlightEnable,
|
|
1242
|
-
highlightColor: this.trackHighlightColor,
|
|
1243
|
-
highlightLayer: this.trackHighlightLayerEnable
|
|
1244
|
-
};
|
|
1245
|
-
|
|
1246
|
-
this._processPick( pickProperties, this.trackProcessEventOnClient );
|
|
1247
|
-
break;
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
|
-
/**
|
|
1252
|
-
* @param e
|
|
1253
|
-
*/
|
|
1254
|
-
_handlePointerDown(e: PointerEvent) {
|
|
1255
|
-
this.pointerDownX = e.clientX;
|
|
1256
|
-
this.pointerDownY = e.clientY;
|
|
1257
|
-
|
|
1258
|
-
this.pointerDown = true;
|
|
1259
|
-
|
|
1260
|
-
if (this.tapEnable && e.buttons & 1) {
|
|
1261
|
-
this.tapping = true;
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
if (this.trackEnable && e.buttons & 2) {
|
|
1265
|
-
this.tracking = 1;
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
/**
|
|
1270
|
-
* @param e
|
|
1271
|
-
*/
|
|
1272
|
-
_handlePointerMove(e: PointerEvent) {
|
|
1273
|
-
if (this.tracking >= 1) {
|
|
1274
|
-
if (this.tracking === 1) {
|
|
1275
|
-
var dx = Math.abs(e.clientX - this.pointerDownX);
|
|
1276
|
-
var dy = Math.abs(e.clientY - this.pointerDownY);
|
|
1277
|
-
if (dx*dx + dy*dy >= 5) {
|
|
1278
|
-
this.tracking = 2;
|
|
1279
|
-
this._handleTrack("start", e.clientX, e.clientY, e.clientX-this.pointerDownX, e.clientY-this.pointerDownY);
|
|
1280
|
-
}
|
|
1281
|
-
}
|
|
1282
|
-
if (this.tracking === 2) {
|
|
1283
|
-
this._handleTrack("track", e.clientX, e.clientY, e.clientX-this.pointerDownX, e.clientY-this.pointerDownY);
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
if (this.hoverEnable) {
|
|
1288
|
-
var adjustedCoords = this._getAdjustedCoords(e.clientX, e.clientY);
|
|
1289
|
-
const pickProperties: PickProperties = {
|
|
1290
|
-
type: "HOVER",
|
|
1291
|
-
x: adjustedCoords.x,
|
|
1292
|
-
y: adjustedCoords.y
|
|
1293
|
-
};
|
|
1294
|
-
|
|
1295
|
-
if (this.pointerDown) {
|
|
1296
|
-
pickProperties.selected = [];
|
|
1297
|
-
this._dispatchPickEvents( pickProperties );
|
|
1298
|
-
}
|
|
1299
|
-
else {
|
|
1300
|
-
if (this.hoverLevel !== undefined) pickProperties.level = this.hoverLevel;
|
|
1301
|
-
if (this.hoverDepth !== undefined) pickProperties.depth = this.hoverDepth;
|
|
1302
|
-
if (this.hoverHighlightEnable) pickProperties.highlight = true;
|
|
1303
|
-
if (this.hoverHighlightColor !== undefined) pickProperties.highlightColor = this.hoverHighlightColor;
|
|
1304
|
-
if (this.hoverHighlightLayerEnable) pickProperties.highlightLayer = true;
|
|
1305
|
-
|
|
1306
|
-
this._processPick( pickProperties, true, e.target );
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
this._resetTimer();
|
|
1311
|
-
}
|
|
1312
|
-
|
|
1313
|
-
/**
|
|
1314
|
-
* @param e
|
|
1315
|
-
*/
|
|
1316
|
-
_handlePointerUp(e: PointerEvent) {
|
|
1317
|
-
this.pointerDown = false;
|
|
1318
|
-
|
|
1319
|
-
if (this.tapping) {
|
|
1320
|
-
this.tapping = false;
|
|
1321
|
-
var dx = Math.abs(e.clientX - this.pointerDownX);
|
|
1322
|
-
var dy = Math.abs(e.clientY - this.pointerDownY);
|
|
1323
|
-
if (dx*dx + dy*dy < 25) {
|
|
1324
|
-
this._handleTap(e.clientX, e.clientY, e.currentTarget);
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
if (this.tracking > 1) {
|
|
1329
|
-
this.tracking = 0;
|
|
1330
|
-
this._handleTrack("end", e.clientX, e.clientY, e.clientX-this.pointerDownX, e.clientY-this.pointerDownY);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
_getAdjustedCoords(x: number, y: number) {
|
|
1335
|
-
var rect = this.renderRoot.querySelector('#dataVizDiv').getBoundingClientRect();
|
|
1336
|
-
var adjustedX = Math.round(x - rect.left);
|
|
1337
|
-
var adjustedY = Math.round(y - rect.top);
|
|
1338
|
-
var clampX = Math.max(0, Math.min(adjustedX, this.width));
|
|
1339
|
-
var clampY = Math.max(0, Math.min(adjustedY, this.height));
|
|
1340
|
-
|
|
1341
|
-
return {x:clampX, y:clampY};
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
_getAdjustedRectangleCoords(x: number, y: number, dx: number, dy: number) {
|
|
1345
|
-
var rect = this.renderRoot.querySelector('#dataVizDiv').getBoundingClientRect();
|
|
1346
|
-
var adjustedX = Math.round(x - rect.left);
|
|
1347
|
-
var adjustedY = Math.round(y - rect.top);
|
|
1348
|
-
var clampX = Math.max(0, Math.min(adjustedX, this.width));
|
|
1349
|
-
var clampY = Math.max(0, Math.min(adjustedY, this.height));
|
|
1350
|
-
var startX = Math.max(0, Math.min(adjustedX - dx, this.width));
|
|
1351
|
-
var startY = Math.max(0, Math.min(adjustedY - dy, this.height));
|
|
1352
|
-
|
|
1353
|
-
var left = Math.min(startX, clampX);
|
|
1354
|
-
var right = Math.max(startX, clampX);
|
|
1355
|
-
var top = Math.min(startY, clampY);
|
|
1356
|
-
var bottom = Math.max(startY, clampY);
|
|
1357
|
-
|
|
1358
|
-
return {left: left, right: right, top: top, bottom: bottom};
|
|
1359
|
-
}
|
|
1360
|
-
|
|
1361
|
-
_processPick( pickProperties: PickProperties, processEventOnClient?: boolean, originalTarget?: any ) {
|
|
1362
|
-
if (processEventOnClient) {
|
|
1363
|
-
if (this.threeViewer) {
|
|
1364
|
-
// ThreeJS client side pick processing
|
|
1365
|
-
|
|
1366
|
-
this.threeViewer.setPickDepth( pickProperties.depth === "ALL" ? PickDepthEnum.All : PickDepthEnum.Closest );
|
|
1367
|
-
if (pickProperties.type === 'TRACK') {
|
|
1368
|
-
this.threeViewer.setPickRectangle( pickProperties.left, pickProperties.top, pickProperties.right, pickProperties.bottom );
|
|
1369
|
-
}
|
|
1370
|
-
else {
|
|
1371
|
-
this.threeViewer.setPickRay( pickProperties.x, pickProperties.y );
|
|
1372
|
-
}
|
|
1373
|
-
this.threeViewer.pick();
|
|
1374
|
-
|
|
1375
|
-
var selectionList = {};
|
|
1376
|
-
if (pickProperties.level === "CELL") {
|
|
1377
|
-
selectionList = this.threeViewer.getPickedCells();
|
|
1378
|
-
}
|
|
1379
|
-
else if (pickProperties.level === "CELL_SET") {
|
|
1380
|
-
selectionList = this.threeViewer.getPickedCellSets();
|
|
1381
|
-
}
|
|
1382
|
-
else {
|
|
1383
|
-
selectionList = this.threeViewer.getPickedSceneNodes();
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1386
|
-
pickProperties.selected = this.threeViewer.getSelectionInfo(selectionList);
|
|
1387
|
-
this._dispatchPickEvents(pickProperties);
|
|
1388
|
-
|
|
1389
|
-
if (pickProperties.highlight) {
|
|
1390
|
-
this.threeViewer.highlightColor.set( pickProperties.highlightColor );
|
|
1391
|
-
this.threeViewer.highlightObjects( selectionList, pickProperties.highlightLayer );
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
else if (this.renderer === 'SVG') {
|
|
1395
|
-
// Client side SVG pick processing
|
|
1396
|
-
|
|
1397
|
-
pickProperties.selected = [];
|
|
1398
|
-
|
|
1399
|
-
if (pickProperties.type !== 'TRACK' && (originalTarget.nodeName === "polygon" || originalTarget.nodeName === "circle")) {
|
|
1400
|
-
const selectedInfo: SelectedInfo = {};
|
|
1401
|
-
|
|
1402
|
-
var seriesIndex = null;
|
|
1403
|
-
var element = originalTarget.parentElement;
|
|
1404
|
-
while (element !== null && (seriesIndex = element.getAttribute("series-index")) === null) {
|
|
1405
|
-
element = element.parentElement;
|
|
1406
|
-
}
|
|
1407
|
-
if (seriesIndex !== null) {
|
|
1408
|
-
selectedInfo.seriesIndex = parseInt(seriesIndex);
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
|
-
var itemIndex = null;
|
|
1412
|
-
element = originalTarget.parentElement;
|
|
1413
|
-
while (element !== null && (itemIndex = element.getAttribute("item-index")) === null) {
|
|
1414
|
-
element = element.parentElement;
|
|
1415
|
-
}
|
|
1416
|
-
if (itemIndex !== null) {
|
|
1417
|
-
selectedInfo.itemIndex = parseInt(itemIndex);
|
|
1418
|
-
}
|
|
1419
|
-
|
|
1420
|
-
var componentInfo = null;
|
|
1421
|
-
element = originalTarget.parentElement;
|
|
1422
|
-
while (element !== null && (componentInfo = element.getAttribute("component-info")) === null) {
|
|
1423
|
-
element = element.parentElement;
|
|
1424
|
-
}
|
|
1425
|
-
if (componentInfo !== null) {
|
|
1426
|
-
selectedInfo.componentInfo = decodeURIComponent(componentInfo);
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
|
-
pickProperties.selected.push(selectedInfo);
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
|
-
this._dispatchPickEvents(pickProperties);
|
|
1433
|
-
|
|
1434
|
-
if (pickProperties.highlight) {
|
|
1435
|
-
if (this.highlightSvg === undefined) {
|
|
1436
|
-
this.highlightSvg = [];
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
for (var i = 0; i < this.highlightSvg.length; i++) {
|
|
1440
|
-
this.highlightSvg[i].setAttribute("fill", this.highlightSvg[i].getAttribute("saveFill"));
|
|
1441
|
-
}
|
|
1442
|
-
this.highlightSvg.length = 0;
|
|
1443
|
-
|
|
1444
|
-
if (pickProperties.type !== 'TRACK' && (originalTarget.nodeName === "polygon" || originalTarget.nodeName === "circle")) {
|
|
1445
|
-
this.highlightSvg.push(originalTarget);
|
|
1446
|
-
originalTarget.setAttribute("saveFill", originalTarget.getAttribute("fill"));
|
|
1447
|
-
originalTarget.setAttribute("fill", pickProperties.highlightColor);
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
else {
|
|
1452
|
-
// Client side imagemap pick processing
|
|
1453
|
-
|
|
1454
|
-
pickProperties.selected = [];
|
|
1455
|
-
|
|
1456
|
-
if (pickProperties.type !== 'TRACK' && this.imageMapData !== undefined) {
|
|
1457
|
-
for (var i = 0; i < this.imageMapData.length; i++) {
|
|
1458
|
-
var area = this.imageMapData[i];
|
|
1459
|
-
console.log(pickProperties.x + " " + pickProperties.y);
|
|
1460
|
-
if (area.shape === "poly" && this._pointInPoly(pickProperties.x, pickProperties.y, area.coords)) {
|
|
1461
|
-
|
|
1462
|
-
const selectedInfo: SelectedInfo = {};
|
|
1463
|
-
if (area.seriesIndex !== null) {
|
|
1464
|
-
selectedInfo.seriesIndex = parseInt(area.seriesIndex);
|
|
1465
|
-
}
|
|
1466
|
-
if (area.itemIndex !== null) {
|
|
1467
|
-
selectedInfo.itemIndex = parseInt(area.itemIndex);
|
|
1468
|
-
}
|
|
1469
|
-
if (area.componentInfo !== null) {
|
|
1470
|
-
selectedInfo.componentInfo = decodeURIComponent(area.componentInfo);
|
|
1471
|
-
}
|
|
1472
|
-
pickProperties.selected.push(selectedInfo);
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
|
|
1477
|
-
this._dispatchPickEvents(pickProperties);
|
|
1478
|
-
}
|
|
1479
|
-
}
|
|
1480
|
-
else if (!this.urlLoadJsonFile) {
|
|
1481
|
-
// Server side pick processing
|
|
1482
|
-
|
|
1483
|
-
this.showSpinner();
|
|
1484
|
-
if (this.url) {
|
|
1485
|
-
this.startSpinner();
|
|
1486
|
-
|
|
1487
|
-
// Send the model to the server
|
|
1488
|
-
this.model = this._assembleModel();
|
|
1489
|
-
if (this.model) {
|
|
1490
|
-
this.model.rendererProperties.pickProperties = pickProperties;
|
|
1491
|
-
this._httpRequest(this.url, this._handleHttpResponse.bind(this), this._handleHttpError.bind(this), this.model);
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
_pointInPoly(x: number, y: number, coords: Array<number>): boolean {
|
|
1498
|
-
var dx1 = coords[0] - x;
|
|
1499
|
-
var dy1 = coords[1] - y;
|
|
1500
|
-
var dx2, dy2, f;
|
|
1501
|
-
var k = 0;
|
|
1502
|
-
|
|
1503
|
-
for (var i=2; i < coords.length; i+=2) {
|
|
1504
|
-
|
|
1505
|
-
dy2 = coords[i+1] - y;
|
|
1506
|
-
|
|
1507
|
-
if ((dy1 < 0 && dy2 < 0) || (dy1 > 0 && dy2 > 0)) {
|
|
1508
|
-
dy1 = dy2;
|
|
1509
|
-
dx1 = coords[i] - x;
|
|
1510
|
-
continue;
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
dx2 = coords[i] - x;
|
|
1514
|
-
|
|
1515
|
-
if (dy2 > 0 && dy1 <= 0) {
|
|
1516
|
-
f = (dx1 * dy2) - (dx2 * dy1);
|
|
1517
|
-
if (f > 0) k++;
|
|
1518
|
-
else if (f === 0) return false;
|
|
1519
|
-
}
|
|
1520
|
-
else if (dy1 > 0 && dy2 <= 0) {
|
|
1521
|
-
f = (dx1 * dy2) - (dx2 * dy1);
|
|
1522
|
-
if (f < 0) k++;
|
|
1523
|
-
else if (f === 0) return false;
|
|
1524
|
-
}
|
|
1525
|
-
else if (dy2 === 0 && dy1 < 0) {
|
|
1526
|
-
f = (dx1 * dy2) - (dx2 * dy1);
|
|
1527
|
-
if (f === 0) return false;
|
|
1528
|
-
}
|
|
1529
|
-
else if (dy1 === 0 && dy2 < 0) {
|
|
1530
|
-
f = dx1 * dy2 - dx2 * dy1;
|
|
1531
|
-
if (f === 0) return false;
|
|
1532
|
-
}
|
|
1533
|
-
else if (dy1 === 0 && dy2 === 0) {
|
|
1534
|
-
if (dx2 <= 0 && dx1 >= 0) {
|
|
1535
|
-
return false;
|
|
1536
|
-
}
|
|
1537
|
-
else if (dx1 <= 0 && dx2 >= 0) {
|
|
1538
|
-
return false;
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
dy1 = dy2;
|
|
1543
|
-
dx1 = dx2;
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
if (k % 2 === 0) return false;
|
|
1547
|
-
return true;
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
/**
|
|
1551
|
-
* Dispatch the appropriate tap, track or hover event.
|
|
1552
|
-
*/
|
|
1553
|
-
_dispatchPickEvents(pickProperties: PickProperties) {
|
|
1554
|
-
|
|
1555
|
-
const pickDetail: PickDetail = {
|
|
1556
|
-
selected: pickProperties.selected
|
|
1557
|
-
};
|
|
1558
|
-
|
|
1559
|
-
if (pickProperties.type === 'TRACK') {
|
|
1560
|
-
pickDetail.left = pickProperties.left;
|
|
1561
|
-
pickDetail.top = pickProperties.top;
|
|
1562
|
-
pickDetail.right = pickProperties.right;
|
|
1563
|
-
pickDetail.bottom = pickProperties.bottom;
|
|
1564
|
-
|
|
1565
|
-
/**
|
|
1566
|
-
* A track event occurred.
|
|
1567
|
-
* @event avs-track
|
|
1568
|
-
*/
|
|
1569
|
-
this.dispatchEvent(new CustomEvent('avs-track', { detail: pickDetail }));
|
|
1570
|
-
}
|
|
1571
|
-
else {
|
|
1572
|
-
pickDetail.x = pickProperties.x;
|
|
1573
|
-
pickDetail.y = pickProperties.y;
|
|
1574
|
-
|
|
1575
|
-
if (pickProperties.type === 'HOVER') {
|
|
1576
|
-
/**
|
|
1577
|
-
* A hover event occurred.
|
|
1578
|
-
* @event avs-hover
|
|
1579
|
-
*/
|
|
1580
|
-
this.dispatchEvent(new CustomEvent('avs-hover', { detail: pickDetail }));
|
|
1581
|
-
}
|
|
1582
|
-
else {
|
|
1583
|
-
/**
|
|
1584
|
-
* A tap event occurred.
|
|
1585
|
-
* @event avs-tap
|
|
1586
|
-
*/
|
|
1587
|
-
this.dispatchEvent(new CustomEvent('avs-tap', { detail: pickDetail }));
|
|
1588
|
-
}
|
|
1589
|
-
}
|
|
1590
|
-
}
|
|
1591
|
-
|
|
1592
|
-
_resetTimer() {
|
|
1593
|
-
window.clearTimeout(this.timer);
|
|
1594
|
-
this.timer = window.setTimeout(() => {
|
|
1595
|
-
/**
|
|
1596
|
-
* A pointer timeout event occurred.
|
|
1597
|
-
* @event avs-pointer-timeout
|
|
1598
|
-
*/
|
|
1599
|
-
this.dispatchEvent(new Event('avs-pointer-timeout'));
|
|
1600
|
-
}, this.pointerTimeout * 1000);
|
|
1601
|
-
}
|
|
1602
|
-
|
|
1603
|
-
constructor() {
|
|
1604
|
-
super();
|
|
1605
|
-
|
|
1606
|
-
// Set default property values
|
|
1607
|
-
this.renderer = Renderer.THREEJS;
|
|
1608
|
-
this.resizeThreshold = 10;
|
|
1609
|
-
this.pointerTimeout = 600;
|
|
1610
|
-
this.panWidthZoomLevel = 100;
|
|
1611
|
-
this.panHeightZoomLevel = 100;
|
|
1612
|
-
this.panMaximumZoomLevel = 1000;
|
|
1613
|
-
|
|
1614
|
-
this.lowResizeWidth = this.highResizeWidth = 0;
|
|
1615
|
-
this.highResizeWidth = this.highResizeHeight = 0;
|
|
1616
|
-
|
|
1617
|
-
this.motionCaptureTime = 0;
|
|
1618
|
-
this.motionCaptureFrames ??= [];
|
|
1619
|
-
|
|
1620
|
-
this._resetTimer();
|
|
1621
|
-
this._updatePixelRatio();
|
|
1622
|
-
}
|
|
1623
|
-
|
|
1624
|
-
/**
|
|
1625
|
-
* Element connected to the DOM
|
|
1626
|
-
*/
|
|
1627
|
-
connectedCallback() {
|
|
1628
|
-
super.connectedCallback();
|
|
1629
|
-
|
|
1630
|
-
ro.observe(this);
|
|
1631
|
-
|
|
1632
|
-
this.addEventListener('pointerdown', this._handlePointerDown);
|
|
1633
|
-
this.addEventListener('pointerup', this._handlePointerUp);
|
|
1634
|
-
this.addEventListener('pointermove', this._handlePointerMove);
|
|
1635
|
-
this.addEventListener('pointerout', this._handlePointerMove);
|
|
1636
|
-
|
|
1637
|
-
var scope = this;
|
|
1638
|
-
this.addEventListener('contextmenu', function(e) {
|
|
1639
|
-
if (scope.trackEnable) {
|
|
1640
|
-
e.preventDefault();
|
|
1641
|
-
}
|
|
1642
|
-
});
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
/**
|
|
1646
|
-
* Element disconnected from the DOM
|
|
1647
|
-
*/
|
|
1648
|
-
disconnectedCallback() {
|
|
1649
|
-
super.disconnectedCallback();
|
|
1650
|
-
|
|
1651
|
-
ro.unobserve(this);
|
|
1652
|
-
}
|
|
1653
|
-
|
|
1654
|
-
_handlePointerEnterMotionCaptureControl(e: PointerEvent) {
|
|
1655
|
-
if (!this.showMotionCaptureTooltip) {
|
|
1656
|
-
var adjustedCoords = this._getAdjustedCoords(e.clientX, e.clientY);
|
|
1657
|
-
var motionCaptureTooltip = this.renderRoot.querySelector('#motionCaptureTooltip') as HTMLDivElement;
|
|
1658
|
-
var pos = this._calcTooltipPosition(motionCaptureTooltip, adjustedCoords.x, adjustedCoords.y);
|
|
1659
|
-
motionCaptureTooltip.style.left = pos.x + "px";
|
|
1660
|
-
motionCaptureTooltip.style.top = pos.y + "px";
|
|
1661
|
-
motionCaptureTooltip.style.opacity = "1";
|
|
1662
|
-
const target = e.currentTarget as HTMLElement;
|
|
1663
|
-
motionCaptureTooltip.innerHTML = target.dataset.tooltip ?? target.id;
|
|
1664
|
-
this.showMotionCaptureTooltip = true;
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
|
|
1668
|
-
_handlePointerLeaveMotionCaptureControl() {
|
|
1669
|
-
var motionCaptureTooltip = this.renderRoot.querySelector('#motionCaptureTooltip') as HTMLDivElement;
|
|
1670
|
-
motionCaptureTooltip.style.opacity = "0";
|
|
1671
|
-
this.showMotionCaptureTooltip = false;
|
|
1672
|
-
}
|
|
1673
|
-
|
|
1674
|
-
_round2dp(n: number) {
|
|
1675
|
-
return Math.round((n + Number.EPSILON) * 100) / 100;
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
|
-
_handleMotionCaptureSnapshot() {
|
|
1679
|
-
const transform = this._getTransformComponents();
|
|
1680
|
-
if (this.motionCaptureFrames.length > 0) {
|
|
1681
|
-
this.motionCaptureTime += this.motionCaptureDelay;
|
|
1682
|
-
}
|
|
1683
|
-
const frame: MotionCaptureFrame = {
|
|
1684
|
-
time: this.motionCaptureTime * 1000,
|
|
1685
|
-
scale: this._round2dp(transform.scale),
|
|
1686
|
-
position: [this._round2dp(transform.position[0]),
|
|
1687
|
-
this._round2dp(transform.position[1]),
|
|
1688
|
-
this._round2dp(transform.position[2])],
|
|
1689
|
-
rotation: [this._round2dp(transform.rotation[0]),
|
|
1690
|
-
this._round2dp(transform.rotation[1]),
|
|
1691
|
-
this._round2dp(transform.rotation[2]),
|
|
1692
|
-
transform.rotation[3]]
|
|
1693
|
-
};
|
|
1694
|
-
this.motionCaptureFrames.push(frame);
|
|
1695
|
-
|
|
1696
|
-
if (this.motionCaptureFrames.length == 1) {
|
|
1697
|
-
this.renderRoot.querySelector('#motionCapturePlay').classList.remove("disabled");
|
|
1698
|
-
this.renderRoot.querySelector('#motionCaptureDelay').classList.remove("disabled");
|
|
1699
|
-
this.renderRoot.querySelector('#motionCaptureDelayLabel').innerHTML = "2";
|
|
1700
|
-
this.renderRoot.querySelector('#motionCaptureClear').classList.remove("disabled");
|
|
1701
|
-
this.renderRoot.querySelector('#motionCaptureCopyData').classList.remove("disabled");
|
|
1702
|
-
this.renderRoot.querySelector('#motionCaptureCopyUrl').classList.remove("disabled");
|
|
1703
|
-
this.motionCaptureDelay = 2;
|
|
1704
|
-
}
|
|
1705
|
-
this.renderRoot.querySelector('#motionCaptureSnapshotLabel').innerHTML = String(this.motionCaptureFrames.length);
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
|
-
_handleMotionCaptureDelayIncrease() {
|
|
1709
|
-
this.motionCaptureDelay++;
|
|
1710
|
-
if (this.motionCaptureDelay > 9) {
|
|
1711
|
-
this.motionCaptureDelay = 9;
|
|
1712
|
-
}
|
|
1713
|
-
this.renderRoot.querySelector('#motionCaptureDelayLabel').innerHTML = String(this.motionCaptureDelay);
|
|
1714
|
-
}
|
|
1715
|
-
|
|
1716
|
-
_handleMotionCaptureDelayDecrease() {
|
|
1717
|
-
this.motionCaptureDelay--;
|
|
1718
|
-
if (this.motionCaptureDelay < 1) {
|
|
1719
|
-
this.motionCaptureDelay = 1;
|
|
1720
|
-
}
|
|
1721
|
-
this.renderRoot.querySelector('#motionCaptureDelayLabel').innerHTML = String(this.motionCaptureDelay);
|
|
1722
|
-
}
|
|
1723
|
-
|
|
1724
|
-
_handleMotionCaptureCopyData() {
|
|
1725
|
-
// Convert to JSON and copy to clipboard
|
|
1726
|
-
const data = JSON.stringify(this.motionCaptureFrames);
|
|
1727
|
-
navigator.clipboard.writeText(data);
|
|
1728
|
-
|
|
1729
|
-
// Show alert
|
|
1730
|
-
const motionCaptureAlert = this.renderRoot.querySelector('#motionCaptureAlert') as HTMLDivElement;
|
|
1731
|
-
motionCaptureAlert.innerHTML = "Motion capture URL copied to clipboard";
|
|
1732
|
-
motionCaptureAlert.style.opacity = "1";
|
|
1733
|
-
setTimeout(() => {
|
|
1734
|
-
motionCaptureAlert.style.opacity = "0";
|
|
1735
|
-
}, 2000);
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
|
-
async _handleMotionCaptureCopyUrl() {
|
|
1739
|
-
// Convert to JSON, compress and base64url encode
|
|
1740
|
-
const json = JSON.stringify(this.motionCaptureFrames);
|
|
1741
|
-
const compressed = await this._compress(json);
|
|
1742
|
-
const encoded = btoa(String.fromCharCode(...new Uint8Array(compressed))).replaceAll('/', '_').replaceAll('+', '-');
|
|
1743
|
-
|
|
1744
|
-
// Create URL and copy to clipboard
|
|
1745
|
-
const url = window.location.origin + window.location.pathname + "?motionCapture=" + encoded;
|
|
1746
|
-
navigator.clipboard.writeText(url);
|
|
1747
|
-
|
|
1748
|
-
// Show alert
|
|
1749
|
-
const motionCaptureAlert = this.renderRoot.querySelector('#motionCaptureAlert') as HTMLDivElement;
|
|
1750
|
-
motionCaptureAlert.innerHTML = "Motion capture URL copied to clipboard";
|
|
1751
|
-
motionCaptureAlert.style.opacity = "1";
|
|
1752
|
-
setTimeout(() => {
|
|
1753
|
-
motionCaptureAlert.style.opacity = "0";
|
|
1754
|
-
}, 2000);
|
|
1755
|
-
}
|
|
1756
|
-
|
|
1757
|
-
/**
|
|
1758
|
-
* Convert a string to its UTF-8 bytes and compress it.
|
|
1759
|
-
*
|
|
1760
|
-
* @param {string} str
|
|
1761
|
-
* @returns {Promise<Uint8Array>}
|
|
1762
|
-
*/
|
|
1763
|
-
async _compress(str: string) {
|
|
1764
|
-
// Convert the string to a byte stream.
|
|
1765
|
-
const stream = new Blob([str]).stream();
|
|
1766
|
-
|
|
1767
|
-
// Create a compressed stream.
|
|
1768
|
-
const compressedStream = stream.pipeThrough(
|
|
1769
|
-
new CompressionStream("gzip")
|
|
1770
|
-
);
|
|
1771
|
-
|
|
1772
|
-
// Read all the bytes from this stream.
|
|
1773
|
-
const chunks = [];
|
|
1774
|
-
for await (const chunk of compressedStream) {
|
|
1775
|
-
chunks.push(chunk);
|
|
1776
|
-
}
|
|
1777
|
-
return this._concatUint8Arrays(chunks);
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
/**
|
|
1781
|
-
* Decompress bytes into a UTF-8 string.
|
|
1782
|
-
*
|
|
1783
|
-
* @param {Uint8Array} compressedBytes
|
|
1784
|
-
* @returns {Promise<string>}
|
|
1785
|
-
*/
|
|
1786
|
-
async _decompress(compressedBytes) {
|
|
1787
|
-
// Convert the bytes to a stream.
|
|
1788
|
-
const stream = new Blob([compressedBytes]).stream();
|
|
1789
|
-
|
|
1790
|
-
// Create a decompressed stream.
|
|
1791
|
-
const decompressedStream = stream.pipeThrough(
|
|
1792
|
-
new DecompressionStream("gzip")
|
|
1793
|
-
);
|
|
1794
|
-
|
|
1795
|
-
// Read all the bytes from this stream.
|
|
1796
|
-
const chunks = [];
|
|
1797
|
-
for await (const chunk of decompressedStream) {
|
|
1798
|
-
chunks.push(chunk);
|
|
1799
|
-
}
|
|
1800
|
-
const stringBytes = await this._concatUint8Arrays(chunks);
|
|
1801
|
-
|
|
1802
|
-
// Convert the bytes to a string.
|
|
1803
|
-
return new TextDecoder().decode(stringBytes);
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
|
-
/**
|
|
1807
|
-
* Combine multiple Uint8Arrays into one.
|
|
1808
|
-
*
|
|
1809
|
-
* @param {ReadonlyArray<Uint8Array>} uint8arrays
|
|
1810
|
-
* @returns {Promise<Uint8Array>}
|
|
1811
|
-
*/
|
|
1812
|
-
async _concatUint8Arrays(uint8arrays) {
|
|
1813
|
-
const blob = new Blob(uint8arrays);
|
|
1814
|
-
const buffer = await blob.arrayBuffer();
|
|
1815
|
-
return new Uint8Array(buffer);
|
|
1816
|
-
}
|
|
1817
|
-
|
|
1818
|
-
_handleMotionCaptureClear() {
|
|
1819
|
-
this.motionCaptureFrames.length = 0;
|
|
1820
|
-
this.renderRoot.querySelector('#motionCapturePlay').classList.add("disabled");
|
|
1821
|
-
this.renderRoot.querySelector('#motionCaptureSnapshotLabel').innerHTML = "0";
|
|
1822
|
-
this.renderRoot.querySelector('#motionCaptureDelay').classList.add("disabled");
|
|
1823
|
-
this.renderRoot.querySelector('#motionCaptureDelayLabel').innerHTML = "0";
|
|
1824
|
-
this.renderRoot.querySelector('#motionCaptureClear').classList.add("disabled");
|
|
1825
|
-
this.renderRoot.querySelector('#motionCaptureCopyData').classList.add("disabled");
|
|
1826
|
-
this.renderRoot.querySelector('#motionCaptureCopyUrl').classList.add("disabled");
|
|
1827
|
-
this.motionCaptureDelay = 0;
|
|
1828
|
-
this.motionCaptureTime = 0;
|
|
1829
|
-
}
|
|
1830
|
-
|
|
1831
|
-
_updatePixelRatio(change?: boolean) {
|
|
1832
|
-
const pr = window.devicePixelRatio;
|
|
1833
|
-
matchMedia( `(resolution: ${pr}dppx)` ).addEventListener('change', this._updatePixelRatio.bind(this, true), { once: true } );
|
|
1834
|
-
if (change) {
|
|
1835
|
-
this.updateViewer();
|
|
1836
|
-
}
|
|
1837
|
-
}
|
|
1838
|
-
|
|
1839
|
-
/**
|
|
1840
|
-
* Change in 'motion-capture-controls-enable' property.
|
|
1841
|
-
*/
|
|
1842
|
-
_motionCaptureControlsEnableChanged(newValue, oldValue) {
|
|
1843
|
-
const el = this.renderRoot.querySelector('#motionCapture') as HTMLDivElement;
|
|
1844
|
-
el.style.display = newValue ? "block" : "none";
|
|
1845
|
-
}
|
|
1846
|
-
|
|
1847
|
-
/**
|
|
1848
|
-
* Change in 'transform-enable' property.
|
|
1849
|
-
*/
|
|
1850
|
-
_transformEnableChanged(newValue, oldValue) {
|
|
1851
|
-
if (this.threeViewer) {
|
|
1852
|
-
if (newValue) {
|
|
1853
|
-
if (this.transformInteractor === undefined) {
|
|
1854
|
-
this.transformInteractor = new TransformInteractor(this.renderRoot.querySelector('#dataVizDiv'));
|
|
1855
|
-
}
|
|
1856
|
-
this.threeViewer.addInteractor( this.transformInteractor );
|
|
1857
|
-
|
|
1858
|
-
if (this.transformRotateDisable) {
|
|
1859
|
-
this.transformInteractor.enableRotate = false;
|
|
1860
|
-
}
|
|
1861
|
-
if (this.transformZoomDisable) {
|
|
1862
|
-
this.transformInteractor.enableZoom = false;
|
|
1863
|
-
}
|
|
1864
|
-
if (this.transformPanDisable) {
|
|
1865
|
-
this.transformInteractor.enablePan = false;
|
|
1866
|
-
}
|
|
1867
|
-
if (this.transformClientOnly) {
|
|
1868
|
-
this.transformInteractor.clientOnly = true;
|
|
1869
|
-
}
|
|
1870
|
-
}
|
|
1871
|
-
else {
|
|
1872
|
-
this.threeViewer.removeInteractor( this.transformInteractor );
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
}
|
|
1876
|
-
|
|
1877
|
-
/**
|
|
1878
|
-
* Change in the 'transform-client-only' property.
|
|
1879
|
-
*/
|
|
1880
|
-
_transformClientOnlyChanged(newValue, oldValue) {
|
|
1881
|
-
if (this.transformInteractor) {
|
|
1882
|
-
this.transformInteractor.clientOnly = newValue;
|
|
1883
|
-
}
|
|
1884
|
-
if (this.zoomRectangleInteractor) {
|
|
1885
|
-
this.zoomRectangleInteractor.clientOnly = newValue;
|
|
1886
|
-
}
|
|
1887
|
-
}
|
|
1888
|
-
|
|
1889
|
-
/**
|
|
1890
|
-
* Change in 'transform-rotate-disable' property.
|
|
1891
|
-
*/
|
|
1892
|
-
_transformRotateDisableChanged(newValue, oldValue) {
|
|
1893
|
-
if (this.transformInteractor) {
|
|
1894
|
-
this.transformInteractor.enableRotate = !newValue;
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
|
|
1898
|
-
/**
|
|
1899
|
-
* Change in 'transform-zoom-disable' property.
|
|
1900
|
-
*/
|
|
1901
|
-
_transformZoomDisableChanged(newValue, oldValue) {
|
|
1902
|
-
if (this.transformInteractor) {
|
|
1903
|
-
this.transformInteractor.enableZoom = !newValue;
|
|
1904
|
-
}
|
|
1905
|
-
}
|
|
1906
|
-
|
|
1907
|
-
/**
|
|
1908
|
-
* Change in 'transform-pan-disable' property.
|
|
1909
|
-
*/
|
|
1910
|
-
_transformPanDisableChanged(newValue, oldValue) {
|
|
1911
|
-
if (this.transformInteractor) {
|
|
1912
|
-
this.transformInteractor.enablePan = !newValue;
|
|
1913
|
-
}
|
|
1914
|
-
}
|
|
1915
|
-
|
|
1916
|
-
/**
|
|
1917
|
-
* Reset the transform interactor.
|
|
1918
|
-
*/
|
|
1919
|
-
resetTransform() {
|
|
1920
|
-
if (this.transformInteractor) {
|
|
1921
|
-
this.transformInteractor.reset();
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
|
-
|
|
1925
|
-
/**
|
|
1926
|
-
* Perform a zoom in using the transform interactor.
|
|
1927
|
-
*/
|
|
1928
|
-
zoomIn() {
|
|
1929
|
-
if (this.transformInteractor) {
|
|
1930
|
-
this.transformInteractor.zoomIn();
|
|
1931
|
-
}
|
|
1932
|
-
}
|
|
1933
|
-
|
|
1934
|
-
/**
|
|
1935
|
-
* Perform a zoom out using the transform interactor.
|
|
1936
|
-
*/
|
|
1937
|
-
zoomOut() {
|
|
1938
|
-
if (this.transformInteractor) {
|
|
1939
|
-
this.transformInteractor.zoomOut();
|
|
1940
|
-
}
|
|
1941
|
-
}
|
|
1942
|
-
|
|
1943
|
-
/**
|
|
1944
|
-
* Perform a pan to center the specified coordinate of the transformed object in the center of the scene.
|
|
1945
|
-
*/
|
|
1946
|
-
panTo(x: number, y: number, z: number) {
|
|
1947
|
-
if (this.transformInteractor) {
|
|
1948
|
-
this.transformInteractor.panTo(x, y, z);
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
|
|
1952
|
-
_getTransformComponents() {
|
|
1953
|
-
var pos = new Vector3();
|
|
1954
|
-
var quat = new Quaternion();
|
|
1955
|
-
var scale = new Vector3();
|
|
1956
|
-
var euler = new Euler();
|
|
1957
|
-
var mat;
|
|
1958
|
-
if (this.transformInteractor) {
|
|
1959
|
-
mat = this.transformInteractor.object.matrix;
|
|
1960
|
-
}
|
|
1961
|
-
mat.decompose(pos, quat, scale);
|
|
1962
|
-
euler.setFromQuaternion(quat);
|
|
1963
|
-
return {
|
|
1964
|
-
position: pos.toArray(),
|
|
1965
|
-
rotation: [euler.x * 180 / Math.PI, euler.y * 180 / Math.PI, euler.z * 180 / Math.PI],
|
|
1966
|
-
rotationOrder: euler.order,
|
|
1967
|
-
scale: 100 * scale.x
|
|
1968
|
-
};
|
|
1969
|
-
}
|
|
1970
|
-
|
|
1971
|
-
getTransformMatrix() {
|
|
1972
|
-
if (this.transformInteractor) {
|
|
1973
|
-
return this.transformInteractor.object.matrix.elements.slice();
|
|
1974
|
-
}
|
|
1975
|
-
}
|
|
1976
|
-
|
|
1977
|
-
runAnimation() {
|
|
1978
|
-
if (this.threeViewer) {
|
|
1979
|
-
var style = window.getComputedStyle(this, null);
|
|
1980
|
-
var styleMap = {
|
|
1981
|
-
transform: this.motionCaptureFrames.length > 0 ? JSON.stringify(this.motionCaptureFrames) : null
|
|
1982
|
-
};
|
|
1983
|
-
this._applyCustomCssProperties(styleMap, style,
|
|
1984
|
-
{
|
|
1985
|
-
"scene": "--avs-scene-animations",
|
|
1986
|
-
"sceneTitle": "--avs-scene-title-animations",
|
|
1987
|
-
"chart": "--avs-chart-animations",
|
|
1988
|
-
"chartTitle": "--avs-chart-title-animations",
|
|
1989
|
-
"axis": "--avs-axis-animations",
|
|
1990
|
-
"legend": "--avs-legend-animations",
|
|
1991
|
-
"legendTitle": "--avs-legend-title-animations",
|
|
1992
|
-
"glyph": "--avs-glyph-animations"
|
|
1993
|
-
});
|
|
1994
|
-
|
|
1995
|
-
this.animator.setStyleMap(styleMap);
|
|
1996
|
-
this.threeViewer.runAnimation();
|
|
1997
|
-
}
|
|
1998
|
-
}
|
|
1999
|
-
|
|
2000
|
-
/**
|
|
2001
|
-
* Change in 'animated-glyphs-visible' property.
|
|
2002
|
-
*/
|
|
2003
|
-
_animatedGlyphsVisibleChanged(newValue, oldValue) {
|
|
2004
|
-
if (this.threeViewer) {
|
|
2005
|
-
this.threeViewer.setVisibleAnimatedGlyphs(newValue);
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
|
|
2009
|
-
/**
|
|
2010
|
-
* Change in 'animated-glyphs-enable' property.
|
|
2011
|
-
*/
|
|
2012
|
-
_animatedGlyphsEnableChanged(newValue, oldValue) {
|
|
2013
|
-
if (this.threeViewer) {
|
|
2014
|
-
this.threeViewer.setEnableAnimatedGlyphs(newValue);
|
|
2015
|
-
}
|
|
2016
|
-
}
|
|
2017
|
-
|
|
2018
|
-
/**
|
|
2019
|
-
* Change in 'transform-twist-angle', 'transform-tilt-angle' or 'transform-scale' properties.
|
|
2020
|
-
*/
|
|
2021
|
-
_transformValueChanged() {
|
|
2022
|
-
var twist = this.transformTwistAngle !== undefined ? this.transformTwistAngle * Math.PI / 180 : 0;
|
|
2023
|
-
var tilt = this.transformTiltAngle !== undefined ? this.transformTiltAngle * Math.PI / 180 : 0;
|
|
2024
|
-
var scale = this.transformScale !== undefined ? this.transformScale / 100.0 : 1.0;
|
|
2025
|
-
|
|
2026
|
-
var sinTW = Math.sin(twist);
|
|
2027
|
-
var cosTW = Math.cos(twist);
|
|
2028
|
-
var sinTI = Math.sin(tilt);
|
|
2029
|
-
var cosTI = Math.cos(tilt);
|
|
2030
|
-
|
|
2031
|
-
var matrix = [ cosTW * scale, 0, cosTI * sinTW * scale, 0,
|
|
2032
|
-
0, cosTI * scale, -sinTI * scale, 0,
|
|
2033
|
-
-sinTW * scale, cosTW * sinTI * scale, cosTW * cosTI * scale, 0,
|
|
2034
|
-
0, 0, 0, 1 ];
|
|
2035
|
-
|
|
2036
|
-
this.transformMatrix = matrix;
|
|
2037
|
-
if (this.transformInteractor) {
|
|
2038
|
-
this.transformInteractor.object.matrix.fromArray( matrix );
|
|
2039
|
-
}
|
|
2040
|
-
}
|
|
2041
|
-
|
|
2042
|
-
/**
|
|
2043
|
-
* Change in 'motion-capture' property.
|
|
2044
|
-
*/
|
|
2045
|
-
async _motionCaptureValueChanged(newValue, oldValue) {
|
|
2046
|
-
if (newValue) {
|
|
2047
|
-
// Try parsing JSON first
|
|
2048
|
-
try {
|
|
2049
|
-
this.motionCaptureFrames = JSON.parse(newValue);
|
|
2050
|
-
}
|
|
2051
|
-
catch {
|
|
2052
|
-
// Decode from base64url, decompress and parse JSON
|
|
2053
|
-
const decoded = atob(newValue).replaceAll('_', '/').replaceAll('-', '+');
|
|
2054
|
-
const decompressed = await this._decompress(decoded);
|
|
2055
|
-
this.motionCaptureFrames = JSON.parse(decompressed);
|
|
2056
|
-
}
|
|
2057
|
-
|
|
2058
|
-
if (!this.motionCaptureFrames) {
|
|
2059
|
-
this.motionCaptureFrames = [];
|
|
2060
|
-
}
|
|
2061
|
-
|
|
2062
|
-
if (this.motionCaptureFrames.length > 0) {
|
|
2063
|
-
this.renderRoot.querySelector('#motionCapturePlay').classList.remove("disabled");
|
|
2064
|
-
this.renderRoot.querySelector('#motionCaptureSnapshotLabel').innerHTML = String(this.motionCaptureFrames.length);
|
|
2065
|
-
this.renderRoot.querySelector('#motionCaptureDelay').classList.remove("disabled");
|
|
2066
|
-
this.renderRoot.querySelector('#motionCaptureDelayLabel').innerHTML = "2";
|
|
2067
|
-
this.renderRoot.querySelector('#motionCaptureClear').classList.remove("disabled");
|
|
2068
|
-
this.renderRoot.querySelector('#motionCaptureCopyData').classList.remove("disabled");
|
|
2069
|
-
this.renderRoot.querySelector('#motionCaptureCopyUrl').classList.remove("disabled");
|
|
2070
|
-
this.motionCaptureDelay = 2;
|
|
2071
|
-
this.motionCaptureTime = this.motionCaptureFrames[this.motionCaptureFrames.length - 1].time / 1000;
|
|
2072
|
-
}
|
|
2073
|
-
else {
|
|
2074
|
-
this.renderRoot.querySelector('#motionCapturePlay').classList.add("disabled");
|
|
2075
|
-
this.renderRoot.querySelector('#motionCaptureSnapshotLabel').innerHTML = "0";
|
|
2076
|
-
this.renderRoot.querySelector('#motionCaptureDelay').classList.add("disabled");
|
|
2077
|
-
this.renderRoot.querySelector('#motionCaptureDelayLabel').innerHTML = "0";
|
|
2078
|
-
this.renderRoot.querySelector('#motionCaptureClear').classList.add("disabled");
|
|
2079
|
-
this.renderRoot.querySelector('#motionCaptureCopyData').classList.add("disabled");
|
|
2080
|
-
this.renderRoot.querySelector('#motionCaptureCopyUrl').classList.add("disabled");
|
|
2081
|
-
this.motionCaptureDelay = 0;
|
|
2082
|
-
this.motionCaptureTime = 0;
|
|
2083
|
-
}
|
|
2084
|
-
}
|
|
2085
|
-
}
|
|
2086
|
-
|
|
2087
|
-
/**
|
|
2088
|
-
* Change in 'zoom-rectangle-enable' property.
|
|
2089
|
-
*/
|
|
2090
|
-
_zoomRectangleEnableChanged(newValue, oldValue) {
|
|
2091
|
-
if (this.threeViewer) {
|
|
2092
|
-
if (newValue) {
|
|
2093
|
-
if (this.zoomRectangleInteractor === undefined) {
|
|
2094
|
-
this.zoomRectangleInteractor = new ZoomRectangleInteractor( this );
|
|
2095
|
-
}
|
|
2096
|
-
this.threeViewer.addInteractor( this.zoomRectangleInteractor );
|
|
2097
|
-
|
|
2098
|
-
if (this.transformClientOnly) {
|
|
2099
|
-
this.zoomRectangleInteractor.clientOnly = true;
|
|
2100
|
-
}
|
|
2101
|
-
}
|
|
2102
|
-
else {
|
|
2103
|
-
this.threeViewer.removeInteractor( this.zoomRectangleInteractor );
|
|
2104
|
-
}
|
|
2105
|
-
}
|
|
2106
|
-
}
|
|
2107
|
-
|
|
2108
|
-
/**
|
|
2109
|
-
* Change in 'pan-enable' property.
|
|
2110
|
-
*/
|
|
2111
|
-
_panEnableChanged(newValue, oldValue) {
|
|
2112
|
-
if (this.threeViewer) {
|
|
2113
|
-
if (newValue) {
|
|
2114
|
-
if (this.panInteractor === undefined) {
|
|
2115
|
-
this.panInteractor = new PanInteractor( this );
|
|
2116
|
-
}
|
|
2117
|
-
this.threeViewer.addInteractor( this.panInteractor );
|
|
2118
|
-
if (this.panZoomEnable) {
|
|
2119
|
-
this.panInteractor.addEventListener('change', this._handlePanChanged.bind(this));
|
|
2120
|
-
this.panInteractor.addEventListener('zoom', this._handlePanZoom.bind(this));
|
|
2121
|
-
this.panInteractor.addEventListener('zoomEnd', this._handlePanZoomEnd.bind(this));
|
|
2122
|
-
}
|
|
2123
|
-
this.panInteractor.setWidthZoomLevel(this.panWidthZoomLevel);
|
|
2124
|
-
this.panInteractor.setHeightZoomLevel(this.panHeightZoomLevel);
|
|
2125
|
-
this.panInteractor.setMaximumZoomLevel(this.panMaximumZoomLevel);
|
|
2126
|
-
this.panInteractor.saveState();
|
|
2127
|
-
}
|
|
2128
|
-
else {
|
|
2129
|
-
this.threeViewer.removeInteractor( this.panInteractor );
|
|
2130
|
-
if (this.panZoomEnable) {
|
|
2131
|
-
this.panInteractor.removeEventListener('change', this._handlePanChanged.bind(this));
|
|
2132
|
-
this.panInteractor.removeEventListener('zoom', this._handlePanZoom.bind(this));
|
|
2133
|
-
this.panInteractor.removeEventListener('zoomEnd', this._handlePanZoomEnd.bind(this));
|
|
2134
|
-
}
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
}
|
|
2138
|
-
|
|
2139
|
-
/**
|
|
2140
|
-
* Change in 'pan-zoom-enable' property.
|
|
2141
|
-
*/
|
|
2142
|
-
_panZoomEnableChanged(newValue, oldValue) {
|
|
2143
|
-
if (this.threeViewer && this.panInteractor) {
|
|
2144
|
-
if (newValue) {
|
|
2145
|
-
this.panInteractor.addEventListener('change', this._handlePanChanged.bind(this));
|
|
2146
|
-
this.panInteractor.addEventListener('zoom', this._handlePanZoom.bind(this));
|
|
2147
|
-
this.panInteractor.addEventListener('zoomEnd', this._handlePanZoomEnd.bind(this));
|
|
2148
|
-
}
|
|
2149
|
-
else {
|
|
2150
|
-
this.panInteractor.removeEventListener('change', this._handlePanChanged.bind(this));
|
|
2151
|
-
this.panInteractor.removeEventListener('zoom', this._handlePanZoom.bind(this));
|
|
2152
|
-
this.panInteractor.removeEventListener('zoomEnd', this._handlePanZoomEnd.bind(this));
|
|
2153
|
-
}
|
|
2154
|
-
}
|
|
2155
|
-
}
|
|
2156
|
-
|
|
2157
|
-
_handlePanChanged(e) {
|
|
2158
|
-
/**
|
|
2159
|
-
* A pan info event occurred.
|
|
2160
|
-
* @event avs-pan-info
|
|
2161
|
-
*/
|
|
2162
|
-
this.dispatchEvent(new CustomEvent('avs-pan-info', e));
|
|
2163
|
-
}
|
|
2164
|
-
|
|
2165
|
-
_handlePanZoom(e) {
|
|
2166
|
-
window.clearTimeout(this.zoomOverlayTimeoutId);
|
|
2167
|
-
|
|
2168
|
-
var width = Math.round(e.detail.widthZoomLevel);
|
|
2169
|
-
var height = Math.round(e.detail.heightZoomLevel);
|
|
2170
|
-
if (width === height) {
|
|
2171
|
-
this.renderRoot.querySelector('#zoomOverlay').innerHTML = width + "%";
|
|
2172
|
-
}
|
|
2173
|
-
else {
|
|
2174
|
-
this.renderRoot.querySelector('#zoomOverlay').innerHTML = width + "%," + height + "%";
|
|
2175
|
-
}
|
|
2176
|
-
|
|
2177
|
-
var coords = this._getAdjustedCoords(e.detail.clientX, e.detail.clientY);
|
|
2178
|
-
const zoomOverlay = this.renderRoot.querySelector('#zoomOverlay') as HTMLDivElement;
|
|
2179
|
-
zoomOverlay.style.left = coords.x + "px";
|
|
2180
|
-
zoomOverlay.style.top = coords.y + "px";
|
|
2181
|
-
zoomOverlay.style.opacity = "1";
|
|
2182
|
-
|
|
2183
|
-
this.pointerDown = true;
|
|
2184
|
-
this._dispatchPickEvents( {type:"HOVER",x:0,y:0,selected:[]} );
|
|
2185
|
-
|
|
2186
|
-
this.zoomOverlayTimeoutId = window.setTimeout(() => {
|
|
2187
|
-
const el = this.renderRoot.querySelector('#zoomOverlay') as HTMLDivElement;
|
|
2188
|
-
el.style.opacity = "0";
|
|
2189
|
-
this.pointerDown = false;
|
|
2190
|
-
}, 1000);
|
|
2191
|
-
}
|
|
2192
|
-
|
|
2193
|
-
_handlePanZoomEnd(e) {
|
|
2194
|
-
this.panWidthZoomLevel = e.detail.widthZoomLevel;
|
|
2195
|
-
this.panHeightZoomLevel = e.detail.heightZoomLevel;
|
|
2196
|
-
}
|
|
2197
|
-
|
|
2198
|
-
/**
|
|
2199
|
-
* Change in 'pan-width-zoom-level' property.
|
|
2200
|
-
*/
|
|
2201
|
-
_panWidthZoomLevelChanged(newValue, oldValue) {
|
|
2202
|
-
if (this.panInteractor) {
|
|
2203
|
-
this.panInteractor.setWidthZoomLevel(newValue);
|
|
2204
|
-
}
|
|
2205
|
-
}
|
|
2206
|
-
|
|
2207
|
-
/**
|
|
2208
|
-
* Change in 'pan-height-zoom-level' property.
|
|
2209
|
-
*/
|
|
2210
|
-
_panHeightZoomLevelChanged(newValue, oldValue) {
|
|
2211
|
-
if (this.panInteractor) {
|
|
2212
|
-
this.panInteractor.setHeightZoomLevel(newValue);
|
|
2213
|
-
}
|
|
2214
|
-
}
|
|
2215
|
-
|
|
2216
|
-
/**
|
|
2217
|
-
* Change in 'pan-maximum-zoom-level' property.
|
|
2218
|
-
*/
|
|
2219
|
-
_panMaximumZoomLevelChanged(newValue, oldValue) {
|
|
2220
|
-
if (this.panInteractor) {
|
|
2221
|
-
this.panInteractor.setMaximumZoomLevel(newValue);
|
|
2222
|
-
}
|
|
2223
|
-
}
|
|
2224
|
-
|
|
2225
|
-
/**
|
|
2226
|
-
* Reset the pan interactor.
|
|
2227
|
-
*/
|
|
2228
|
-
resetPan() {
|
|
2229
|
-
if (this.panInteractor) {
|
|
2230
|
-
this.panInteractor.reset();
|
|
2231
|
-
}
|
|
2232
|
-
}
|
|
2233
|
-
|
|
2234
|
-
/**
|
|
2235
|
-
* Change in 'renderer' property.
|
|
2236
|
-
*/
|
|
2237
|
-
_rendererChanged(newValue, oldValue) {
|
|
2238
|
-
if (oldValue === 'IMAGE') {
|
|
2239
|
-
this.sceneImage.src = 'data:,';
|
|
2240
|
-
this.renderRoot.querySelector('#dataVizDiv').removeChild(this.sceneImage);
|
|
2241
|
-
this.renderRoot.querySelector('#dataVizDiv').removeChild(this.sceneImageMap);
|
|
2242
|
-
}
|
|
2243
|
-
else if (oldValue === 'SVG') {
|
|
2244
|
-
var el = this.svgDiv;
|
|
2245
|
-
while (el.firstChild) el.removeChild(el.firstChild);
|
|
2246
|
-
this.renderRoot.querySelector('#dataVizDiv').removeChild(this.svgDiv);
|
|
2247
|
-
}
|
|
2248
|
-
else if (this.threeViewer) {
|
|
2249
|
-
this.threeViewer.clearGeometry();
|
|
2250
|
-
this.threeViewer.render();
|
|
2251
|
-
this.renderRoot.querySelector('#dataVizDiv').removeChild(this.threeViewer.domElement);
|
|
2252
|
-
}
|
|
2253
|
-
|
|
2254
|
-
if (newValue === 'IMAGE') {
|
|
2255
|
-
if (this.sceneImage === undefined) {
|
|
2256
|
-
this.sceneImage = document.createElement("img");
|
|
2257
|
-
this.sceneImage.setAttribute("id", "sceneImage");
|
|
2258
|
-
this.sceneImage.setAttribute("usemap", "#sceneImageMap");
|
|
2259
|
-
|
|
2260
|
-
this.sceneImageMap = document.createElement("map");
|
|
2261
|
-
this.sceneImageMap.setAttribute("id", "sceneImageMap");
|
|
2262
|
-
this.sceneImageMap.setAttribute("name", "sceneImageMap");
|
|
2263
|
-
}
|
|
2264
|
-
|
|
2265
|
-
this.renderRoot.querySelector('#dataVizDiv').appendChild(this.sceneImage);
|
|
2266
|
-
this.renderRoot.querySelector('#dataVizDiv').appendChild(this.sceneImageMap);
|
|
2267
|
-
this.threeViewer = null;
|
|
2268
|
-
}
|
|
2269
|
-
else if (newValue === 'SVG') {
|
|
2270
|
-
if (this.svgDiv === undefined) {
|
|
2271
|
-
this.svgDiv = document.createElement("div");
|
|
2272
|
-
this.svgDiv.setAttribute("id", "svgDiv");
|
|
2273
|
-
}
|
|
2274
|
-
|
|
2275
|
-
this.renderRoot.querySelector('#dataVizDiv').appendChild(this.svgDiv);
|
|
2276
|
-
this.threeViewer = null;
|
|
2277
|
-
}
|
|
2278
|
-
else {
|
|
2279
|
-
if (!this.threeViewer) {
|
|
2280
|
-
// Create ThreeJS viewer
|
|
2281
|
-
this.threeViewer = new Viewer();
|
|
2282
|
-
|
|
2283
|
-
// Check if the user has requested a specific renderer
|
|
2284
|
-
var rendererId = 'avsDefaultWebGLRenderer';
|
|
2285
|
-
// if (this.rendererProperties.webGLRendererId !== undefined) {
|
|
2286
|
-
// rendererId = this.rendererProperties.webGLRendererId;
|
|
2287
|
-
// }
|
|
2288
|
-
|
|
2289
|
-
// Search for renderer, if not found create one and save to the DOM
|
|
2290
|
-
var renderer = document.getElementById(rendererId) as AvsRenderer;
|
|
2291
|
-
if (renderer === undefined || renderer === null) {
|
|
2292
|
-
renderer = new AvsRenderer();
|
|
2293
|
-
renderer.setAttribute('id', rendererId);
|
|
2294
|
-
document.body.appendChild(renderer);
|
|
2295
|
-
// console.log("create new webGL renderer = " + rendererId);
|
|
2296
|
-
}
|
|
2297
|
-
else {
|
|
2298
|
-
// console.log("reference existing webGL renderer = " + rendererId);
|
|
2299
|
-
}
|
|
2300
|
-
this.threeViewer.setWebGLRenderer(renderer.webGLRenderer);
|
|
2301
|
-
|
|
2302
|
-
this.animator = new Animator();
|
|
2303
|
-
this.threeViewer.setAnimator(this.animator);
|
|
2304
|
-
}
|
|
2305
|
-
|
|
2306
|
-
this.renderRoot.querySelector('#dataVizDiv').appendChild(this.threeViewer.domElement);
|
|
2307
|
-
}
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
/**
|
|
2311
|
-
* Change in 'track-enable' property.
|
|
2312
|
-
*/
|
|
2313
|
-
_trackEnableChanged(newValue, oldValue) {
|
|
2314
|
-
if (newValue) {
|
|
2315
|
-
if (this.rectCanvas === undefined) {
|
|
2316
|
-
this.rectCanvas = document.createElement("canvas");
|
|
2317
|
-
this.rectCanvas.setAttribute("id", "rectCanvas");
|
|
2318
|
-
this.rectCtx = this.rectCanvas.getContext('2d');
|
|
2319
|
-
}
|
|
2320
|
-
this.renderRoot.appendChild(this.rectCanvas);
|
|
2321
|
-
}
|
|
2322
|
-
else {
|
|
2323
|
-
this.renderRoot.removeChild(this.rectCanvas);
|
|
2324
|
-
}
|
|
2325
|
-
}
|
|
2326
|
-
|
|
2327
|
-
/**
|
|
2328
|
-
* Change in 'display-canvas' property.
|
|
2329
|
-
*/
|
|
2330
|
-
_displayCanvasChanged(newValue, oldValue) {
|
|
2331
|
-
if (this.threeViewer) {
|
|
2332
|
-
this.threeViewer.displayCanvas = newValue;
|
|
2333
|
-
}
|
|
2334
|
-
}
|
|
2335
|
-
|
|
2336
|
-
setTooltipHTML(html: string) {
|
|
2337
|
-
this.renderRoot.querySelector('#tooltip').innerHTML = html;
|
|
2338
|
-
}
|
|
2339
|
-
|
|
2340
|
-
showTooltip(clientX: number, clientY: number) {
|
|
2341
|
-
var tooltip = this.renderRoot.querySelector('#tooltip') as HTMLDivElement;
|
|
2342
|
-
var pos = this._calcTooltipPosition(tooltip, clientX, clientY);
|
|
2343
|
-
tooltip.style.left = pos.x + "px";
|
|
2344
|
-
tooltip.style.top = pos.y + "px";
|
|
2345
|
-
tooltip.style.opacity = "1";
|
|
2346
|
-
}
|
|
2347
|
-
|
|
2348
|
-
hideTooltip() {
|
|
2349
|
-
var tooltip = this.renderRoot.querySelector('#tooltip') as HTMLDivElement;
|
|
2350
|
-
tooltip.style.opacity = "0";
|
|
2351
|
-
}
|
|
2352
|
-
|
|
2353
|
-
_calcTooltipPosition(tooltip: HTMLDivElement, clientX: number, clientY: number) {
|
|
2354
|
-
|
|
2355
|
-
// Calculate the tooltip location based on 4 quadrants of the visible portion
|
|
2356
|
-
// of the visualization window
|
|
2357
|
-
|
|
2358
|
-
var dataVizDiv = this.renderRoot.querySelector('#dataVizDiv') as HTMLDivElement;
|
|
2359
|
-
|
|
2360
|
-
var offset = this._getOffset(dataVizDiv);
|
|
2361
|
-
var deltaTop = -Math.min(0, offset.top - window.pageYOffset);
|
|
2362
|
-
var deltaLeft = -Math.min(0, offset.left - window.pageXOffset);
|
|
2363
|
-
var deltaBottom = -Math.min(0, window.innerHeight - (dataVizDiv.offsetHeight + offset.top - window.pageYOffset));
|
|
2364
|
-
var deltaRight = -Math.min(0, window.innerWidth - (dataVizDiv.offsetWidth + offset.left - window.pageXOffset));
|
|
2365
|
-
var vizHeight = dataVizDiv.offsetHeight - deltaTop - deltaBottom;
|
|
2366
|
-
var vizWidth = dataVizDiv.offsetWidth - deltaLeft - deltaRight;
|
|
2367
|
-
var vizHalfX = vizWidth / 2 + deltaLeft;
|
|
2368
|
-
var vizHalfY = vizHeight / 2 + deltaTop;
|
|
2369
|
-
|
|
2370
|
-
var toolPosition = { x: 0, y: 0 };
|
|
2371
|
-
if (clientX < vizHalfX) {
|
|
2372
|
-
var offst = (clientY < vizHalfY) ? 15 : 5;
|
|
2373
|
-
toolPosition.x = clientX + offst + dataVizDiv.offsetLeft;
|
|
2374
|
-
}
|
|
2375
|
-
else {
|
|
2376
|
-
toolPosition.x = clientX - 10 + dataVizDiv.offsetLeft - tooltip.offsetWidth;
|
|
2377
|
-
}
|
|
2378
|
-
if (clientY < vizHalfY) {
|
|
2379
|
-
toolPosition.y = clientY + 5 + dataVizDiv.offsetTop;
|
|
2380
|
-
}
|
|
2381
|
-
else {
|
|
2382
|
-
toolPosition.y = clientY - 10 + dataVizDiv.offsetTop - tooltip.offsetHeight;
|
|
2383
|
-
}
|
|
2384
|
-
|
|
2385
|
-
return toolPosition;
|
|
2386
|
-
}
|
|
2387
|
-
|
|
2388
|
-
_getOffset(dataVizDiv: HTMLDivElement) {
|
|
2389
|
-
var rect = dataVizDiv.getBoundingClientRect(),
|
|
2390
|
-
scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
|
|
2391
|
-
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
2392
|
-
return { top: rect.top + scrollTop, left: rect.left + scrollLeft }
|
|
2393
|
-
}
|
|
2394
|
-
}
|
|
2395
|
-
|
|
2396
|
-
declare global {
|
|
2397
|
-
interface HTMLElementTagNameMap {
|
|
2398
|
-
'avs-go-dataviz': AvsGoDataViz;
|
|
2399
|
-
}
|
|
2400
|
-
}
|