@avs/go 0.12.71730
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avs-go.min.js +2 -0
- package/dist/avs-go.min.js.LICENSE.txt +61 -0
- package/lib/LICENSE-avsthreejs +41 -0
- package/lib/avs-three.module.min.js +2 -0
- package/package.json +34 -0
- package/src/avs-data-source-mixin.js +61 -0
- package/src/avs-go-dataviz.js +1982 -0
- package/src/avs-go-dynamic-html.js +143 -0
- package/src/avs-go-info.js +124 -0
- package/src/avs-http-mixin.js +197 -0
- package/src/avs-renderer.js +36 -0
- package/src/avs-stream-mixin.js +65 -0
- package/src/constants.js +21 -0
- package/src/logo.js +21 -0
- package/webpack.config.js +29 -0
|
@@ -0,0 +1,1982 @@
|
|
|
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 {PolymerElement, html} from '@polymer/polymer/polymer-element.js';
|
|
22
|
+
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
|
|
23
|
+
import {IronResizableBehavior} from '@polymer/iron-resizable-behavior/iron-resizable-behavior.js';
|
|
24
|
+
import {afterNextRender} from '@polymer/polymer/lib/utils/render-status.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 {AvsHttpMixin} from './avs-http-mixin.js';
|
|
28
|
+
import {AvsStreamMixin} from './avs-stream-mixin.js';
|
|
29
|
+
import {AvsDataSourceMixin} from './avs-data-source-mixin.js';
|
|
30
|
+
import {LOGO} from './logo.js';
|
|
31
|
+
import {Euler, Vector3, Quaternion} from 'three';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* `avs-go-dataviz` is a Polymer 3.0 element which requests a data visualization
|
|
35
|
+
* from either the `sceneName` class on the AVS/Go server application running at `url`,
|
|
36
|
+
* or from a JSON file at `url` when `urlLoadJsonFile` is set.
|
|
37
|
+
*
|
|
38
|
+
* The request occurs upon:
|
|
39
|
+
* * An explicit call to `updateViewer()`
|
|
40
|
+
* * A change in `renderer`
|
|
41
|
+
* * Additionally if `manualUpdate` is false:
|
|
42
|
+
* * * Initialization of this element has completed
|
|
43
|
+
* * * This element is resized outside of the `resizeThresold` percentage
|
|
44
|
+
*
|
|
45
|
+
* @customElement
|
|
46
|
+
* @polymer
|
|
47
|
+
* @appliesMixin AvsDataSourceMixin
|
|
48
|
+
* @appliesMixin AvsStreamMixin
|
|
49
|
+
* @appliesMixin AvsHttpMixin
|
|
50
|
+
*/
|
|
51
|
+
export class AvsGoDataViz extends AvsDataSourceMixin(AvsStreamMixin(AvsHttpMixin(mixinBehaviors([IronResizableBehavior], PolymerElement)))) {
|
|
52
|
+
|
|
53
|
+
static get template() {
|
|
54
|
+
return html`
|
|
55
|
+
<style>
|
|
56
|
+
:host {
|
|
57
|
+
display:block;
|
|
58
|
+
width:100%;
|
|
59
|
+
height:100%;
|
|
60
|
+
overflow:hidden;
|
|
61
|
+
}
|
|
62
|
+
#container {
|
|
63
|
+
position:relative;
|
|
64
|
+
width:100%;
|
|
65
|
+
height:100%;
|
|
66
|
+
letter-spacing:normal;
|
|
67
|
+
word-spacing:normal;
|
|
68
|
+
line-height:normal;
|
|
69
|
+
text-indent:0;
|
|
70
|
+
text-transform:none;
|
|
71
|
+
direction:ltr;
|
|
72
|
+
}
|
|
73
|
+
#dataVizDiv {
|
|
74
|
+
position:relative;
|
|
75
|
+
width:100%;
|
|
76
|
+
height:100%;
|
|
77
|
+
}
|
|
78
|
+
#sceneImage {
|
|
79
|
+
width:100%;
|
|
80
|
+
height:100%;
|
|
81
|
+
position:absolute;
|
|
82
|
+
outline:none;
|
|
83
|
+
}
|
|
84
|
+
#rectCanvas {
|
|
85
|
+
position:absolute;
|
|
86
|
+
top:0px;
|
|
87
|
+
left:0px;
|
|
88
|
+
}
|
|
89
|
+
#zoomOverlay {
|
|
90
|
+
position:absolute;
|
|
91
|
+
opacity:0;
|
|
92
|
+
transition:opacity ease 0.3s;
|
|
93
|
+
pointer-events:none;
|
|
94
|
+
background:var(--avs-zoom-overlay-background, rgba(80,80,80,0.75));
|
|
95
|
+
color:var(--avs-zoom-overlay-color, #ffffff);
|
|
96
|
+
border-radius:5px;
|
|
97
|
+
padding:5px;
|
|
98
|
+
transform:translate(-50%, -100%);
|
|
99
|
+
font-size:var(--avs-zoom-overlay-font-size, 10pt);
|
|
100
|
+
font-family:var(--avs-zoom-overlay-font-family);
|
|
101
|
+
font-weight:var(--avs-zoom-overlay-font-weight, bold);
|
|
102
|
+
font-style:var(--avs-zoom-overlay-font-style);
|
|
103
|
+
}
|
|
104
|
+
#tooltip {
|
|
105
|
+
position:absolute;
|
|
106
|
+
opacity:0;
|
|
107
|
+
transition:opacity ease 0.3s;
|
|
108
|
+
pointer-events:none;
|
|
109
|
+
padding:5px;
|
|
110
|
+
border-radius:5px;
|
|
111
|
+
background:var(--avs-tooltip-background, rgb(80,80,80));
|
|
112
|
+
color:var(--avs-tooltip-color, #ffffff);
|
|
113
|
+
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);
|
|
114
|
+
font-size:var(--avs-tooltip-font-size, 10pt);
|
|
115
|
+
font-family:var(--avs-tooltip-font-family);
|
|
116
|
+
font-weight:var(--avs-tooltip-font-weight);
|
|
117
|
+
font-style:var(--avs-tooltip-font-style);
|
|
118
|
+
}
|
|
119
|
+
#spinnerDiv {
|
|
120
|
+
position:absolute;
|
|
121
|
+
left:var(--avs-spinner-left, 50%);
|
|
122
|
+
top:var(--avs-spinner-top, 50%);
|
|
123
|
+
transform:var(--avs-spinner-transform, translate(-50%,-50%));
|
|
124
|
+
}
|
|
125
|
+
#spinner {
|
|
126
|
+
display:none;
|
|
127
|
+
}
|
|
128
|
+
.spin {
|
|
129
|
+
-webkit-animation:spin 2s ease-in-out infinite;
|
|
130
|
+
-moz-animation:spin 2s ease-in-out infinite;
|
|
131
|
+
animation:spin 2s ease-in-out infinite;
|
|
132
|
+
}
|
|
133
|
+
.spinnerBackground {
|
|
134
|
+
fill:var(--avs-spinner-background-color, rgb(0,0,0,0));
|
|
135
|
+
stroke-width:0.0160303
|
|
136
|
+
}
|
|
137
|
+
@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
|
|
138
|
+
@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
|
|
139
|
+
@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
|
|
140
|
+
</style>
|
|
141
|
+
<div id="container">
|
|
142
|
+
<div id="dataVizDiv"></div>
|
|
143
|
+
<div id="zoomOverlay"></div>
|
|
144
|
+
<div id="spinnerDiv">
|
|
145
|
+
<div id="spinner"></div>
|
|
146
|
+
</div>
|
|
147
|
+
<div id="tooltip"></div>
|
|
148
|
+
</div>
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
static get properties() {
|
|
153
|
+
return {
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Don't request a new scene upon initialization or resize.
|
|
157
|
+
*/
|
|
158
|
+
manualUpdate: {
|
|
159
|
+
type: Boolean
|
|
160
|
+
},
|
|
161
|
+
/**
|
|
162
|
+
* Highlight canvas elements when using the `THREEJS` renderer.
|
|
163
|
+
*/
|
|
164
|
+
displayCanvas: {
|
|
165
|
+
type: Boolean,
|
|
166
|
+
observer: "_displayCanvasChanged"
|
|
167
|
+
},
|
|
168
|
+
/**
|
|
169
|
+
* The URL to an instance of AVS/Go server application or file.
|
|
170
|
+
*/
|
|
171
|
+
url: {
|
|
172
|
+
type: String
|
|
173
|
+
},
|
|
174
|
+
/**
|
|
175
|
+
* Enables loading JSON from a file.
|
|
176
|
+
*/
|
|
177
|
+
urlLoadJsonFile: {
|
|
178
|
+
type: Boolean
|
|
179
|
+
},
|
|
180
|
+
/**
|
|
181
|
+
* The name of the scene registered in the library map on the server.
|
|
182
|
+
*/
|
|
183
|
+
sceneName: {
|
|
184
|
+
type: String
|
|
185
|
+
},
|
|
186
|
+
/**
|
|
187
|
+
* User properties for the scene passed directly to the server.
|
|
188
|
+
*/
|
|
189
|
+
sceneUserProperties: {
|
|
190
|
+
type: Object,
|
|
191
|
+
value: {}
|
|
192
|
+
},
|
|
193
|
+
/**
|
|
194
|
+
* The name of the renderer registered in the library map on the server.
|
|
195
|
+
*/
|
|
196
|
+
rendererName: {
|
|
197
|
+
type: String
|
|
198
|
+
},
|
|
199
|
+
/**
|
|
200
|
+
* User properties for the renderer passed directly to the server.
|
|
201
|
+
*/
|
|
202
|
+
rendererUserProperties: {
|
|
203
|
+
type: Object,
|
|
204
|
+
value: {}
|
|
205
|
+
},
|
|
206
|
+
/**
|
|
207
|
+
* The type of renderer to be used to display a scene: `IMAGE`, `SVG` or `THREEJS`
|
|
208
|
+
*/
|
|
209
|
+
renderer: {
|
|
210
|
+
type: String,
|
|
211
|
+
value: "IMAGE",
|
|
212
|
+
observer: "_rendererChanged"
|
|
213
|
+
},
|
|
214
|
+
/**
|
|
215
|
+
* 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`
|
|
216
|
+
*/
|
|
217
|
+
themeName: {
|
|
218
|
+
type: String
|
|
219
|
+
},
|
|
220
|
+
/**
|
|
221
|
+
* Hide the data visualization.
|
|
222
|
+
*/
|
|
223
|
+
hidden: {
|
|
224
|
+
type: Boolean,
|
|
225
|
+
observer: "_hiddenChanged"
|
|
226
|
+
},
|
|
227
|
+
/**
|
|
228
|
+
* Resize threshold (percent) to determine when the update is performed on the client or the server.
|
|
229
|
+
* Default is 10%. Set to zero to disable resize on the server.
|
|
230
|
+
*/
|
|
231
|
+
resizeThreshold: {
|
|
232
|
+
type: Number,
|
|
233
|
+
value: 10
|
|
234
|
+
},
|
|
235
|
+
/**
|
|
236
|
+
* Aspect ratio (w/h) of the viewer if it is unable to determine the height of its parent element.
|
|
237
|
+
*/
|
|
238
|
+
aspectRatio: {
|
|
239
|
+
type: Number,
|
|
240
|
+
value: 1.777777
|
|
241
|
+
},
|
|
242
|
+
/**
|
|
243
|
+
* Number of seconds between pointer moves before an `avs-pointer-timeout` event is dispatched.
|
|
244
|
+
*/
|
|
245
|
+
pointerTimeout: {
|
|
246
|
+
type: Number,
|
|
247
|
+
value: 600
|
|
248
|
+
},
|
|
249
|
+
/**
|
|
250
|
+
* Enables the `avs-tap` event.
|
|
251
|
+
*/
|
|
252
|
+
tapEnable: {
|
|
253
|
+
type: Boolean
|
|
254
|
+
},
|
|
255
|
+
/**
|
|
256
|
+
* The level of geometry within the scene to be modified by the tap event: `CELL`, `CELL_SET` or `SCENE_NODE`
|
|
257
|
+
*/
|
|
258
|
+
tapLevel: {
|
|
259
|
+
type: String
|
|
260
|
+
},
|
|
261
|
+
/**
|
|
262
|
+
* The depth at which an object is selected: `ALL` or `CLOSEST`
|
|
263
|
+
*/
|
|
264
|
+
tapDepth: {
|
|
265
|
+
type: String
|
|
266
|
+
},
|
|
267
|
+
/**
|
|
268
|
+
* Enables highlight of selected geometry in the scene.
|
|
269
|
+
*/
|
|
270
|
+
tapHighlightEnable: {
|
|
271
|
+
type: Boolean
|
|
272
|
+
},
|
|
273
|
+
/**
|
|
274
|
+
* The color to used to highlight the selected objects in the scene.
|
|
275
|
+
*/
|
|
276
|
+
tapHighlightColor: {
|
|
277
|
+
type: String
|
|
278
|
+
},
|
|
279
|
+
/**
|
|
280
|
+
* 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.
|
|
281
|
+
*/
|
|
282
|
+
tapHighlightLayerEnable: {
|
|
283
|
+
type: Boolean
|
|
284
|
+
},
|
|
285
|
+
/**
|
|
286
|
+
* Enables the processing of tap events on the client. `THREEJS` only.
|
|
287
|
+
*/
|
|
288
|
+
tapProcessEventOnClient: {
|
|
289
|
+
type: Boolean
|
|
290
|
+
},
|
|
291
|
+
/**
|
|
292
|
+
* Enables the `avs-track` event.
|
|
293
|
+
*/
|
|
294
|
+
trackEnable: {
|
|
295
|
+
type: Boolean,
|
|
296
|
+
observer: "_trackEnableChanged"
|
|
297
|
+
},
|
|
298
|
+
/**
|
|
299
|
+
* The level of geometry within the scene to be modified by the track event: `CELL`, `CELL_SET` or `SCENE_NODE`
|
|
300
|
+
*/
|
|
301
|
+
trackLevel: {
|
|
302
|
+
type: String
|
|
303
|
+
},
|
|
304
|
+
/**
|
|
305
|
+
* The depth at which an object is selected: `ALL` or `CLOSEST`
|
|
306
|
+
*/
|
|
307
|
+
trackDepth: {
|
|
308
|
+
type: String
|
|
309
|
+
},
|
|
310
|
+
/**
|
|
311
|
+
* Enables highlight of selected geometry in the scene.
|
|
312
|
+
*/
|
|
313
|
+
trackHighlightEnable: {
|
|
314
|
+
type: Boolean
|
|
315
|
+
},
|
|
316
|
+
/**
|
|
317
|
+
* The color to used to highlight the selected objects in the scene.
|
|
318
|
+
*/
|
|
319
|
+
trackHighlightColor: {
|
|
320
|
+
type: String
|
|
321
|
+
},
|
|
322
|
+
/**
|
|
323
|
+
* 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.
|
|
324
|
+
*/
|
|
325
|
+
trackHighlightLayerEnable: {
|
|
326
|
+
type: Boolean
|
|
327
|
+
},
|
|
328
|
+
/**
|
|
329
|
+
* Enables the processing of track events on the client. `THREEJS` only.
|
|
330
|
+
*/
|
|
331
|
+
trackProcessEventOnClient: {
|
|
332
|
+
type: Boolean
|
|
333
|
+
},
|
|
334
|
+
/**
|
|
335
|
+
* Enables the `avs-hover` event.
|
|
336
|
+
*/
|
|
337
|
+
hoverEnable: {
|
|
338
|
+
type: Boolean
|
|
339
|
+
},
|
|
340
|
+
/**
|
|
341
|
+
* The level of geometry within the scene to be modified by the hover event: `CELL`, `CELL_SET` or `SCENE_NODE`
|
|
342
|
+
*/
|
|
343
|
+
hoverLevel: {
|
|
344
|
+
type: String
|
|
345
|
+
},
|
|
346
|
+
/**
|
|
347
|
+
* The depth at which an object is selected: `ALL` or `CLOSEST`
|
|
348
|
+
*/
|
|
349
|
+
hoverDepth: {
|
|
350
|
+
type: String
|
|
351
|
+
},
|
|
352
|
+
/**
|
|
353
|
+
* Enables highlight of selected geometry in the scene.
|
|
354
|
+
*/
|
|
355
|
+
hoverHighlightEnable: {
|
|
356
|
+
type: Boolean
|
|
357
|
+
},
|
|
358
|
+
/**
|
|
359
|
+
* The color to used to highlight the selected objects in the scene.
|
|
360
|
+
*/
|
|
361
|
+
hoverHighlightColor: {
|
|
362
|
+
type: String
|
|
363
|
+
},
|
|
364
|
+
/**
|
|
365
|
+
* 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.
|
|
366
|
+
*/
|
|
367
|
+
hoverHighlightLayerEnable: {
|
|
368
|
+
type: Boolean
|
|
369
|
+
},
|
|
370
|
+
/**
|
|
371
|
+
* Enable the transform interactor. Only available when `renderer` is `THREEJS`
|
|
372
|
+
*
|
|
373
|
+
* Create an interactor for transforming a particular scene object on the client.
|
|
374
|
+
* Use the IGoRenderer.addInteractor() method on the server to select which object to transform.
|
|
375
|
+
*/
|
|
376
|
+
transformEnable: {
|
|
377
|
+
type: Boolean,
|
|
378
|
+
observer: "_transformEnableChanged"
|
|
379
|
+
},
|
|
380
|
+
/**
|
|
381
|
+
* Transform on the client only, do not update the transform matrix on the server.
|
|
382
|
+
*/
|
|
383
|
+
transformClientOnly: {
|
|
384
|
+
type: Boolean,
|
|
385
|
+
observer: "_transformClientOnlyChanged"
|
|
386
|
+
},
|
|
387
|
+
/**
|
|
388
|
+
* Disables rotation of the object.
|
|
389
|
+
*/
|
|
390
|
+
transformRotateDisable: {
|
|
391
|
+
type: Boolean,
|
|
392
|
+
observer: "_transformRotateDisableChanged"
|
|
393
|
+
},
|
|
394
|
+
/**
|
|
395
|
+
* Disables zooming of the object.
|
|
396
|
+
*/
|
|
397
|
+
transformZoomDisable: {
|
|
398
|
+
type: Boolean,
|
|
399
|
+
observer: "_transformZoomDisableChanged"
|
|
400
|
+
},
|
|
401
|
+
/**
|
|
402
|
+
* Disables panning of the object.
|
|
403
|
+
*/
|
|
404
|
+
transformPanDisable: {
|
|
405
|
+
type: Boolean,
|
|
406
|
+
observer: "_transformPanDisableChanged"
|
|
407
|
+
},
|
|
408
|
+
/**
|
|
409
|
+
* The twist angle of the object in degrees.
|
|
410
|
+
*/
|
|
411
|
+
transformTwistAngle: {
|
|
412
|
+
type: Number,
|
|
413
|
+
observer: "_transformValueChanged"
|
|
414
|
+
},
|
|
415
|
+
/**
|
|
416
|
+
* The tilt angle of the object in degrees.
|
|
417
|
+
*/
|
|
418
|
+
transformTiltAngle: {
|
|
419
|
+
type: Number,
|
|
420
|
+
observer: "_transformValueChanged"
|
|
421
|
+
},
|
|
422
|
+
/**
|
|
423
|
+
* The scale of the object in percent.
|
|
424
|
+
*/
|
|
425
|
+
transformScale: {
|
|
426
|
+
type: Number,
|
|
427
|
+
observer: "_transformValueChanged"
|
|
428
|
+
},
|
|
429
|
+
/**
|
|
430
|
+
* Enable the zoom rectangle interactor. Only available when `renderer` is `THREEJS`
|
|
431
|
+
*
|
|
432
|
+
* Create an interactor for scaling an object by drawing a rectangle.
|
|
433
|
+
* Use the IGoRenderer.addInteractor() method on the server to select which object to transform.
|
|
434
|
+
*/
|
|
435
|
+
zoomRectangleEnable: {
|
|
436
|
+
type: Boolean,
|
|
437
|
+
observer: "_zoomRectangleEnableChanged"
|
|
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
|
+
panEnable: {
|
|
445
|
+
type: Boolean,
|
|
446
|
+
observer: "_panEnableChanged"
|
|
447
|
+
},
|
|
448
|
+
/**
|
|
449
|
+
* Use mousewheel or pinch zoom to adjust the pan interactor's zoom level.
|
|
450
|
+
* Otherwise the zoom level must be set using `pan-width-zoom-level` and `pan-height-zoom-level`.
|
|
451
|
+
*/
|
|
452
|
+
panZoomEnable: {
|
|
453
|
+
type: Boolean,
|
|
454
|
+
observer: "_panZoomEnableChanged"
|
|
455
|
+
},
|
|
456
|
+
/**
|
|
457
|
+
* The width zoom level in percent of the original scene greater than 100%
|
|
458
|
+
*/
|
|
459
|
+
panWidthZoomLevel: {
|
|
460
|
+
type: Number,
|
|
461
|
+
observer: "_panWidthZoomLevelChanged"
|
|
462
|
+
},
|
|
463
|
+
/**
|
|
464
|
+
* The height zoom level in percent of the original scene greater than 100%
|
|
465
|
+
*/
|
|
466
|
+
panHeightZoomLevel: {
|
|
467
|
+
type: Number,
|
|
468
|
+
observer: "_panHeightZoomLevelChanged"
|
|
469
|
+
},
|
|
470
|
+
/**
|
|
471
|
+
* The maximum zoom level in percent of the original scene greater than 100%
|
|
472
|
+
* Default is 1000%
|
|
473
|
+
*/
|
|
474
|
+
panMaximumZoomLevel: {
|
|
475
|
+
type: Number,
|
|
476
|
+
observer: "_panMaximumZoomLevelChanged",
|
|
477
|
+
value: 1000
|
|
478
|
+
},
|
|
479
|
+
/**
|
|
480
|
+
* Show animated glyphs. Only available when `renderer` is `THREEJS`
|
|
481
|
+
*/
|
|
482
|
+
animatedGlyphsVisible: {
|
|
483
|
+
type: Boolean,
|
|
484
|
+
observer: "_animatedGlyphsVisibleChanged"
|
|
485
|
+
},
|
|
486
|
+
/**
|
|
487
|
+
* Enable animated glyphs. Only available when `renderer` is `THREEJS`
|
|
488
|
+
*/
|
|
489
|
+
animatedGlyphsEnable: {
|
|
490
|
+
type: Boolean,
|
|
491
|
+
observer: "_animatedGlyphsEnableChanged"
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Default line style and color
|
|
498
|
+
*/
|
|
499
|
+
_rectangleStyle() {
|
|
500
|
+
this.rectCtx.setLineDash([3]);
|
|
501
|
+
this.rectCtx.strokeStyle="#ff0000";
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Assemble the model from our properties to send to the server.
|
|
506
|
+
*/
|
|
507
|
+
_assembleModel(fullReset) {
|
|
508
|
+
if (this.sceneName === undefined) {
|
|
509
|
+
this._logError( JSON.stringify( {"GoType":1, "error":"\'scene-name\' property must be set to the name of the scene registered in the library map on the server."} ) );
|
|
510
|
+
return undefined;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
var model = {};
|
|
514
|
+
|
|
515
|
+
// Scene Properties
|
|
516
|
+
var sceneProperties = {name:this.sceneName};
|
|
517
|
+
if (this.sceneUserProperties !== undefined) {
|
|
518
|
+
sceneProperties.userProperties = this.sceneUserProperties;
|
|
519
|
+
}
|
|
520
|
+
model.sceneProperties = sceneProperties;
|
|
521
|
+
|
|
522
|
+
// Renderer Properties
|
|
523
|
+
var rendererProperties = {width:this.width, height:this.height, name:this.rendererName, type:this.renderer};
|
|
524
|
+
if (this.rendererUserProperties !== undefined) {
|
|
525
|
+
rendererProperties.userProperties = this.rendererUserProperties;
|
|
526
|
+
}
|
|
527
|
+
model.rendererProperties = rendererProperties;
|
|
528
|
+
|
|
529
|
+
// Transform Properties
|
|
530
|
+
if (this.transformInteractor !== undefined) {
|
|
531
|
+
// Update the local transform matrix from the transform interactor, we may have transformed since the last request
|
|
532
|
+
this.transformMatrix = this.transformInteractor.object.matrix.elements.slice();
|
|
533
|
+
this.transformClientOnly = this.transformInteractor.clientOnly;
|
|
534
|
+
}
|
|
535
|
+
if (this.transformMatrix !== undefined && !this.transformClientOnly) {
|
|
536
|
+
rendererProperties.transformMatrix = this.transformMatrix;
|
|
537
|
+
}
|
|
538
|
+
if (fullReset !== undefined) {
|
|
539
|
+
if (this.transformClientOnly && this.transformInteractor !== undefined) {
|
|
540
|
+
this.transformInteractor.fullReset = fullReset;
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
rendererProperties.fullReset = true;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// PanInteractor
|
|
548
|
+
if (this.panEnable) {
|
|
549
|
+
rendererProperties.panProperties = {widthZoomLevel: this.panWidthZoomLevel, heightZoomLevel: this.panHeightZoomLevel};
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Base theme to use from themeName property
|
|
553
|
+
rendererProperties.themeName = this.themeName;
|
|
554
|
+
|
|
555
|
+
var style = window.getComputedStyle(this, null);
|
|
556
|
+
|
|
557
|
+
// Theme Properties from page CSS
|
|
558
|
+
var cssBackgroundColor = style.getPropertyValue("background-color").trim();
|
|
559
|
+
var cssColor = style.getPropertyValue("color").trim();
|
|
560
|
+
var cssFontFamily = style.getPropertyValue("font-family").trim().replace(/['"]+/g, '');
|
|
561
|
+
rendererProperties.cssProperties = {
|
|
562
|
+
sceneBackgroundType: "Solid",
|
|
563
|
+
sceneBackgroundColor: cssBackgroundColor,
|
|
564
|
+
sceneLineColor: cssColor,
|
|
565
|
+
sceneTextColor: cssColor,
|
|
566
|
+
sceneFontFamily: cssFontFamily,
|
|
567
|
+
sceneSurfaceColor: cssColor
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
// Theme Properties from custom CSS
|
|
571
|
+
this._applyCustomCssProperties(rendererProperties.cssProperties, style,
|
|
572
|
+
{
|
|
573
|
+
// Scene
|
|
574
|
+
"sceneBackgroundType": "--avs-scene-background-type",
|
|
575
|
+
"sceneBackgroundColor": "--avs-scene-background-color",
|
|
576
|
+
"sceneBackgroundStartColor": "--avs-scene-background-start-color",
|
|
577
|
+
"sceneBackgroundEndColor": "--avs-scene-background-end-color",
|
|
578
|
+
"sceneBackgroundGradientStyle": "--avs-scene-background-gradient-style",
|
|
579
|
+
"sceneBackgroundGradientInterpolation": "--avs-scene-background-gradient-interpolation",
|
|
580
|
+
"sceneBackgroundGradientColorRepeat": "--avs-scene-background-gradient-color-repeat",
|
|
581
|
+
"sceneHighlightColor": "--avs-scene-highlight-color",
|
|
582
|
+
"sceneSurfaceColor": "--avs-scene-surface-color",
|
|
583
|
+
"scenePointColor": "--avs-scene-point-color",
|
|
584
|
+
"sceneLineColor": "--avs-scene-line-color",
|
|
585
|
+
"sceneLineWidth": "--avs-scene-line-width",
|
|
586
|
+
"sceneLineOpacity": "--avs-scene-line-opacity",
|
|
587
|
+
"sceneTextColor": "--avs-scene-text-color",
|
|
588
|
+
"sceneTextRotation": "--avs-scene-text-rotation",
|
|
589
|
+
"sceneFontFamily": "--avs-scene-font-family",
|
|
590
|
+
"sceneFontStyle": "--avs-scene-font-style",
|
|
591
|
+
"sceneFontWeight": "--avs-scene-font-weight",
|
|
592
|
+
"sceneFontSize": "--avs-scene-font-size",
|
|
593
|
+
// Scene title
|
|
594
|
+
"sceneTitleTextColor": "--avs-scene-title-text-color",
|
|
595
|
+
"sceneTitleTextRotation": "--avs-scene-title-text-rotation",
|
|
596
|
+
"sceneTitleFontFamily": "--avs-scene-title-font-family",
|
|
597
|
+
"sceneTitleFontStyle": "--avs-scene-title-font-style",
|
|
598
|
+
"sceneTitleFontWeight": "--avs-scene-title-font-weight",
|
|
599
|
+
"sceneTitleFontSize": "--avs-scene-title-font-size",
|
|
600
|
+
// Chart
|
|
601
|
+
"chartBackgroundType": "--avs-chart-background-type",
|
|
602
|
+
"chartBackgroundColor": "--avs-chart-background-color",
|
|
603
|
+
"chartBackgroundStartColor": "--avs-chart-background-start-color",
|
|
604
|
+
"chartBackgroundEndColor": "--avs-chart-background-end-color",
|
|
605
|
+
"chartBackgroundGradientStyle": "--avs-chart-background-gradient-style",
|
|
606
|
+
"chartBackgroundGradientInterpolation": "--avs-chart-background-gradient-interpolation",
|
|
607
|
+
"chartBackgroundGradientColorRepeat": "--avs-chart-background-gradient-color-repeat",
|
|
608
|
+
"chartHighlightColor": "--avs-chart-highlight-color",
|
|
609
|
+
"chartSurfaceColor": "--avs-chart-surface-color",
|
|
610
|
+
"chartPointColor": "--avs-chart-point-color",
|
|
611
|
+
"chartLineColor": "--avs-chart-line-color",
|
|
612
|
+
"chartLineWidth": "--avs-chart-line-width",
|
|
613
|
+
"chartLinePattern": "--avs-chart-line-pattern",
|
|
614
|
+
"chartLineOpacity": "--avs-chart-line-opacity",
|
|
615
|
+
"chartTextColor": "--avs-chart-text-color",
|
|
616
|
+
"chartTextRotation": "--avs-chart-text-rotation",
|
|
617
|
+
"chartFontFamily": "--avs-chart-font-family",
|
|
618
|
+
"chartFontStyle": "--avs-chart-font-style",
|
|
619
|
+
"chartFontWeight": "--avs-chart-font-weight",
|
|
620
|
+
"chartFontSize": "--avs-chart-font-size",
|
|
621
|
+
// Chart title
|
|
622
|
+
"chartTitleTextColor": "--avs-chart-title-text-color",
|
|
623
|
+
"chartTitleTextRotation": "--avs-chart-title-text-rotation",
|
|
624
|
+
"chartTitleFontFamily": "--avs-chart-title-font-family",
|
|
625
|
+
"chartTitleFontStyle": "--avs-chart-title-font-style",
|
|
626
|
+
"chartTitleFontWeight": "--avs-chart-title-font-weight",
|
|
627
|
+
"chartTitleFontSize": "--avs-chart-title-font-size",
|
|
628
|
+
// Axis
|
|
629
|
+
"axisLineColor": "--avs-axis-line-color",
|
|
630
|
+
"axisLineWidth": "--avs-axis-line-width",
|
|
631
|
+
"axisLineOpacity": "--avs-axis-line-opacity",
|
|
632
|
+
"axisTextColor": "--avs-axis-text-color",
|
|
633
|
+
"axisTextRotation": "--avs-axis-text-rotation",
|
|
634
|
+
"axisFontFamily": "--avs-axis-font-family",
|
|
635
|
+
"axisFontStyle": "--avs-axis-font-style",
|
|
636
|
+
"axisFontWeight": "--avs-axis-font-weight",
|
|
637
|
+
"axisFontSize": "--avs-axis-font-size",
|
|
638
|
+
// Axis axle
|
|
639
|
+
"axisAxleColor": "--avs-axis-axle-color",
|
|
640
|
+
"axisAxleWidth": "--avs-axis-axle-width",
|
|
641
|
+
// Axis tick mark
|
|
642
|
+
"axisTickMarkColor": "--avs-axis-tick-mark-color",
|
|
643
|
+
"axisTickMarkWidth": "--avs-axis-tick-mark-width",
|
|
644
|
+
// Axis tick line
|
|
645
|
+
"axisTickLineColor": "--avs-axis-tick-line-color",
|
|
646
|
+
"axisTickLineWidth": "--avs-axis-tick-line-width",
|
|
647
|
+
"axisTickLineStyle": "--avs-axis-tick-line-style",
|
|
648
|
+
// Axis title
|
|
649
|
+
"axisTitleTextColor": "--avs-axis-title-text-color",
|
|
650
|
+
"axisTitleTextRotation": "--avs-axis-title-text-rotation",
|
|
651
|
+
"axisTitleFontFamily": "--avs-axis-title-font-family",
|
|
652
|
+
"axisTitleFontStyle": "--avs-axis-title-font-style",
|
|
653
|
+
"axisTitleFontWeight": "--avs-axis-title-font-weight",
|
|
654
|
+
"axisTitleFontSize": "--avs-axis-title-font-size",
|
|
655
|
+
// Axis unit
|
|
656
|
+
"axisUnitTextColor": "--avs-axis-unit-text-color",
|
|
657
|
+
"axisUnitTextRotation": "--avs-axis-unit-text-rotation",
|
|
658
|
+
"axisUnitFontFamily": "--avs-axis-unit-font-family",
|
|
659
|
+
"axisUnitFontStyle": "--avs-axis-unit-font-style",
|
|
660
|
+
"axisUnitFontWeight": "--avs-axis-unit-font-weight",
|
|
661
|
+
"axisUnitFontSize": "--avs-axis-unit-font-size",
|
|
662
|
+
// Axis labels
|
|
663
|
+
"axisLabelTextColor": "--avs-axis-label-text-color",
|
|
664
|
+
"axisLabelTextRotation": "--avs-axis-label-text-rotation",
|
|
665
|
+
"axisLabelFontFamily": "--avs-axis-label-font-family",
|
|
666
|
+
"axisLabelFontStyle": "--avs-axis-label-font-style",
|
|
667
|
+
"axisLabelFontWeight": "--avs-axis-label-font-weight",
|
|
668
|
+
"axisLabelFontSize": "--avs-axis-label-font-size",
|
|
669
|
+
// Legend
|
|
670
|
+
"legendBackgroundColor": "--avs-legend-background-color",
|
|
671
|
+
"legendTextColor": "--avs-legend-text-color",
|
|
672
|
+
"legendTextRotation": "--avs-legend-text-rotation",
|
|
673
|
+
"legendFontFamily": "--avs-legend-font-family",
|
|
674
|
+
"legendFontStyle": "--avs-legend-font-style",
|
|
675
|
+
"legendFontWeight": "--avs-legend-font-weight",
|
|
676
|
+
"legendFontSize": "--avs-legend-font-size",
|
|
677
|
+
// Legend title
|
|
678
|
+
"legendTitleTextColor": "--avs-legend-title-text-color",
|
|
679
|
+
"legendTitleTextRotation": "--avs-legend-title-text-rotation",
|
|
680
|
+
"legendTitleFontFamily": "--avs-legend-title-font-family",
|
|
681
|
+
"legendTitleFontStyle": "--avs-legend-title-font-style",
|
|
682
|
+
"legendTitleFontWeight": "--avs-legend-title-font-weight",
|
|
683
|
+
"legendTitleFontSize": "--avs-legend-title-font-size",
|
|
684
|
+
// Defaults
|
|
685
|
+
"defaultPointSize": "--avs-default-point-size",
|
|
686
|
+
"defaultGlyphSize": "--avs-default-glyph-size",
|
|
687
|
+
"minGlyphSize": "--avs-min-glyph-size",
|
|
688
|
+
"maxGlyphSize": "--avs-max-glyph-size"
|
|
689
|
+
} );
|
|
690
|
+
|
|
691
|
+
this._addDataSourceProperties(model);
|
|
692
|
+
|
|
693
|
+
if (this.renderer === 'THREEJS') {
|
|
694
|
+
this._addStreamProperties(rendererProperties);
|
|
695
|
+
|
|
696
|
+
var styleMap = {};
|
|
697
|
+
this._applyCustomCssProperties(styleMap, style,
|
|
698
|
+
{
|
|
699
|
+
"scene": "--avs-scene-animations",
|
|
700
|
+
"sceneTitle": "--avs-scene-title-animations",
|
|
701
|
+
"chart": "--avs-chart-animations",
|
|
702
|
+
"chartTitle": "--avs-chart-title-animations",
|
|
703
|
+
"axis": "--avs-axis-animations",
|
|
704
|
+
"legend": "--avs-legend-animations",
|
|
705
|
+
"legendTitle": "--avs-legend-title-animations",
|
|
706
|
+
"glyph": "--avs-glyph-animations",
|
|
707
|
+
"transform": "--avs-transform-animation"
|
|
708
|
+
} );
|
|
709
|
+
this.animator.setStyleMap(styleMap);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
return model;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
*
|
|
717
|
+
*/
|
|
718
|
+
_applyCustomCssProperties(cssProperties, style, values) {
|
|
719
|
+
for (var key in values) {
|
|
720
|
+
if (values.hasOwnProperty(key)) {
|
|
721
|
+
var css = style.getPropertyValue(values[key]).trim();
|
|
722
|
+
if (css.length > 0) {
|
|
723
|
+
cssProperties[key] = css;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
*
|
|
731
|
+
*/
|
|
732
|
+
_onResize() {
|
|
733
|
+
if (!this.urlLoadJsonFile &&
|
|
734
|
+
!this.manualUpdate &&
|
|
735
|
+
this.resizeThreshold > 0 &&
|
|
736
|
+
(this.clientWidth < this.lowResizeWidth ||
|
|
737
|
+
this.clientWidth > this.highResizeWidth ||
|
|
738
|
+
this.clientHeight < this.lowResizeHeight ||
|
|
739
|
+
this.clientHeight > this.highResizeHeight)) {
|
|
740
|
+
|
|
741
|
+
this.updateViewer();
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
this._updateViewerClient();
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
*
|
|
750
|
+
*/
|
|
751
|
+
_updateSize() {
|
|
752
|
+
// Get the width provided by our container
|
|
753
|
+
this.width = this.clientWidth;
|
|
754
|
+
if (this.width <= 0) {
|
|
755
|
+
this.width = 200; // fallback if clientWidth fails
|
|
756
|
+
this.$.container.style.width = this.width + "px";
|
|
757
|
+
}
|
|
758
|
+
else {
|
|
759
|
+
this.$.container.style.width = "100%";
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Get the height provided by our container
|
|
763
|
+
this.height = this.clientHeight;
|
|
764
|
+
if (this.height <= 0) {
|
|
765
|
+
if (this.aspectRatio > 0.1) {
|
|
766
|
+
// Use the aspect ratio if one is set
|
|
767
|
+
this.height = this.width / this.aspectRatio;
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
this.height = 200; // fallback if clientHeight fails
|
|
771
|
+
}
|
|
772
|
+
this.$.container.style.height = this.height + "px";
|
|
773
|
+
}
|
|
774
|
+
else {
|
|
775
|
+
this.$.container.style.height = "100%";
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
if (this.rectCanvas) {
|
|
779
|
+
this.rectCanvas.width = this.width;
|
|
780
|
+
this.rectCanvas.height = this.height;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
showSpinner() {
|
|
785
|
+
var spinner = window.getComputedStyle(this, null).getPropertyValue("--avs-spinner").trim().replace(/['"]+/g, '');
|
|
786
|
+
if (spinner.length > 0) {
|
|
787
|
+
fetch(spinner)
|
|
788
|
+
.then((response) => {
|
|
789
|
+
if (!response.ok) {
|
|
790
|
+
throw new Error(response);
|
|
791
|
+
}
|
|
792
|
+
return response.text();
|
|
793
|
+
})
|
|
794
|
+
.then((html) => {
|
|
795
|
+
this.$.spinner.innerHTML = html;
|
|
796
|
+
})
|
|
797
|
+
.catch((error) => {
|
|
798
|
+
this.$.spinner.innerHTML = '';
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
else {
|
|
802
|
+
this.$.spinner.innerHTML = LOGO;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
this.$.spinner.style.display = 'block';
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
hideSpinner() {
|
|
809
|
+
this.$.spinner.style.display = 'none';
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
startSpinner() {
|
|
813
|
+
this.$.spinner.className = 'spin';
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
stopSpinner() {
|
|
817
|
+
this.$.spinner.className = '';
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Send the request to the server.
|
|
822
|
+
*/
|
|
823
|
+
updateViewer(fullReset) {
|
|
824
|
+
this._updateSize();
|
|
825
|
+
|
|
826
|
+
this.lowResizeWidth = (100 - this.resizeThreshold) / 100 * this.width;
|
|
827
|
+
this.highResizeWidth = (100 + this.resizeThreshold) / 100 * this.width;
|
|
828
|
+
this.lowResizeHeight = (100 - this.resizeThreshold) / 100 * this.height;
|
|
829
|
+
this.highResizeHeight = (100 + this.resizeThreshold) / 100 * this.height;
|
|
830
|
+
|
|
831
|
+
this.showSpinner();
|
|
832
|
+
if (this.url !== undefined && this.url !== null) {
|
|
833
|
+
this.startSpinner();
|
|
834
|
+
|
|
835
|
+
// Use avs-http-mixin to send the model to the server
|
|
836
|
+
if (this.urlLoadJsonFile) {
|
|
837
|
+
this.chunkFile = 0;
|
|
838
|
+
this._httpRequest(this.url, this._handleHttpResponse.bind(this), undefined, this._handleHttpError.bind(this));
|
|
839
|
+
}
|
|
840
|
+
else {
|
|
841
|
+
var model = this._assembleModel(fullReset);
|
|
842
|
+
if (model !== undefined) {
|
|
843
|
+
this._httpRequest(this.url, this._handleHttpResponse.bind(this), undefined, this._handleHttpError.bind(this), model);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* HTTP error handler.
|
|
851
|
+
* @param event
|
|
852
|
+
*/
|
|
853
|
+
_handleHttpError(event) {
|
|
854
|
+
this.hideSpinner();
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
*
|
|
859
|
+
*/
|
|
860
|
+
_updateViewerClient() {
|
|
861
|
+
this._updateSize();
|
|
862
|
+
if (this.renderer === 'THREEJS') {
|
|
863
|
+
this.threeViewer.render(true);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
*
|
|
869
|
+
*/
|
|
870
|
+
clear() {
|
|
871
|
+
if (this.renderer === 'THREEJS') {
|
|
872
|
+
this.threeViewer.clearGeometry();
|
|
873
|
+
this.threeViewer.render();
|
|
874
|
+
}
|
|
875
|
+
else if (this.renderer === 'SVG') {
|
|
876
|
+
var el = this.svgDiv;
|
|
877
|
+
while (el.firstChild) el.removeChild(el.firstChild);
|
|
878
|
+
}
|
|
879
|
+
else {
|
|
880
|
+
this.sceneImage.src = 'data:,';
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
this.showSpinner();
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/**
|
|
887
|
+
* HTTP response handler.
|
|
888
|
+
* @param json JSON parsed from HTTP response.
|
|
889
|
+
*/
|
|
890
|
+
_handleHttpResponse(json) {
|
|
891
|
+
var loadComplete = true;
|
|
892
|
+
|
|
893
|
+
if (json !== undefined) {
|
|
894
|
+
|
|
895
|
+
if (json.selectionInfo !== undefined) {
|
|
896
|
+
this._dispatchPickEvents(json.selectionInfo);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
if (json.sceneInfo !== undefined) {
|
|
900
|
+
var sceneEvent = {detail: json.sceneInfo};
|
|
901
|
+
/**
|
|
902
|
+
* Scene info from the server.
|
|
903
|
+
* @event avs-scene-info
|
|
904
|
+
*/
|
|
905
|
+
this.dispatchEvent(new CustomEvent('avs-scene-info', sceneEvent));
|
|
906
|
+
|
|
907
|
+
// Set tooltip and zoom overlay style to reversed theme
|
|
908
|
+
if (json.sceneInfo.backgroundColor !== undefined) {
|
|
909
|
+
var col = json.sceneInfo.backgroundColor.match(/[0-9.]+/gi);
|
|
910
|
+
var bgCol = window.getComputedStyle(this.parentNode, null).getPropertyValue("background-color").trim().match(/[0-9.]+/gi);
|
|
911
|
+
var blendedR = (col[0] * col[3]);
|
|
912
|
+
var blendedG = (col[1] * col[3]);
|
|
913
|
+
var blendedB = (col[2] * col[3]);
|
|
914
|
+
if (bgCol) {
|
|
915
|
+
// In case sceneInfo.backgroundColor is transparent, blend with our parent's background color
|
|
916
|
+
blendedR += (bgCol[0] * (1 - col[3]));
|
|
917
|
+
blendedG += (bgCol[1] * (1 - col[3]));
|
|
918
|
+
blendedB += (bgCol[2] * (1 - col[3]));
|
|
919
|
+
}
|
|
920
|
+
this.$.zoomOverlay.style.color = "var(--avs-zoom-overlay-color, rgb(" + blendedR + "," + blendedG + "," + blendedB + "))";
|
|
921
|
+
this.$.tooltip.style.color = "var(--avs-tooltip-color, rgb(" + blendedR + "," + blendedG + "," + blendedB + "))";
|
|
922
|
+
}
|
|
923
|
+
if (json.sceneInfo.color !== undefined) {
|
|
924
|
+
var col = json.sceneInfo.color.match(/[0-9.]+/gi);
|
|
925
|
+
this.$.zoomOverlay.style.background = "var(--avs-zoom-overlay-background, rgba(" + col[0] + "," + col[1] + "," + col[2] + "))";
|
|
926
|
+
this.$.tooltip.style.background = "var(--avs-tooltip-background, rgb(" + col[0] + "," + col[1] + "," + col[2] + "))";
|
|
927
|
+
}
|
|
928
|
+
if (json.sceneInfo.fontFamily !== undefined) {
|
|
929
|
+
this.$.zoomOverlay.style.fontFamily = "var(--avs-zoom-overlay-font-family, " + json.sceneInfo.fontFamily + ")";
|
|
930
|
+
this.$.tooltip.style.fontFamily = "var(--avs-tooltip-font-family, " + json.sceneInfo.fontFamily + ")";
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
if (json.image !== undefined) {
|
|
935
|
+
|
|
936
|
+
if (json.image.startsWith("?app=image")) {
|
|
937
|
+
this.sceneImage.src = this.url + json.image;
|
|
938
|
+
}
|
|
939
|
+
else {
|
|
940
|
+
this.sceneImage.src = json.image;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
if (json.imagemap !== undefined) {
|
|
944
|
+
this.sceneImageMap.innerHTML = decodeURIComponent(json.imagemap.replace(/\+/g, '%20'));
|
|
945
|
+
|
|
946
|
+
this.imageMapData = Array.from(this.sceneImageMap.querySelectorAll('area')).map(area => {
|
|
947
|
+
return {
|
|
948
|
+
shape: area.getAttribute('shape'),
|
|
949
|
+
coords: area.getAttribute('coords').split(',').map(Number),
|
|
950
|
+
seriesIndex: area.getAttribute('series-index'),
|
|
951
|
+
itemIndex: area.getAttribute('item-index'),
|
|
952
|
+
componentInfo: area.getAttribute('component-info')
|
|
953
|
+
};
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
else {
|
|
957
|
+
this.sceneImageMap.innerHTML = "";
|
|
958
|
+
this.imageMapData = undefined;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
else if (json.svg !== undefined) {
|
|
962
|
+
this.svgDiv.innerHTML = decodeURIComponent(json.svg.replace(/\+/g, '%20'));
|
|
963
|
+
}
|
|
964
|
+
else if (json.threejs !== undefined) {
|
|
965
|
+
this.threeViewer.loadGeometryAsJson(json.threejs);
|
|
966
|
+
}
|
|
967
|
+
else if (json.chunkId !== undefined) {
|
|
968
|
+
this.threeViewer.loadGeometryAsEvents(json);
|
|
969
|
+
|
|
970
|
+
if (json.moreChunks === true) {
|
|
971
|
+
if (this.urlLoadJsonFile) {
|
|
972
|
+
this.chunkFile++;
|
|
973
|
+
const urlBase = this.url.substring(0, this.url.lastIndexOf('.')) || this.url;
|
|
974
|
+
const ext = this.url.split('.').pop();
|
|
975
|
+
this._httpRequest(urlBase + '-' + this.chunkFile + '.' + ext, this._handleHttpResponse.bind(this), undefined, this._handleHttpError.bind(this));
|
|
976
|
+
}
|
|
977
|
+
else {
|
|
978
|
+
var model = this._assembleModel();
|
|
979
|
+
if (model !== undefined) {
|
|
980
|
+
model.rendererProperties.streamProperties.chunkId = json.chunkId;
|
|
981
|
+
this._httpRequest(this.url, this._handleHttpResponse.bind(this), undefined, this._handleHttpError.bind(this), model);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
loadComplete = false;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
else if (this.urlLoadJsonFile) {
|
|
988
|
+
this.threeViewer.loadGeometryAsJson(json);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
if (loadComplete) {
|
|
993
|
+
// Hide the spinner and grab the scene background color for next time
|
|
994
|
+
// Disable background temporarily
|
|
995
|
+
this.hideSpinner();
|
|
996
|
+
this.stopSpinner();
|
|
997
|
+
/* if (json.backgroundColor !== undefined) {
|
|
998
|
+
this.updateStyles({'--avs-spinner-background-color': json.backgroundColor});
|
|
999
|
+
}*/
|
|
1000
|
+
|
|
1001
|
+
/**
|
|
1002
|
+
* Scene load has completed.
|
|
1003
|
+
* @event avs-load-complete
|
|
1004
|
+
*/
|
|
1005
|
+
this.dispatchEvent(new CustomEvent('avs-load-complete'));
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
/**
|
|
1010
|
+
* @param e
|
|
1011
|
+
*/
|
|
1012
|
+
_handleTap(e) {
|
|
1013
|
+
var adjustedCoords = this._getAdjustedCoords(e.detail.x, e.detail.y);
|
|
1014
|
+
|
|
1015
|
+
var pickProperties = {type:"TAP", x:adjustedCoords.x, y:adjustedCoords.y};
|
|
1016
|
+
|
|
1017
|
+
if (this.tapLevel !== undefined) pickProperties.level = this.tapLevel;
|
|
1018
|
+
if (this.tapDepth !== undefined) pickProperties.depth = this.tapDepth;
|
|
1019
|
+
if (this.tapHighlightEnable) pickProperties.highlight = true;
|
|
1020
|
+
if (this.tapHighlightColor !== undefined) pickProperties.highlightColor = this.tapHighlightColor;
|
|
1021
|
+
if (this.tapHighlightLayerEnable) pickProperties.highlightLayer = true;
|
|
1022
|
+
|
|
1023
|
+
this._processPick( pickProperties, this.tapProcessEventOnClient, e.originalTarget );
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* @param e
|
|
1028
|
+
*/
|
|
1029
|
+
_handleTrack(e) {
|
|
1030
|
+
var adjustedCoords = this._getAdjustedRectangleCoords(e);
|
|
1031
|
+
|
|
1032
|
+
switch(e.detail.state) {
|
|
1033
|
+
case 'start':
|
|
1034
|
+
break;
|
|
1035
|
+
|
|
1036
|
+
case 'track':
|
|
1037
|
+
this.rectCtx.clearRect(0,0,this.width,this.height);
|
|
1038
|
+
this._rectangleStyle();
|
|
1039
|
+
this.rectCtx.strokeRect(adjustedCoords.left, adjustedCoords.top, adjustedCoords.right - adjustedCoords.left, adjustedCoords.bottom - adjustedCoords.top);
|
|
1040
|
+
break;
|
|
1041
|
+
|
|
1042
|
+
case 'end':
|
|
1043
|
+
this.rectCtx.clearRect(0,0,this.width,this.height);
|
|
1044
|
+
|
|
1045
|
+
var pickProperties = {type:"TRACK"};
|
|
1046
|
+
pickProperties.left = adjustedCoords.left;
|
|
1047
|
+
pickProperties.right = adjustedCoords.right;
|
|
1048
|
+
pickProperties.top = adjustedCoords.top;
|
|
1049
|
+
pickProperties.bottom = adjustedCoords.bottom;
|
|
1050
|
+
|
|
1051
|
+
if (this.trackLevel !== undefined) pickProperties.level = this.trackLevel;
|
|
1052
|
+
if (this.trackDepth !== undefined) pickProperties.depth = this.trackDepth;
|
|
1053
|
+
if (this.trackHighlightEnable) pickProperties.highlight = true;
|
|
1054
|
+
if (this.trackHighlightColor !== undefined) pickProperties.highlightColor = this.trackHighlightColor;
|
|
1055
|
+
if (this.trackHighlightLayerEnable) pickProperties.highlightLayer = true;
|
|
1056
|
+
|
|
1057
|
+
this._processPick( pickProperties, this.trackProcessEventOnClient );
|
|
1058
|
+
break;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
/**
|
|
1063
|
+
* @param e
|
|
1064
|
+
*/
|
|
1065
|
+
_handlePointerDown(e) {
|
|
1066
|
+
this.pointerDownX = e.clientX;
|
|
1067
|
+
this.pointerDownY = e.clientY;
|
|
1068
|
+
|
|
1069
|
+
this.pointerDown = true;
|
|
1070
|
+
|
|
1071
|
+
if (this.tapEnable && e.buttons & 1) {
|
|
1072
|
+
this.tapping = true;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
if (this.trackEnable && e.buttons & 2) {
|
|
1076
|
+
this.tracking = 1;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* @param e
|
|
1082
|
+
*/
|
|
1083
|
+
_handlePointerMove(e) {
|
|
1084
|
+
if (this.tracking >= 1) {
|
|
1085
|
+
if (this.tracking === 1) {
|
|
1086
|
+
var dx = Math.abs(e.clientX - this.pointerDownX);
|
|
1087
|
+
var dy = Math.abs(e.clientY - this.pointerDownY);
|
|
1088
|
+
if (dx*dx + dy*dy >= 5) {
|
|
1089
|
+
this.tracking = 2;
|
|
1090
|
+
this._handleTrack({detail:{state:"start", x:e.clientX, y:e.clientY, dx:e.clientX-this.pointerDownX, dy:e.clientY-this.pointerDownY}});
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
if (this.tracking === 2) {
|
|
1094
|
+
this._handleTrack({detail:{state:"track", x:e.clientX, y:e.clientY, dx:e.clientX-this.pointerDownX, dy:e.clientY-this.pointerDownY}});
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
if (this.hoverEnable) {
|
|
1099
|
+
var adjustedCoords = this._getAdjustedCoords(e.clientX, e.clientY);
|
|
1100
|
+
var pickProperties = {type:"HOVER", x:adjustedCoords.x, y:adjustedCoords.y};
|
|
1101
|
+
|
|
1102
|
+
if (this.pointerDown) {
|
|
1103
|
+
pickProperties.selected = {};
|
|
1104
|
+
this._dispatchPickEvents( pickProperties );
|
|
1105
|
+
}
|
|
1106
|
+
else {
|
|
1107
|
+
if (this.hoverLevel !== undefined) pickProperties.level = this.hoverLevel;
|
|
1108
|
+
if (this.hoverDepth !== undefined) pickProperties.depth = this.hoverDepth;
|
|
1109
|
+
if (this.hoverHighlightEnable) pickProperties.highlight = true;
|
|
1110
|
+
if (this.hoverHighlightColor !== undefined) pickProperties.highlightColor = this.hoverHighlightColor;
|
|
1111
|
+
if (this.hoverHighlightLayerEnable) pickProperties.highlightLayer = true;
|
|
1112
|
+
|
|
1113
|
+
this._processPick( pickProperties, true, e.originalTarget );
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
this._resetTimer();
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/**
|
|
1121
|
+
* @param e
|
|
1122
|
+
*/
|
|
1123
|
+
_handlePointerUp(e) {
|
|
1124
|
+
this.pointerDown = false;
|
|
1125
|
+
|
|
1126
|
+
if (this.tapping) {
|
|
1127
|
+
this.tapping = false;
|
|
1128
|
+
var dx = Math.abs(e.clientX - this.pointerDownX);
|
|
1129
|
+
var dy = Math.abs(e.clientY - this.pointerDownY);
|
|
1130
|
+
if (dx*dx + dy*dy < 25) {
|
|
1131
|
+
this._handleTap({detail:{x:e.clientX, y:e.clientY}});
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
if (this.tracking > 1) {
|
|
1136
|
+
this.tracking = 0;
|
|
1137
|
+
this._handleTrack({detail:{state:"end", x:e.clientX, y:e.clientY, dx:e.clientX-this.pointerDownX, dy:e.clientY-this.pointerDownY}});
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
_getAdjustedCoords(x, y) {
|
|
1142
|
+
var rect = this.$.dataVizDiv.getBoundingClientRect();
|
|
1143
|
+
var x = Math.round(x - rect.left);
|
|
1144
|
+
var y = Math.round(y - rect.top);
|
|
1145
|
+
var clampX = Math.max(0, Math.min(x, this.width));
|
|
1146
|
+
var clampY = Math.max(0, Math.min(y, this.height));
|
|
1147
|
+
|
|
1148
|
+
return {x:clampX, y:clampY};
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
_getAdjustedRectangleCoords(e) {
|
|
1152
|
+
var rect = this.$.dataVizDiv.getBoundingClientRect();
|
|
1153
|
+
var x = Math.round(e.detail.x - rect.left);
|
|
1154
|
+
var y = Math.round(e.detail.y - rect.top);
|
|
1155
|
+
var clampX = Math.max(0, Math.min(x, this.width));
|
|
1156
|
+
var clampY = Math.max(0, Math.min(y, this.height));
|
|
1157
|
+
var startX = x - e.detail.dx;
|
|
1158
|
+
var startY = y - e.detail.dy;
|
|
1159
|
+
|
|
1160
|
+
var left = Math.min(startX, clampX);
|
|
1161
|
+
var right = Math.max(startX, clampX);
|
|
1162
|
+
var top = Math.min(startY, clampY);
|
|
1163
|
+
var bottom = Math.max(startY, clampY);
|
|
1164
|
+
|
|
1165
|
+
return {left: left, right: right, top: top, bottom: bottom};
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
_processPick( pickProperties, processEventOnClient, originalTarget ) {
|
|
1169
|
+
if (processEventOnClient) {
|
|
1170
|
+
if (this.renderer === 'THREEJS') {
|
|
1171
|
+
// ThreeJS client side pick processing
|
|
1172
|
+
|
|
1173
|
+
this.threeViewer.setPickDepth( this._getPickDepth(pickProperties.depth) );
|
|
1174
|
+
if (pickProperties.type === 'TRACK') {
|
|
1175
|
+
this.threeViewer.setPickRectangle( pickProperties.left, pickProperties.top, pickProperties.right, pickProperties.bottom );
|
|
1176
|
+
}
|
|
1177
|
+
else {
|
|
1178
|
+
this.threeViewer.setPickRay( pickProperties.x, pickProperties.y );
|
|
1179
|
+
}
|
|
1180
|
+
this.threeViewer.pick();
|
|
1181
|
+
|
|
1182
|
+
var selectionList = {};
|
|
1183
|
+
if (pickProperties.level === "CELL") {
|
|
1184
|
+
selectionList = this.threeViewer.getPickedCells();
|
|
1185
|
+
}
|
|
1186
|
+
else if (pickProperties.level === "CELL_SET") {
|
|
1187
|
+
selectionList = this.threeViewer.getPickedCellSets();
|
|
1188
|
+
}
|
|
1189
|
+
else {
|
|
1190
|
+
selectionList = this.threeViewer.getPickedSceneNodes();
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
pickProperties.selected = this.threeViewer.getSelectionInfo(selectionList);
|
|
1194
|
+
this._dispatchPickEvents(pickProperties);
|
|
1195
|
+
|
|
1196
|
+
if (pickProperties.highlight) {
|
|
1197
|
+
this.threeViewer.highlightColor.set( pickProperties.highlightColor );
|
|
1198
|
+
this.threeViewer.highlightObjects( selectionList, pickProperties.highlightLayer );
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
else if (this.renderer === 'SVG') {
|
|
1202
|
+
// Client side SVG pick processing
|
|
1203
|
+
|
|
1204
|
+
pickProperties.selected = [];
|
|
1205
|
+
|
|
1206
|
+
if (pickProperties.type !== 'TRACK' && (originalTarget.nodeName === "polygon" || originalTarget.nodeName === "circle")) {
|
|
1207
|
+
var selectedInfo = {};
|
|
1208
|
+
|
|
1209
|
+
var seriesIndex = null;
|
|
1210
|
+
var element = originalTarget.parentElement;
|
|
1211
|
+
while (element !== null && (seriesIndex = element.getAttribute("series-index")) === null) {
|
|
1212
|
+
element = element.parentElement;
|
|
1213
|
+
}
|
|
1214
|
+
if (seriesIndex !== null) {
|
|
1215
|
+
selectedInfo.seriesIndex = parseInt(seriesIndex);
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
var itemIndex = null;
|
|
1219
|
+
element = originalTarget.parentElement;
|
|
1220
|
+
while (element !== null && (itemIndex = element.getAttribute("item-index")) === null) {
|
|
1221
|
+
element = element.parentElement;
|
|
1222
|
+
}
|
|
1223
|
+
if (itemIndex !== null) {
|
|
1224
|
+
selectedInfo.itemIndex = parseInt(itemIndex);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
var componentInfo = null;
|
|
1228
|
+
element = originalTarget.parentElement;
|
|
1229
|
+
while (element !== null && (componentInfo = element.getAttribute("component-info")) === null) {
|
|
1230
|
+
element = element.parentElement;
|
|
1231
|
+
}
|
|
1232
|
+
if (componentInfo !== null) {
|
|
1233
|
+
selectedInfo.componentInfo = decodeURIComponent(componentInfo);
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
pickProperties.selected.push(selectedInfo);
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
this._dispatchPickEvents(pickProperties);
|
|
1240
|
+
|
|
1241
|
+
if (pickProperties.highlight) {
|
|
1242
|
+
if (this.highlightSvg === undefined) {
|
|
1243
|
+
this.highlightSvg = [];
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
for (var i = 0; i < this.highlightSvg.length; i++) {
|
|
1247
|
+
this.highlightSvg[i].setAttribute("fill", this.highlightSvg[i].getAttribute("saveFill"));
|
|
1248
|
+
}
|
|
1249
|
+
this.highlightSvg.length = 0;
|
|
1250
|
+
|
|
1251
|
+
if (pickProperties.type !== 'TRACK' && (originalTarget.nodeName === "polygon" || originalTarget.nodeName === "circle")) {
|
|
1252
|
+
this.highlightSvg.push(originalTarget);
|
|
1253
|
+
originalTarget.setAttribute("saveFill", originalTarget.getAttribute("fill"));
|
|
1254
|
+
originalTarget.setAttribute("fill", pickProperties.highlightColor);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
else {
|
|
1259
|
+
// Client side imagemap pick processing
|
|
1260
|
+
|
|
1261
|
+
pickProperties.selected = [];
|
|
1262
|
+
|
|
1263
|
+
if (pickProperties.type !== 'TRACK' && this.imageMapData !== undefined) {
|
|
1264
|
+
for (var i = 0; i < this.imageMapData.length; i++) {
|
|
1265
|
+
var area = this.imageMapData[i];
|
|
1266
|
+
if (area.shape === "poly" && this._pointInPoly(pickProperties.x, pickProperties.y, area.coords) !== false) {
|
|
1267
|
+
|
|
1268
|
+
var selectedInfo = {};
|
|
1269
|
+
if (area.seriesIndex !== null) {
|
|
1270
|
+
selectedInfo.seriesIndex = parseInt(area.seriesIndex);
|
|
1271
|
+
}
|
|
1272
|
+
if (area.itemIndex !== null) {
|
|
1273
|
+
selectedInfo.itemIndex = parseInt(area.itemIndex);
|
|
1274
|
+
}
|
|
1275
|
+
if (area.componentInfo !== null) {
|
|
1276
|
+
selectedInfo.componentInfo = decodeURIComponent(area.componentInfo);
|
|
1277
|
+
}
|
|
1278
|
+
pickProperties.selected.push(selectedInfo);
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
this._dispatchPickEvents(pickProperties);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
else if (!this.urlLoadJsonFile) {
|
|
1287
|
+
// Server side pick processing
|
|
1288
|
+
|
|
1289
|
+
this.showSpinner();
|
|
1290
|
+
if (this.url !== undefined && this.url !== null) {
|
|
1291
|
+
this.startSpinner();
|
|
1292
|
+
|
|
1293
|
+
// Use avs-http-mixin to send the model to the server
|
|
1294
|
+
var model = this._assembleModel();
|
|
1295
|
+
if (model !== undefined) {
|
|
1296
|
+
model.rendererProperties.pickProperties = pickProperties;
|
|
1297
|
+
this._httpRequest(this.url, this._handleHttpResponse.bind(this), undefined, this._handleHttpError.bind(this), model);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
_pointInPoly(x, y, coords) {
|
|
1304
|
+
var dx1 = coords[0] - x;
|
|
1305
|
+
var dy1 = coords[1] - y;
|
|
1306
|
+
var dx2, dy2, f;
|
|
1307
|
+
var k = 0;
|
|
1308
|
+
|
|
1309
|
+
for (var i=2; i < coords.length; i+=2) {
|
|
1310
|
+
|
|
1311
|
+
dy2 = coords[i+1] - y;
|
|
1312
|
+
|
|
1313
|
+
if ((dy1 < 0 && dy2 < 0) || (dy1 > 0 && dy2 > 0)) {
|
|
1314
|
+
dy1 = dy2;
|
|
1315
|
+
dx1 = coords[i] - x;
|
|
1316
|
+
continue;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
dx2 = coords[i] - x;
|
|
1320
|
+
|
|
1321
|
+
if (dy2 > 0 && dy1 <= 0) {
|
|
1322
|
+
f = (dx1 * dy2) - (dx2 * dy1);
|
|
1323
|
+
if (f > 0) k++;
|
|
1324
|
+
else if (f === 0) return 0;
|
|
1325
|
+
}
|
|
1326
|
+
else if (dy1 > 0 && dy2 <= 0) {
|
|
1327
|
+
f = (dx1 * dy2) - (dx2 * dy1);
|
|
1328
|
+
if (f < 0) k++;
|
|
1329
|
+
else if (f === 0) return 0;
|
|
1330
|
+
}
|
|
1331
|
+
else if (dy2 === 0 && dy1 < 0) {
|
|
1332
|
+
f = (dx1 * dy2) - (dx2 * dy1);
|
|
1333
|
+
if (f === 0) return 0;
|
|
1334
|
+
}
|
|
1335
|
+
else if (dy1 === 0 && dy2 < 0) {
|
|
1336
|
+
f = dx1 * dy2 - dx2 * dy1;
|
|
1337
|
+
if (f === 0) return 0;
|
|
1338
|
+
}
|
|
1339
|
+
else if (dy1 === 0 && dy2 === 0) {
|
|
1340
|
+
if (dx2 <= 0 && dx1 >= 0) {
|
|
1341
|
+
return 0;
|
|
1342
|
+
}
|
|
1343
|
+
else if (dx1 <= 0 && dx2 >= 0) {
|
|
1344
|
+
return 0;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
dy1 = dy2;
|
|
1349
|
+
dx1 = dx2;
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
if (k % 2 === 0) return false;
|
|
1353
|
+
return true;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
/**
|
|
1357
|
+
* @param strValue
|
|
1358
|
+
*/
|
|
1359
|
+
_getPickDepth( strValue ) {
|
|
1360
|
+
if (strValue == "ALL") {
|
|
1361
|
+
return PickDepthEnum.All;
|
|
1362
|
+
}
|
|
1363
|
+
else {
|
|
1364
|
+
return PickDepthEnum.Closest;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
/**
|
|
1369
|
+
* Dispatch the appropriate tap, track or hover event.
|
|
1370
|
+
*/
|
|
1371
|
+
_dispatchPickEvents(pickProperties) {
|
|
1372
|
+
|
|
1373
|
+
var pickEvent = {detail: {selected: pickProperties.selected}};
|
|
1374
|
+
if (pickProperties.type === 'TRACK') {
|
|
1375
|
+
pickEvent.detail.left = pickProperties.left;
|
|
1376
|
+
pickEvent.detail.top = pickProperties.top;
|
|
1377
|
+
pickEvent.detail.right = pickProperties.right;
|
|
1378
|
+
pickEvent.detail.bottom = pickProperties.bottom;
|
|
1379
|
+
|
|
1380
|
+
/**
|
|
1381
|
+
* A track event occurred.
|
|
1382
|
+
* @event avs-track
|
|
1383
|
+
*/
|
|
1384
|
+
this.dispatchEvent(new CustomEvent('avs-track', pickEvent));
|
|
1385
|
+
}
|
|
1386
|
+
else {
|
|
1387
|
+
pickEvent.detail.x = pickProperties.x;
|
|
1388
|
+
pickEvent.detail.y = pickProperties.y;
|
|
1389
|
+
|
|
1390
|
+
if (pickProperties.type === 'HOVER') {
|
|
1391
|
+
/**
|
|
1392
|
+
* A hover event occurred.
|
|
1393
|
+
* @event avs-hover
|
|
1394
|
+
*/
|
|
1395
|
+
this.dispatchEvent(new CustomEvent('avs-hover', pickEvent));
|
|
1396
|
+
}
|
|
1397
|
+
else {
|
|
1398
|
+
/**
|
|
1399
|
+
* A tap event occurred.
|
|
1400
|
+
* @event avs-tap
|
|
1401
|
+
*/
|
|
1402
|
+
this.dispatchEvent(new CustomEvent('avs-tap', pickEvent));
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
_resetTimer() {
|
|
1408
|
+
clearTimeout(this.timer);
|
|
1409
|
+
this.timer = setTimeout(function() {
|
|
1410
|
+
/**
|
|
1411
|
+
* A pointer timeout event occurred.
|
|
1412
|
+
* @event avs-pointer-timeout
|
|
1413
|
+
*/
|
|
1414
|
+
this.dispatchEvent(new Event('avs-pointer-timeout'));
|
|
1415
|
+
}.bind(this), this.pointerTimeout * 1000);
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
/**
|
|
1419
|
+
*
|
|
1420
|
+
*/
|
|
1421
|
+
connectedCallback() {
|
|
1422
|
+
super.connectedCallback();
|
|
1423
|
+
|
|
1424
|
+
// Make sure all CSS and layout has been processed
|
|
1425
|
+
afterNextRender(this, function() {
|
|
1426
|
+
if (this.initialized !== true) {
|
|
1427
|
+
|
|
1428
|
+
this._updateSize();
|
|
1429
|
+
if (!this.manualUpdate) {
|
|
1430
|
+
this.updateViewer(true);
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
this.addEventListener('iron-resize', this._onResize);
|
|
1434
|
+
this._updatePixelRatio();
|
|
1435
|
+
|
|
1436
|
+
this.addEventListener('pointerdown', this._handlePointerDown);
|
|
1437
|
+
this.addEventListener('pointerup', this._handlePointerUp);
|
|
1438
|
+
this.addEventListener('pointermove', this._handlePointerMove);
|
|
1439
|
+
this.addEventListener('pointerout', this._handlePointerMove);
|
|
1440
|
+
|
|
1441
|
+
var scope = this;
|
|
1442
|
+
this.addEventListener('contextmenu', function(e) {
|
|
1443
|
+
if (scope.trackEnable) {
|
|
1444
|
+
e.preventDefault();
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
|
|
1448
|
+
this._resetTimer();
|
|
1449
|
+
|
|
1450
|
+
this.initialized = true;
|
|
1451
|
+
}
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
_updatePixelRatio(change) {
|
|
1456
|
+
const pr = window.devicePixelRatio;
|
|
1457
|
+
matchMedia( `(resolution: ${pr}dppx)` ).addEventListener('change', this._updatePixelRatio.bind(this, true), { once: true } );
|
|
1458
|
+
if (change) {
|
|
1459
|
+
this.updateViewer();
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
/**
|
|
1464
|
+
* Change in 'hidden' property.
|
|
1465
|
+
*/
|
|
1466
|
+
_hiddenChanged(newValue, oldValue) {
|
|
1467
|
+
if (newValue) {
|
|
1468
|
+
this.$.dataVizDiv.style.display = 'none';
|
|
1469
|
+
}
|
|
1470
|
+
else {
|
|
1471
|
+
this.$.dataVizDiv.style.display = '';
|
|
1472
|
+
if (this.threeViewer) {
|
|
1473
|
+
this.threeViewer.render();
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
/**
|
|
1479
|
+
* Change in 'transform-enable' property.
|
|
1480
|
+
*/
|
|
1481
|
+
_transformEnableChanged(newValue, oldValue) {
|
|
1482
|
+
if (this.threeViewer) {
|
|
1483
|
+
if (newValue) {
|
|
1484
|
+
if (this.transformInteractor === undefined) {
|
|
1485
|
+
this.transformInteractor = new TransformInteractor( this );
|
|
1486
|
+
}
|
|
1487
|
+
this.threeViewer.addInteractor( this.transformInteractor );
|
|
1488
|
+
|
|
1489
|
+
if (this.transformRotateDisable) {
|
|
1490
|
+
this.transformInteractor.enableRotate = false;
|
|
1491
|
+
}
|
|
1492
|
+
if (this.transformZoomDisable) {
|
|
1493
|
+
this.transformInteractor.enableZoom = false;
|
|
1494
|
+
}
|
|
1495
|
+
if (this.transformPanDisable) {
|
|
1496
|
+
this.transformInteractor.enablePan = false;
|
|
1497
|
+
}
|
|
1498
|
+
if (this.transformClientOnly) {
|
|
1499
|
+
this.transformInteractor.clientOnly = true;
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
else {
|
|
1503
|
+
this.threeViewer.removeInteractor( this.transformInteractor );
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
/**
|
|
1509
|
+
* Change in the 'transform-client-only' property.
|
|
1510
|
+
*/
|
|
1511
|
+
_transformClientOnlyChanged(newValue, oldValue) {
|
|
1512
|
+
if (this.transformInteractor) {
|
|
1513
|
+
this.transformInteractor.clientOnly = newValue;
|
|
1514
|
+
}
|
|
1515
|
+
if (this.zoomRectangleInteractor) {
|
|
1516
|
+
this.zoomRectangleInteractor.clientOnly = newValue;
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
/**
|
|
1521
|
+
* Change in 'transform-rotate-disable' property.
|
|
1522
|
+
*/
|
|
1523
|
+
_transformRotateDisableChanged(newValue, oldValue) {
|
|
1524
|
+
if (this.transformInteractor) {
|
|
1525
|
+
this.transformInteractor.enableRotate = !newValue;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
/**
|
|
1530
|
+
* Change in 'transform-zoom-disable' property.
|
|
1531
|
+
*/
|
|
1532
|
+
_transformZoomDisableChanged(newValue, oldValue) {
|
|
1533
|
+
if (this.transformInteractor) {
|
|
1534
|
+
this.transformInteractor.enableZoom = !newValue;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
/**
|
|
1539
|
+
* Change in 'transform-pan-disable' property.
|
|
1540
|
+
*/
|
|
1541
|
+
_transformPanDisableChanged(newValue, oldValue) {
|
|
1542
|
+
if (this.transformInteractor) {
|
|
1543
|
+
this.transformInteractor.enablePan = !newValue;
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
/**
|
|
1548
|
+
* Reset the transform interactor.
|
|
1549
|
+
*/
|
|
1550
|
+
resetTransform() {
|
|
1551
|
+
if (this.transformInteractor) {
|
|
1552
|
+
this.transformInteractor.reset();
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
/**
|
|
1557
|
+
* Perform a zoom in using the transform interactor.
|
|
1558
|
+
*/
|
|
1559
|
+
zoomIn() {
|
|
1560
|
+
if (this.transformInteractor) {
|
|
1561
|
+
this.transformInteractor.zoomIn();
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
/**
|
|
1566
|
+
* Perform a zoom out using the transform interactor.
|
|
1567
|
+
*/
|
|
1568
|
+
zoomOut() {
|
|
1569
|
+
if (this.transformInteractor) {
|
|
1570
|
+
this.transformInteractor.zoomOut();
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
/**
|
|
1575
|
+
* Perform a pan to center the specified coordinate of the transformed object in the center of the scene.
|
|
1576
|
+
*/
|
|
1577
|
+
panTo(x, y, z) {
|
|
1578
|
+
if (this.transformInteractor) {
|
|
1579
|
+
this.transformInteractor.panTo(x, y, z);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
getTransformComponents() {
|
|
1584
|
+
var pos = new Vector3();
|
|
1585
|
+
var quat = new Quaternion();
|
|
1586
|
+
var scale = new Vector3();
|
|
1587
|
+
var euler = new Euler();
|
|
1588
|
+
var mat;
|
|
1589
|
+
if (this.transformInteractor) {
|
|
1590
|
+
mat = this.transformInteractor.object.matrix;
|
|
1591
|
+
}
|
|
1592
|
+
mat.decompose(pos, quat, scale);
|
|
1593
|
+
euler.setFromQuaternion(quat);
|
|
1594
|
+
return {
|
|
1595
|
+
position: pos.toArray(),
|
|
1596
|
+
rotation: [euler.x * 180 / Math.PI, euler.y * 180 / Math.PI, euler.z * 180 / Math.PI, euler.order],
|
|
1597
|
+
scale: 100 * scale.x
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
getTransformMatrix() {
|
|
1602
|
+
if (this.transformInteractor) {
|
|
1603
|
+
return this.transformInteractor.object.matrix.elements.slice();
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
runAnimation() {
|
|
1608
|
+
|
|
1609
|
+
var style = window.getComputedStyle(this, null);
|
|
1610
|
+
|
|
1611
|
+
if (this.renderer === 'THREEJS') {
|
|
1612
|
+
var styleMap = {};
|
|
1613
|
+
this._applyCustomCssProperties(styleMap, style,
|
|
1614
|
+
{
|
|
1615
|
+
"scene": "--avs-scene-animations",
|
|
1616
|
+
"sceneTitle": "--avs-scene-title-animations",
|
|
1617
|
+
"chart": "--avs-chart-animations",
|
|
1618
|
+
"chartTitle": "--avs-chart-title-animations",
|
|
1619
|
+
"axis": "--avs-axis-animations",
|
|
1620
|
+
"legend": "--avs-legend-animations",
|
|
1621
|
+
"legendTitle": "--avs-legend-title-animations",
|
|
1622
|
+
"glyph": "--avs-glyph-animations",
|
|
1623
|
+
"transform": "--avs-transform-animation"
|
|
1624
|
+
} );
|
|
1625
|
+
this.animator.setStyleMap(styleMap);
|
|
1626
|
+
this.threeViewer.runAnimation();
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
/**
|
|
1631
|
+
* Change in 'animated-glyphs-visible' property.
|
|
1632
|
+
*/
|
|
1633
|
+
_animatedGlyphsVisibleChanged(newValue, oldValue) {
|
|
1634
|
+
if (this.renderer === 'THREEJS') {
|
|
1635
|
+
this.threeViewer.setVisibleAnimatedGlyphs(newValue);
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
/**
|
|
1640
|
+
* Change in 'animated-glyphs-enable' property.
|
|
1641
|
+
*/
|
|
1642
|
+
_animatedGlyphsEnableChanged(newValue, oldValue) {
|
|
1643
|
+
if (this.renderer === 'THREEJS') {
|
|
1644
|
+
this.threeViewer.setEnableAnimatedGlyphs(newValue);
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
/**
|
|
1649
|
+
* Change in 'transform-twist-angle', 'transform-tilt-angle' or 'transform-scale' properties.
|
|
1650
|
+
*/
|
|
1651
|
+
_transformValueChanged(newValue, oldValue) {
|
|
1652
|
+
var twist = this.transformTwistAngle !== undefined ? this.transformTwistAngle * Math.PI / 180 : 0;
|
|
1653
|
+
var tilt = this.transformTiltAngle !== undefined ? this.transformTiltAngle * Math.PI / 180 : 0;
|
|
1654
|
+
var scale = this.transformScale !== undefined ? this.transformScale / 100.0 : 1.0;
|
|
1655
|
+
|
|
1656
|
+
var sinTW = Math.sin(twist);
|
|
1657
|
+
var cosTW = Math.cos(twist);
|
|
1658
|
+
var sinTI = Math.sin(tilt);
|
|
1659
|
+
var cosTI = Math.cos(tilt);
|
|
1660
|
+
|
|
1661
|
+
var matrix = [ cosTW * scale, 0, cosTI * sinTW * scale, 0,
|
|
1662
|
+
0, cosTI * scale, -sinTI * scale, 0,
|
|
1663
|
+
-sinTW * scale, cosTW * sinTI * scale, cosTW * cosTI * scale, 0,
|
|
1664
|
+
0, 0, 0, 1 ];
|
|
1665
|
+
|
|
1666
|
+
this.transformMatrix = matrix;
|
|
1667
|
+
if (this.transformInteractor) {
|
|
1668
|
+
this.transformInteractor.object.matrix.fromArray( matrix );
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
/**
|
|
1673
|
+
* Change in 'zoom-rectangle-enable' property.
|
|
1674
|
+
*/
|
|
1675
|
+
_zoomRectangleEnableChanged(newValue, oldValue) {
|
|
1676
|
+
if (this.threeViewer) {
|
|
1677
|
+
if (newValue) {
|
|
1678
|
+
if (this.zoomRectangleInteractor === undefined) {
|
|
1679
|
+
this.zoomRectangleInteractor = new ZoomRectangleInteractor( this );
|
|
1680
|
+
}
|
|
1681
|
+
this.threeViewer.addInteractor( this.zoomRectangleInteractor );
|
|
1682
|
+
|
|
1683
|
+
if (this.transformClientOnly) {
|
|
1684
|
+
this.zoomRectangleInteractor.clientOnly = true;
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
else {
|
|
1688
|
+
this.threeViewer.removeInteractor( this.zoomRectangleInteractor );
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
/**
|
|
1694
|
+
* Change in 'pan-enable' property.
|
|
1695
|
+
*/
|
|
1696
|
+
_panEnableChanged(newValue, oldValue) {
|
|
1697
|
+
if (this.threeViewer) {
|
|
1698
|
+
if (newValue) {
|
|
1699
|
+
if (this.panInteractor === undefined) {
|
|
1700
|
+
this.panInteractor = new PanInteractor( this );
|
|
1701
|
+
}
|
|
1702
|
+
this.threeViewer.addInteractor( this.panInteractor );
|
|
1703
|
+
if (this.panZoomEnable) {
|
|
1704
|
+
this.panInteractor.addEventListener('change', this._handlePanChanged.bind(this));
|
|
1705
|
+
this.panInteractor.addEventListener('zoom', this._handlePanZoom.bind(this));
|
|
1706
|
+
this.panInteractor.addEventListener('zoomEnd', this._handlePanZoomEnd.bind(this));
|
|
1707
|
+
}
|
|
1708
|
+
this.panInteractor.setWidthZoomLevel(this.panWidthZoomLevel);
|
|
1709
|
+
this.panInteractor.setHeightZoomLevel(this.panHeightZoomLevel);
|
|
1710
|
+
this.panInteractor.setMaximumZoomLevel(this.panMaximumZoomLevel);
|
|
1711
|
+
this.panInteractor.saveState();
|
|
1712
|
+
}
|
|
1713
|
+
else {
|
|
1714
|
+
this.threeViewer.removeInteractor( this.panInteractor );
|
|
1715
|
+
if (this.panZoomEnable) {
|
|
1716
|
+
this.panInteractor.removeEventListener('change', this._handlePanChanged.bind(this));
|
|
1717
|
+
this.panInteractor.removeEventListener('zoom', this._handlePanZoom.bind(this));
|
|
1718
|
+
this.panInteractor.removeEventListener('zoomEnd', this._handlePanZoomEnd.bind(this));
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
/**
|
|
1725
|
+
* Change in 'pan-zoom-enable' property.
|
|
1726
|
+
*/
|
|
1727
|
+
_panZoomEnableChanged(newValue, oldValue) {
|
|
1728
|
+
if (this.threeViewer && this.panInteractor) {
|
|
1729
|
+
if (newValue) {
|
|
1730
|
+
this.panInteractor.addEventListener('change', this._handlePanChanged.bind(this));
|
|
1731
|
+
this.panInteractor.addEventListener('zoom', this._handlePanZoom.bind(this));
|
|
1732
|
+
this.panInteractor.addEventListener('zoomEnd', this._handlePanZoomEnd.bind(this));
|
|
1733
|
+
}
|
|
1734
|
+
else {
|
|
1735
|
+
this.panInteractor.removeEventListener('change', this._handlePanChanged.bind(this));
|
|
1736
|
+
this.panInteractor.removeEventListener('zoom', this._handlePanZoom.bind(this));
|
|
1737
|
+
this.panInteractor.removeEventListener('zoomEnd', this._handlePanZoomEnd.bind(this));
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
_handlePanChanged(e) {
|
|
1743
|
+
/**
|
|
1744
|
+
* A pan info event occurred.
|
|
1745
|
+
* @event avs-pan-info
|
|
1746
|
+
*/
|
|
1747
|
+
this.dispatchEvent(new CustomEvent('avs-pan-info', e));
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
_zoomOverlayTimeout() {
|
|
1751
|
+
this.$.zoomOverlay.style.opacity = 0;
|
|
1752
|
+
this.pointerDown = false;
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
_handlePanZoom(e) {
|
|
1756
|
+
clearTimeout(this.zoomOverlayTimeoutId);
|
|
1757
|
+
|
|
1758
|
+
var width = Math.round(e.detail.widthZoomLevel);
|
|
1759
|
+
var height = Math.round(e.detail.heightZoomLevel);
|
|
1760
|
+
if (width === height) {
|
|
1761
|
+
this.$.zoomOverlay.innerHTML = width + "%";
|
|
1762
|
+
}
|
|
1763
|
+
else {
|
|
1764
|
+
this.$.zoomOverlay.innerHTML = width + "%," + height + "%";
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
var coords = this._getAdjustedCoords(e.detail.clientX, e.detail.clientY);
|
|
1768
|
+
this.$.zoomOverlay.style.left = coords.x + "px";
|
|
1769
|
+
this.$.zoomOverlay.style.top = coords.y + "px";
|
|
1770
|
+
this.$.zoomOverlay.style.opacity = 1;
|
|
1771
|
+
|
|
1772
|
+
this.pointerDown = true;
|
|
1773
|
+
this._dispatchPickEvents( {type:"HOVER",x:0,y:0,selected:{}} );
|
|
1774
|
+
|
|
1775
|
+
this.zoomOverlayTimeoutId = setTimeout(this._zoomOverlayTimeout.bind(this), 1000);
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
_handlePanZoomEnd(e) {
|
|
1779
|
+
if (this.initialized) {
|
|
1780
|
+
this.panWidthZoomLevel = e.detail.widthZoomLevel;
|
|
1781
|
+
this.panHeightZoomLevel = e.detail.heightZoomLevel;
|
|
1782
|
+
this.updateViewer();
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
/**
|
|
1787
|
+
* Change in 'pan-width-zoom-level' property.
|
|
1788
|
+
*/
|
|
1789
|
+
_panWidthZoomLevelChanged(newValue, oldValue) {
|
|
1790
|
+
if (this.panInteractor) {
|
|
1791
|
+
this.panInteractor.setWidthZoomLevel(newValue);
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
/**
|
|
1796
|
+
* Change in 'pan-height-zoom-level' property.
|
|
1797
|
+
*/
|
|
1798
|
+
_panHeightZoomLevelChanged(newValue, oldValue) {
|
|
1799
|
+
if (this.panInteractor) {
|
|
1800
|
+
this.panInteractor.setHeightZoomLevel(newValue);
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
/**
|
|
1805
|
+
* Change in 'pan-maximum-zoom-level' property.
|
|
1806
|
+
*/
|
|
1807
|
+
_panMaximumZoomLevelChanged(newValue, oldValue) {
|
|
1808
|
+
if (this.panInteractor) {
|
|
1809
|
+
this.panInteractor.setMaximumZoomLevel(newValue);
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
/**
|
|
1814
|
+
* Reset the pan interactor.
|
|
1815
|
+
*/
|
|
1816
|
+
resetPan() {
|
|
1817
|
+
if (this.panInteractor) {
|
|
1818
|
+
this.panInteractor.reset();
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
/**
|
|
1823
|
+
* Change in 'renderer' property.
|
|
1824
|
+
*/
|
|
1825
|
+
_rendererChanged(newValue, oldValue) {
|
|
1826
|
+
if (oldValue === 'IMAGE' || oldValue === 'IMAGEURL') {
|
|
1827
|
+
this.sceneImage.src = 'data:,';
|
|
1828
|
+
this.$.dataVizDiv.removeChild(this.sceneImage);
|
|
1829
|
+
this.$.dataVizDiv.removeChild(this.sceneImageMap);
|
|
1830
|
+
}
|
|
1831
|
+
else if (oldValue === 'SVG') {
|
|
1832
|
+
var el = this.svgDiv;
|
|
1833
|
+
while (el.firstChild) el.removeChild(el.firstChild);
|
|
1834
|
+
this.$.dataVizDiv.removeChild(this.svgDiv);
|
|
1835
|
+
}
|
|
1836
|
+
else if (oldValue === 'THREEJS') {
|
|
1837
|
+
this.threeViewer.clearGeometry();
|
|
1838
|
+
this.threeViewer.render();
|
|
1839
|
+
this.$.dataVizDiv.removeChild(this.threeViewer.domElement);
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
if (newValue === 'IMAGE' || newValue === 'IMAGEURL') {
|
|
1843
|
+
if (this.sceneImage === undefined) {
|
|
1844
|
+
this.sceneImage = document.createElement("img");
|
|
1845
|
+
this.sceneImage.setAttribute("id", "sceneImage");
|
|
1846
|
+
this.sceneImage.setAttribute("usemap", "#sceneImageMap");
|
|
1847
|
+
|
|
1848
|
+
this.sceneImageMap = document.createElement("map");
|
|
1849
|
+
this.sceneImageMap.setAttribute("id", "sceneImageMap");
|
|
1850
|
+
this.sceneImageMap.setAttribute("name", "sceneImageMap");
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
this.$.dataVizDiv.appendChild(this.sceneImage);
|
|
1854
|
+
this.$.dataVizDiv.appendChild(this.sceneImageMap);
|
|
1855
|
+
}
|
|
1856
|
+
else if (newValue === 'SVG') {
|
|
1857
|
+
if (this.svgDiv === undefined) {
|
|
1858
|
+
this.svgDiv = document.createElement("div");
|
|
1859
|
+
this.svgDiv.setAttribute("id", "svgDiv");
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
this.$.dataVizDiv.appendChild(this.svgDiv);
|
|
1863
|
+
}
|
|
1864
|
+
else if (newValue === 'THREEJS') {
|
|
1865
|
+
if (this.threeViewer === undefined) {
|
|
1866
|
+
// Create ThreeJS viewer
|
|
1867
|
+
this.threeViewer = new Viewer();
|
|
1868
|
+
|
|
1869
|
+
// Check if the user has requested a specific renderer
|
|
1870
|
+
var rendererId = 'avsDefaultWebGLRenderer';
|
|
1871
|
+
// if (this.rendererProperties.webGLRendererId !== undefined) {
|
|
1872
|
+
// rendererId = this.rendererProperties.webGLRendererId;
|
|
1873
|
+
// }
|
|
1874
|
+
|
|
1875
|
+
// Search for renderer, if not found create one and save to the DOM
|
|
1876
|
+
var renderer = document.getElementById(rendererId);
|
|
1877
|
+
if (renderer === undefined || renderer === null) {
|
|
1878
|
+
renderer = new AvsRenderer();
|
|
1879
|
+
renderer.setAttribute('id', rendererId);
|
|
1880
|
+
document.body.appendChild(renderer);
|
|
1881
|
+
// console.log("create new webGL renderer = " + rendererId);
|
|
1882
|
+
}
|
|
1883
|
+
else {
|
|
1884
|
+
// console.log("reference existing webGL renderer = " + rendererId);
|
|
1885
|
+
}
|
|
1886
|
+
this.threeViewer.setWebGLRenderer(renderer.webGLRenderer);
|
|
1887
|
+
|
|
1888
|
+
this.animator = new Animator();
|
|
1889
|
+
this.threeViewer.setAnimator(this.animator);
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
this.$.dataVizDiv.appendChild(this.threeViewer.domElement);
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
if (this.initialized && !this.manualUpdate) {
|
|
1896
|
+
this.updateViewer();
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
|
|
1900
|
+
/**
|
|
1901
|
+
* Change in 'track-enable' property.
|
|
1902
|
+
*/
|
|
1903
|
+
_trackEnableChanged(newValue, oldValue) {
|
|
1904
|
+
if (newValue) {
|
|
1905
|
+
if (this.rectCanvas === undefined) {
|
|
1906
|
+
this.rectCanvas = document.createElement("canvas");
|
|
1907
|
+
this.rectCanvas.setAttribute("id", "rectCanvas");
|
|
1908
|
+
this.rectCtx = this.rectCanvas.getContext('2d');
|
|
1909
|
+
}
|
|
1910
|
+
this.$.container.appendChild(this.rectCanvas);
|
|
1911
|
+
}
|
|
1912
|
+
else {
|
|
1913
|
+
this.$.container.removeChild(this.rectCanvas);
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
/**
|
|
1918
|
+
* Change in 'display-canvas' property.
|
|
1919
|
+
*/
|
|
1920
|
+
_displayCanvasChanged(newValue, oldValue) {
|
|
1921
|
+
if (this.threeViewer) {
|
|
1922
|
+
this.threeViewer.displayCanvas = newValue;
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
setTooltipHTML(html) {
|
|
1927
|
+
this.$.tooltip.innerHTML = html;
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
showTooltip(clientX, clientY) {
|
|
1931
|
+
var pos = this._calcTooltipPosition(clientX, clientY);
|
|
1932
|
+
this.$.tooltip.style.left = pos.x + "px";
|
|
1933
|
+
this.$.tooltip.style.top = pos.y + "px";
|
|
1934
|
+
this.$.tooltip.style.opacity = 1;
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1937
|
+
hideTooltip() {
|
|
1938
|
+
this.$.tooltip.style.opacity = 0;
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
_calcTooltipPosition(clientX, clientY) {
|
|
1942
|
+
|
|
1943
|
+
// Calculate the tooltip location based on 4 quadrants of the visible portion
|
|
1944
|
+
// of the visualization window
|
|
1945
|
+
|
|
1946
|
+
var offset = this._getOffset();
|
|
1947
|
+
var deltaTop = -Math.min(0, offset.top - window.pageYOffset);
|
|
1948
|
+
var deltaLeft = -Math.min(0, offset.left - window.pageXOffset);
|
|
1949
|
+
var deltaBottom = -Math.min(0, window.innerHeight - (this.$.dataVizDiv.offsetHeight + offset.top - window.pageYOffset));
|
|
1950
|
+
var deltaRight = -Math.min(0, window.innerWidth - (this.$.dataVizDiv.offsetWidth + offset.left - window.pageXOffset));
|
|
1951
|
+
var vizHeight = this.$.dataVizDiv.offsetHeight - deltaTop - deltaBottom;
|
|
1952
|
+
var vizWidth = this.$.dataVizDiv.offsetWidth - deltaLeft - deltaRight;
|
|
1953
|
+
var vizHalfX = vizWidth / 2 + deltaLeft;
|
|
1954
|
+
var vizHalfY = vizHeight / 2 + deltaTop;
|
|
1955
|
+
|
|
1956
|
+
var toolPosition = { x: 0, y: 0 };
|
|
1957
|
+
if (clientX < vizHalfX) {
|
|
1958
|
+
var offset = (clientY < vizHalfY) ? 15 : 5;
|
|
1959
|
+
toolPosition.x = clientX + offset + this.$.dataVizDiv.offsetLeft;
|
|
1960
|
+
}
|
|
1961
|
+
else {
|
|
1962
|
+
toolPosition.x = clientX - 10 + this.$.dataVizDiv.offsetLeft - this.$.tooltip.offsetWidth;
|
|
1963
|
+
}
|
|
1964
|
+
if (clientY < vizHalfY) {
|
|
1965
|
+
toolPosition.y = clientY + 5 + this.$.dataVizDiv.offsetTop;
|
|
1966
|
+
}
|
|
1967
|
+
else {
|
|
1968
|
+
toolPosition.y = clientY - 10 + this.$.dataVizDiv.offsetTop - this.$.tooltip.offsetHeight;
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
return toolPosition;
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
_getOffset() {
|
|
1975
|
+
var rect = this.$.dataVizDiv.getBoundingClientRect(),
|
|
1976
|
+
scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
|
|
1977
|
+
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
1978
|
+
return { top: rect.top + scrollTop, left: rect.left + scrollLeft }
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
window.customElements.define('avs-go-dataviz', AvsGoDataViz);
|