bug-fix: trip animation for multiple devices

This commit is contained in:
Dmitriymush 2020-11-11 13:24:10 +02:00
parent c3623be872
commit 643563ec6a
2 changed files with 99 additions and 50 deletions

View File

@ -599,26 +599,32 @@ export default abstract class LeafletMap {
return polygon; return polygon;
} }
updatePoints(pointsData: FormattedData[], getTooltip: (point: FormattedData, setTooltip?: boolean) => string) { updatePoints(pointsData: FormattedData[][], getTooltip: (point: FormattedData[], setTooltip?: boolean) => string) {
for(let i = 0; i < pointsData.length; i++) {
let pointsList = pointsData[i];
if(i === 0) {
if (this.points) { if (this.points) {
this.map.removeLayer(this.points); this.map.removeLayer(this.points);
} }
this.points = new FeatureGroup(); this.points = new FeatureGroup();
pointsData.filter(pdata => !!this.convertPosition(pdata)).forEach(data => { }
pointsList.filter(pdata => !!this.convertPosition(pdata)).forEach(data => {
const point = L.circleMarker(this.convertPosition(data), { const point = L.circleMarker(this.convertPosition(data), {
color: this.options.pointColor, color: this.options.pointColor,
radius: this.options.pointSize radius: this.options.pointSize
}); });
if (!this.options.pointTooltipOnRightPanel) { if (!this.options.pointTooltipOnRightPanel) {
point.on('click', () => getTooltip(data)); point.on('click', () => getTooltip([data]));
} } else {
else { createTooltip(point, this.options, data.$datasource, getTooltip([data], false));
createTooltip(point, this.options, data.$datasource, getTooltip(data, false));
} }
this.points.addLayer(point); this.points.addLayer(point);
}); });
if(i === 0) {
this.map.addLayer(this.points); this.map.addLayer(this.points);
} }
}
}
// Polyline // Polyline

View File

