...
|
...
|
@@ -19,7 +19,7 @@ import tinycolor from 'tinycolor2'; |
19
|
19
|
|
20
|
20
|
import { AfterViewInit, ChangeDetectorRef, Component, Input, OnInit, SecurityContext, ViewChild } from '@angular/core';
|
21
|
21
|
import { MapWidgetController, TbMapWidgetV2 } from '../lib/maps/map-widget2';
|
22
|
|
-import { FormattedData, MapProviders } from '../lib/maps/map-models';
|
|
22
|
+import { FormattedData, MapProviders, TripAnimationSettings } from '../lib/maps/map-models';
|
23
|
23
|
import { addCondition, addGroupInfo, addToSchema, initSchema } from '@app/core/schema-utils';
|
24
|
24
|
import { mapPolygonSchema, pathSchema, pointSchema, tripAnimationSchema } from '../lib/maps/schemes';
|
25
|
25
|
import { DomSanitizer } from '@angular/platform-browser';
|
...
|
...
|
@@ -56,17 +56,14 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { |
56
|
56
|
historicalData: FormattedData[][];
|
57
|
57
|
normalizationStep: number;
|
58
|
58
|
interpolatedTimeData = [];
|
59
|
|
- intervals = [];
|
60
|
59
|
widgetConfig: WidgetConfig;
|
61
|
|
- settings;
|
|
60
|
+ settings: TripAnimationSettings;
|
62
|
61
|
mainTooltip = '';
|
63
|
62
|
visibleTooltip = false;
|
64
|
63
|
activeTrip: FormattedData;
|
65
|
64
|
label;
|
66
|
65
|
minTime: number;
|
67
|
|
- minTimeFormat: string;
|
68
|
66
|
maxTime: number;
|
69
|
|
- maxTimeFormat: string;
|
70
|
67
|
anchors: number[] = [];
|
71
|
68
|
useAnchors: boolean;
|
72
|
69
|
currentTime: number;
|
...
|
...
|
@@ -98,15 +95,15 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { |
98
|
95
|
this.settings = { ...settings, ...this.ctx.settings };
|
99
|
96
|
this.useAnchors = this.settings.showPoints && this.settings.usePointAsAnchor;
|
100
|
97
|
this.settings.pointAsAnchorFunction = parseFunction(this.settings.pointAsAnchorFunction, ['data', 'dsData', 'dsIndex']);
|
101
|
|
- this.settings.fitMapBounds = true;
|
|
98
|
+ this.settings.tooltipFunction = parseFunction(this.settings.tooltipFunction, ['data', 'dsData', 'dsIndex']);
|
|
99
|
+ this.settings.labelFunction = parseFunction(this.settings.labelFunction, ['data', 'dsData', 'dsIndex']);
|
102
|
100
|
this.normalizationStep = this.settings.normalizationStep;
|
103
|
101
|
const subscription = this.ctx.subscriptions[Object.keys(this.ctx.subscriptions)[0]];
|
104
|
102
|
if (subscription) subscription.callbacks.onDataUpdated = () => {
|
105
|
103
|
this.historicalData = parseArray(this.ctx.data).filter(arr => arr.length);
|
106
|
104
|
if (this.historicalData.length) {
|
107
|
|
- this.activeTrip = this.historicalData[0][0];
|
108
|
105
|
this.calculateIntervals();
|
109
|
|
- this.timeUpdated(this.minTime);
|
|
106
|
+ this.timeUpdated(this.currentTime && this.currentTime > this.minTime ? this.currentTime : this.minTime);
|
110
|
107
|
}
|
111
|
108
|
this.mapWidget.map.map?.invalidateSize();
|
112
|
109
|
this.cd.detectChanges();
|
...
|
...
|
@@ -122,12 +119,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { |
122
|
119
|
this.currentTime = time;
|
123
|
120
|
const currentPosition = this.interpolatedTimeData
|
124
|
121
|
.map(dataSource => dataSource[time])
|
125
|
|
- .filter(ds => ds)
|
126
|
|
- .map(ds => {
|
127
|
|
- ds.minTime = this.minTimeFormat;
|
128
|
|
- ds.maxTime = this.maxTimeFormat;
|
129
|
|
- return ds;
|
130
|
|
- });
|
|
122
|
+ .filter(ds => ds);
|
131
|
123
|
if (isUndefined(currentPosition[0])) {
|
132
|
124
|
const timePoints = Object.keys(this.interpolatedTimeData[0]).map(item => parseInt(item, 10));
|
133
|
125
|
for (let i = 1; i < timePoints.length; i++) {
|
...
|
...
|
@@ -145,7 +137,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { |
145
|
137
|
}
|
146
|
138
|
}
|
147
|
139
|
this.calcLabel();
|
148
|
|
- this.calcTooltip();
|
|
140
|
+ this.calcTooltip(currentPosition.find(position => position.entityName === this.activeTrip.entityName));
|
149
|
141
|
if (this.mapWidget) {
|
150
|
142
|
this.mapWidget.map.updatePolylines(this.interpolatedTimeData.map(ds => _.values(ds)), this.activeTrip);
|
151
|
143
|
if (this.settings.showPolygon) {
|
...
|
...
|
@@ -167,11 +159,14 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { |
167
|
159
|
calculateIntervals() {
|
168
|
160
|
this.historicalData.forEach((dataSource, index) => {
|
169
|
161
|
this.minTime = dataSource[0]?.time || Infinity;
|
170
|
|
- this.minTimeFormat = this.minTime !== Infinity ? moment(this.minTime).format('YYYY-MM-DD HH:mm:ss') : '';
|
|
162
|
+ const minTimeFormat = this.minTime !== Infinity ? moment(this.minTime).format('YYYY-MM-DD HH:mm:ss') : '';
|
171
|
163
|
this.maxTime = dataSource[dataSource.length - 1]?.time || -Infinity;
|
172
|
|
- this.maxTimeFormat = this.maxTime !== -Infinity ? moment(this.maxTime).format('YYYY-MM-DD HH:mm:ss') : '';
|
173
|
|
- this.interpolatedTimeData[index] = this.interpolateArray(dataSource);
|
|
164
|
+ const maxTimeFormat = this.maxTime !== -Infinity ? moment(this.maxTime).format('YYYY-MM-DD HH:mm:ss') : '';
|
|
165
|
+ this.interpolatedTimeData[index] = this.interpolateArray(dataSource, minTimeFormat, maxTimeFormat);
|
174
|
166
|
});
|
|
167
|
+ if(!this.activeTrip){
|
|
168
|
+ this.activeTrip = this.interpolatedTimeData.map(dataSource => dataSource[this.minTime]).filter(ds => ds)[0];
|
|
169
|
+ }
|
175
|
170
|
if (this.useAnchors) {
|
176
|
171
|
const anchorDate = Object.entries(_.union(this.interpolatedTimeData)[0]);
|
177
|
172
|
this.anchors = anchorDate
|
...
|
...
|
@@ -180,39 +175,26 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { |
180
|
175
|
}
|
181
|
176
|
}
|
182
|
177
|
|
183
|
|
- calcTooltip = (point?: FormattedData, setTooltip = true) => {
|
184
|
|
- if (!point) {
|
185
|
|
- point = this.activeTrip;
|
186
|
|
- }
|
187
|
|
- const data = {
|
188
|
|
- ...this.activeTrip,
|
189
|
|
- maxTime: this.maxTimeFormat,
|
190
|
|
- minTime: this.minTimeFormat
|
191
|
|
- }
|
|
178
|
+ calcTooltip = (point?: FormattedData) => {
|
|
179
|
+ const data = point ? point : this.activeTrip;
|
192
|
180
|
const tooltipPattern: string = this.settings.useTooltipFunction ?
|
193
|
|
- safeExecute(this.settings.tooolTipFunction, [data, this.historicalData, point.dsIndex]) : this.settings.tooltipPattern;
|
|
181
|
+ safeExecute(this.settings.tooltipFunction, [data, this.historicalData, point.dsIndex]) : this.settings.tooltipPattern;
|
194
|
182
|
const tooltipText = parseWithTranslation.parseTemplate(tooltipPattern, data, true);
|
195
|
|
- if (setTooltip) {
|
196
|
|
- this.mainTooltip = this.sanitizer.sanitize(
|
197
|
|
- SecurityContext.HTML, tooltipText);
|
198
|
|
- this.cd.detectChanges();
|
199
|
|
- }
|
|
183
|
+ this.mainTooltip = this.sanitizer.sanitize(
|
|
184
|
+ SecurityContext.HTML, tooltipText);
|
|
185
|
+ this.cd.detectChanges();
|
200
|
186
|
this.activeTrip = point;
|
201
|
187
|
return tooltipText;
|
202
|
188
|
}
|
203
|
189
|
|
204
|
190
|
calcLabel() {
|
205
|
|
- const data = {
|
206
|
|
- ...this.activeTrip,
|
207
|
|
- maxTime: this.maxTimeFormat,
|
208
|
|
- minTime: this.minTimeFormat
|
209
|
|
- }
|
|
191
|
+ const data = this.activeTrip;
|
210
|
192
|
const labelText: string = this.settings.useLabelFunction ?
|
211
|
193
|
safeExecute(this.settings.labelFunction, [data, this.historicalData, data.dsIndex]) : this.settings.label;
|
212
|
194
|
this.label = (parseWithTranslation.parseTemplate(labelText, data, true));
|
213
|
195
|
}
|
214
|
196
|
|
215
|
|
- interpolateArray(originData: FormattedData[]) {
|
|
197
|
+ interpolateArray(originData: FormattedData[], minTimeFormat?: string, maxTimeFormat?: string) {
|
216
|
198
|
const result = {};
|
217
|
199
|
const latKeyName = this.settings.latKeyName;
|
218
|
200
|
const lngKeyName = this.settings.lngKeyName;
|
...
|
...
|
@@ -221,6 +203,8 @@ export class TripAnimationComponent implements OnInit, AfterViewInit { |
221
|
203
|
const normalizeTime = this.minTime + Math.ceil((currentTime - this.minTime) / this.normalizationStep) * this.normalizationStep;
|
222
|
204
|
result[normalizeTime] = {
|
223
|
205
|
...data,
|
|
206
|
+ minTime: minTimeFormat,
|
|
207
|
+ maxTime: maxTimeFormat,
|
224
|
208
|
rotationAngle: this.settings.rotationAngle
|
225
|
209
|
};
|
226
|
210
|
}
|
...
|
...
|
|