|
@@ -47,6 +47,9 @@ import moment from 'moment'; |
|
@@ -47,6 +47,9 @@ import moment from 'moment'; |
47
|
import { isUndefined } from '@core/utils';
|
47
|
import { isUndefined } from '@core/utils';
|
48
|
import { ResizeObserver } from '@juggle/resize-observer';
|
48
|
import { ResizeObserver } from '@juggle/resize-observer';
|
49
|
|
49
|
|
|
|
50
|
+interface dataMap {
|
|
|
51
|
+ [key: string] : FormattedData
|
|
|
52
|
+}
|
50
|
|
53
|
|
51
|
@Component({
|
54
|
@Component({
|
52
|
// tslint:disable-next-line:component-selector
|
55
|
// tslint:disable-next-line:component-selector
|
|
@@ -70,7 +73,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
|
@@ -70,7 +73,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
70
|
interpolatedTimeData = [];
|
73
|
interpolatedTimeData = [];
|
71
|
widgetConfig: WidgetConfig;
|
74
|
widgetConfig: WidgetConfig;
|
72
|
settings: TripAnimationSettings;
|
75
|
settings: TripAnimationSettings;
|
73
|
- mainTooltip = '';
|
76
|
+ mainTooltips = [];
|
74
|
visibleTooltip = false;
|
77
|
visibleTooltip = false;
|
75
|
activeTrip: FormattedData;
|
78
|
activeTrip: FormattedData;
|
76
|
label: string;
|
79
|
label: string;
|
|
@@ -115,7 +118,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
|
@@ -115,7 +118,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
115
|
this.historicalData = parseArray(this.ctx.data).filter(arr => arr.length);
|
118
|
this.historicalData = parseArray(this.ctx.data).filter(arr => arr.length);
|
116
|
if (this.historicalData.length) {
|
119
|
if (this.historicalData.length) {
|
117
|
this.calculateIntervals();
|
120
|
this.calculateIntervals();
|
118
|
- this.timeUpdated(this.currentTime && this.currentTime > this.minTime ? this.currentTime : this.minTime);
|
121
|
+ this.timeUpdated(this.minTime);
|
119
|
}
|
122
|
}
|
120
|
this.mapWidget.map.map?.invalidateSize();
|
123
|
this.mapWidget.map.map?.invalidateSize();
|
121
|
this.cd.detectChanges();
|
124
|
this.cd.detectChanges();
|
|
@@ -140,32 +143,39 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
|
@@ -140,32 +143,39 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
140
|
this.currentTime = time;
|
143
|
this.currentTime = time;
|
141
|
const currentPosition = this.interpolatedTimeData
|
144
|
const currentPosition = this.interpolatedTimeData
|
142
|
.map(dataSource => dataSource[time])
|
145
|
.map(dataSource => dataSource[time])
|
143
|
- .filter(ds => ds);
|
|
|
144
|
- if (isUndefined(currentPosition[0])) {
|
|
|
145
|
- const timePoints = Object.keys(this.interpolatedTimeData[0]).map(item => parseInt(item, 10));
|
|
|
146
|
- for (let i = 1; i < timePoints.length; i++) {
|
|
|
147
|
- if (timePoints[i - 1] < time && timePoints[i] > time) {
|
|
|
148
|
- const beforePosition = this.interpolatedTimeData[0][timePoints[i - 1]];
|
|
|
149
|
- const afterPosition = this.interpolatedTimeData[0][timePoints[i]];
|
|
|
150
|
- const ratio = getRatio(timePoints[i - 1], timePoints[i], time);
|
|
|
151
|
- currentPosition[0] = {
|
|
|
152
|
- ...beforePosition,
|
|
|
153
|
- time,
|
|
|
154
|
- ...interpolateOnLineSegment(beforePosition, afterPosition, this.settings.latKeyName, this.settings.lngKeyName, ratio)
|
146
|
+ for(let j = 0; j < this.interpolatedTimeData.length; j++) {
|
|
|
147
|
+ if (isUndefined(currentPosition[j])) {
|
|
|
148
|
+ const timePoints = Object.keys(this.interpolatedTimeData[j]).map(item => parseInt(item, 10));
|
|
|
149
|
+ for (let i = 1; i < timePoints.length; i++) {
|
|
|
150
|
+ if (timePoints[i - 1] < time && timePoints[i] > time) {
|
|
|
151
|
+ const beforePosition = this.interpolatedTimeData[j][timePoints[i - 1]];
|
|
|
152
|
+ const afterPosition = this.interpolatedTimeData[j][timePoints[i]];
|
|
|
153
|
+ const ratio = getRatio(timePoints[i - 1], timePoints[i], time);
|
|
|
154
|
+ currentPosition[j] = {
|
|
|
155
|
+ ...beforePosition,
|
|
|
156
|
+ time,
|
|
|
157
|
+ ...interpolateOnLineSegment(beforePosition, afterPosition, this.settings.latKeyName, this.settings.lngKeyName, ratio)
|
|
|
158
|
+ }
|
|
|
159
|
+ break;
|
155
|
}
|
160
|
}
|
156
|
- break;
|
|
|
157
|
}
|
161
|
}
|
158
|
}
|
162
|
}
|
159
|
}
|
163
|
}
|
|
|
164
|
+ for(let j = 0; j < this.interpolatedTimeData.length; j++) {
|
|
|
165
|
+ if (isUndefined(currentPosition[j])) {
|
|
|
166
|
+ currentPosition[j] = this.calculateLastPoints(this.interpolatedTimeData[j], time);
|
|
|
167
|
+ }
|
|
|
168
|
+ }
|
160
|
this.calcLabel();
|
169
|
this.calcLabel();
|
161
|
- this.calcTooltip(currentPosition.find(position => position.entityName === this.activeTrip.entityName));
|
170
|
+ this.calcMainTooltip(currentPosition);
|
162
|
if (this.mapWidget && this.mapWidget.map && this.mapWidget.map.map) {
|
171
|
if (this.mapWidget && this.mapWidget.map && this.mapWidget.map.map) {
|
163
|
- this.mapWidget.map.updatePolylines(this.interpolatedTimeData.map(ds => _.values(ds)), true, this.activeTrip);
|
172
|
+ const formattedInterpolatedTimeData = this.interpolatedTimeData.map(ds => _.values(ds));
|
|
|
173
|
+ this.mapWidget.map.updatePolylines(formattedInterpolatedTimeData, true);
|
164
|
if (this.settings.showPolygon) {
|
174
|
if (this.settings.showPolygon) {
|
165
|
this.mapWidget.map.updatePolygons(this.interpolatedTimeData);
|
175
|
this.mapWidget.map.updatePolygons(this.interpolatedTimeData);
|
166
|
}
|
176
|
}
|
167
|
if (this.settings.showPoints) {
|
177
|
if (this.settings.showPoints) {
|
168
|
- this.mapWidget.map.updatePoints(_.values(_.union(this.interpolatedTimeData)[0]), this.calcTooltip);
|
178
|
+ this.mapWidget.map.updatePoints(formattedInterpolatedTimeData.map(ds => _.union(ds)), this.calcTooltip);
|
169
|
}
|
179
|
}
|
170
|
this.mapWidget.map.updateMarkers(currentPosition, true, (trip) => {
|
180
|
this.mapWidget.map.updateMarkers(currentPosition, true, (trip) => {
|
171
|
this.activeTrip = trip;
|
181
|
this.activeTrip = trip;
|
|
@@ -177,6 +187,23 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
|
@@ -177,6 +187,23 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
177
|
setActiveTrip() {
|
187
|
setActiveTrip() {
|
178
|
}
|
188
|
}
|
179
|
|
189
|
|
|
|
190
|
+ private calculateLastPoints(dataSource: dataMap, time: number): FormattedData {
|
|
|
191
|
+ const timeArr = Object.keys(dataSource);
|
|
|
192
|
+ let index = timeArr.findIndex((dtime, index) => {
|
|
|
193
|
+ return Number(dtime) >= time;
|
|
|
194
|
+ });
|
|
|
195
|
+
|
|
|
196
|
+ if(index !== -1) {
|
|
|
197
|
+ if(Number(timeArr[index]) !== time && index !== 0) {
|
|
|
198
|
+ index--;
|
|
|
199
|
+ }
|
|
|
200
|
+ } else {
|
|
|
201
|
+ index = timeArr.length - 1;
|
|
|
202
|
+ }
|
|
|
203
|
+
|
|
|
204
|
+ return dataSource[timeArr[index]];
|
|
|
205
|
+ }
|
|
|
206
|
+
|
180
|
calculateIntervals() {
|
207
|
calculateIntervals() {
|
181
|
this.historicalData.forEach((dataSource, index) => {
|
208
|
this.historicalData.forEach((dataSource, index) => {
|
182
|
this.minTime = dataSource[0]?.time || Infinity;
|
209
|
this.minTime = dataSource[0]?.time || Infinity;
|
|
@@ -194,16 +221,19 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
|
@@ -194,16 +221,19 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
194
|
}
|
221
|
}
|
195
|
}
|
222
|
}
|
196
|
|
223
|
|
197
|
- calcTooltip = (point?: FormattedData): string => {
|
224
|
+ calcTooltip = (point: FormattedData): string => {
|
198
|
const data = point ? point : this.activeTrip;
|
225
|
const data = point ? point : this.activeTrip;
|
199
|
const tooltipPattern: string = this.settings.useTooltipFunction ?
|
226
|
const tooltipPattern: string = this.settings.useTooltipFunction ?
|
200
|
safeExecute(this.settings.tooltipFunction, [data, this.historicalData, point.dsIndex]) : this.settings.tooltipPattern;
|
227
|
safeExecute(this.settings.tooltipFunction, [data, this.historicalData, point.dsIndex]) : this.settings.tooltipPattern;
|
201
|
- const tooltipText = parseWithTranslation.parseTemplate(tooltipPattern, data, true);
|
|
|
202
|
- this.mainTooltip = this.sanitizer.sanitize(
|
|
|
203
|
- SecurityContext.HTML, tooltipText);
|
|
|
204
|
- this.cd.detectChanges();
|
|
|
205
|
- this.activeTrip = point;
|
|
|
206
|
- return tooltipText;
|
228
|
+ return parseWithTranslation.parseTemplate(tooltipPattern, data, true);
|
|
|
229
|
+ }
|
|
|
230
|
+
|
|
|
231
|
+ private calcMainTooltip(points: FormattedData[]): void {
|
|
|
232
|
+ const tooltips = [];
|
|
|
233
|
+ for (let point of points) {
|
|
|
234
|
+ tooltips.push(this.sanitizer.sanitize(SecurityContext.HTML, this.calcTooltip(point)));
|
|
|
235
|
+ }
|
|
|
236
|
+ this.mainTooltips = tooltips;
|
207
|
}
|
237
|
}
|
208
|
|
238
|
|
209
|
calcLabel() {
|
239
|
calcLabel() {
|