@ -47,6 +47,9 @@ import moment from 'moment';
import { isUndefined } from '@core/utils'; import { isUndefined } from '@core/utils';
import { ResizeObserver } from '@juggle/resize-observer'; import { ResizeObserver } from '@juggle/resize-observer';
interface dataMap {
[key: string] : FormattedData
}
@Component({ @Component({
// tslint:disable-next-line:component-selector // tslint:disable-next-line:component-selector
@ -70,7 +73,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
interpolatedTimeData = []; interpolatedTimeData = [];
widgetConfig: WidgetConfig; widgetConfig: WidgetConfig;
settings: TripAnimationSettings; settings: TripAnimationSettings;
mainTooltip = ''; mainTooltips = [];
visibleTooltip = false; visibleTooltip = false;
activeTrip: FormattedData; activeTrip: FormattedData;
label: string; label: string;
@ -115,7 +118,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
this.historicalData = parseArray(this.ctx.data).filter(arr => arr.length); this.historicalData = parseArray(this.ctx.data).filter(arr => arr.length);
if (this.historicalData.length) { if (this.historicalData.length) {
this.calculateIntervals(); this.calculateIntervals();
this.timeUpdated(this.currentTime && this.currentTime > this.minTime ? this.currentTime : this.minTime); this.timeUpdated(this.minTime);
} }
this.mapWidget.map.map?.invalidateSize(); this.mapWidget.map.map?.invalidateSize();
this.cd.detectChanges(); this.cd.detectChanges();
@ -138,17 +141,17 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
timeUpdated(time: number) { timeUpdated(time: number) {
this.currentTime = time; this.currentTime = time;
const currentPosition = this.interpolatedTimeData let currentPosition = this.interpolatedTimeData
.map(dataSource => dataSource[time]) .map(dataSource => dataSource[time])
.filter(ds => ds); for(let j = 0; j < this.interpolatedTimeData.length; j++) {
if (isUndefined(currentPosition[0])) { if (isUndefined(currentPosition[j])) {
const timePoints = Object.keys(this.interpolatedTimeData[0]).map(item => parseInt(item, 10)); const timePoints = Object.keys(this.interpolatedTimeData[j]).map(item => parseInt(item, 10));
for (let i = 1; i < timePoints.length; i++) { for (let i = 1; i < timePoints.length; i++) {
if (timePoints[i - 1] < time && timePoints[i] > time) { if (timePoints[i - 1] < time && timePoints[i] > time) {
const beforePosition = this.interpolatedTimeData[0][timePoints[i - 1]]; const beforePosition = this.interpolatedTimeData[j][timePoints[i - 1]];
const afterPosition = this.interpolatedTimeData[0][timePoints[i]]; const afterPosition = this.interpolatedTimeData[j][timePoints[i]];
const ratio = getRatio(timePoints[i - 1], timePoints[i], time); const ratio = getRatio(timePoints[i - 1], timePoints[i], time);
currentPosition[0] = { currentPosition[j] = {
...beforePosition, ...beforePosition,
time, time,
...interpolateOnLineSegment(beforePosition, afterPosition, this.settings.latKeyName, this.settings.lngKeyName, ratio) ...interpolateOnLineSegment(beforePosition, afterPosition, this.settings.latKeyName, this.settings.lngKeyName, ratio)
@ -157,15 +160,22 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
} }
} }
} }
this.calcLabel(); }
this.calcTooltip(currentPosition.find(position => position.entityName === this.activeTrip.entityName)); for(let j = 0; j < this.interpolatedTimeData.length; j++) {
if (isUndefined(currentPosition[j])) {
currentPosition[j] = this.calculateLastPoints(this.interpolatedTimeData[j], time);
}
}
this.calcLabel(currentPosition);
this.calcTooltip(currentPosition, true);
if (this.mapWidget && this.mapWidget.map && this.mapWidget.map.map) { if (this.mapWidget && this.mapWidget.map && this.mapWidget.map.map) {
this.mapWidget.map.updatePolylines(this.interpolatedTimeData.map(ds => _.values(ds)), true, this.activeTrip); const formattedInterpolatedTimeData = this.interpolatedTimeData.map(ds => _.values(ds));
this.mapWidget.map.updatePolylines(formattedInterpolatedTimeData, true);
if (this.settings.showPolygon) { if (this.settings.showPolygon) {
this.mapWidget.map.updatePolygons(this.interpolatedTimeData); this.mapWidget.map.updatePolygons(this.interpolatedTimeData);
} }
if (this.settings.showPoints) { if (this.settings.showPoints) {
this.mapWidget.map.updatePoints(_.values(_.union(this.interpolatedTimeData)[0]), this.calcTooltip); this.mapWidget.map.updatePoints(formattedInterpolatedTimeData, this.calcTooltip);
} }
this.mapWidget.map.updateMarkers(currentPosition, true, (trip) => { this.mapWidget.map.updateMarkers(currentPosition, true, (trip) => {
this.activeTrip = trip; this.activeTrip = trip;
@ -177,6 +187,23 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
setActiveTrip() { setActiveTrip() {
} }
private calculateLastPoints(dataSource: dataMap, time: number): FormattedData {
const timeArr = Object.keys(dataSource);
let index = timeArr.findIndex((dtime, index) => {
return Number(dtime) >= time;
});
if(index !== -1) {
if(Number(timeArr[index]) !== time && index !== 0) {
index--;
}
} else {
index = timeArr.length - 1;
}
return dataSource[timeArr[index]];
}
calculateIntervals() { calculateIntervals() {
this.historicalData.forEach((dataSource, index) => { this.historicalData.forEach((dataSource, index) => {
this.minTime = dataSource[0]?.time || Infinity; this.minTime = dataSource[0]?.time || Infinity;
@ -194,23 +221,39 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
} }
} }
calcTooltip = (point?: FormattedData): string => { calcTooltip = (points?: FormattedData[], isMainTooltip: boolean = false): string => {
let tooltipText;
if(isMainTooltip) {
this.mainTooltips = []
}
for (let point of points) {
const data = point ? point : this.activeTrip; const data = point ? point : this.activeTrip;
const tooltipPattern: string = this.settings.useTooltipFunction ? const tooltipPattern: string = this.settings.useTooltipFunction ?
safeExecute(this.settings.tooltipFunction, [data, this.historicalData, point.dsIndex]) : this.settings.tooltipPattern; safeExecute(this.settings.tooltipFunction, [data, this.historicalData, point.dsIndex]) : this.settings.tooltipPattern;
const tooltipText = parseWithTranslation.parseTemplate(tooltipPattern, data, true); tooltipText = parseWithTranslation.parseTemplate(tooltipPattern, data, true);
this.mainTooltip = this.sanitizer.sanitize( if(isMainTooltip) {
SecurityContext.HTML, tooltipText); this.mainTooltips.push(this.sanitizer.sanitize(SecurityContext.HTML, tooltipText));
}
this.cd.detectChanges(); this.cd.detectChanges();
this.activeTrip = point; this.activeTrip = point;
}
return tooltipText; return tooltipText;
} }
calcLabel() { calcLabel(formattedDataArr: FormattedData[]) {
const data = this.activeTrip; // const data = this.activeTrip;
// const labelText: string = this.settings.useLabelFunction ?
// safeExecute(this.settings.labelFunction, [data, this.historicalData, data.dsIndex]) : this.settings.label;
// this.label = (parseWithTranslation.parseTemplate(labelText, data, true));
// console.log(this.label, 'this.label');
this.label = '';
for (let formattedData of formattedDataArr) {
const data = formattedData;
const labelText: string = this.settings.useLabelFunction ? const labelText: string = this.settings.useLabelFunction ?
safeExecute(this.settings.labelFunction, [data, this.historicalData, data.dsIndex]) : this.settings.label; safeExecute(this.settings.labelFunction, [data, this.historicalData, data.dsIndex]) : this.settings.label;
this.label = (parseWithTranslation.parseTemplate(labelText, data, true)); const label = (parseWithTranslation.parseTemplate(labelText, data, true));
this.label = this.label.length ? this.label + ',' + label : label;
}
} }
interpolateArray(originData: FormattedData[]) { interpolateArray(originData: FormattedData[]) {