diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts index 5d6f39850e..6944e4d23d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts @@ -599,26 +599,32 @@ export default abstract class LeafletMap { return polygon; } - updatePoints(pointsData: FormattedData[], getTooltip: (point: FormattedData, setTooltip?: boolean) => string) { - if (this.points) { + 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) { this.map.removeLayer(this.points); + } + this.points = new FeatureGroup(); } - this.points = new FeatureGroup(); - pointsData.filter(pdata => !!this.convertPosition(pdata)).forEach(data => { - const point = L.circleMarker(this.convertPosition(data), { - color: this.options.pointColor, - radius: this.options.pointSize - }); - if (!this.options.pointTooltipOnRightPanel) { - point.on('click', () => getTooltip(data)); - } - else { - createTooltip(point, this.options, data.$datasource, getTooltip(data, false)); - } - this.points.addLayer(point); + pointsList.filter(pdata => !!this.convertPosition(pdata)).forEach(data => { + const point = L.circleMarker(this.convertPosition(data), { + color: this.options.pointColor, + radius: this.options.pointSize + }); + if (!this.options.pointTooltipOnRightPanel) { + point.on('click', () => getTooltip([data])); + } else { + createTooltip(point, this.options, data.$datasource, getTooltip([data], false)); + } + this.points.addLayer(point); }); - this.map.addLayer(this.points); + if(i === 0) { + this.map.addLayer(this.points); + } } + } // Polyline diff --git a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts b/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts index 99c399d3f2..b51cda6cbb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts @@ -47,6 +47,9 @@ import moment from 'moment'; import { isUndefined } from '@core/utils'; import { ResizeObserver } from '@juggle/resize-observer'; +interface dataMap { + [key: string] : FormattedData +} @Component({ // tslint:disable-next-line:component-selector @@ -70,7 +73,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy interpolatedTimeData = []; widgetConfig: WidgetConfig; settings: TripAnimationSettings; - mainTooltip = ''; + mainTooltips = []; visibleTooltip = false; activeTrip: FormattedData; label: string; @@ -115,7 +118,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy this.historicalData = parseArray(this.ctx.data).filter(arr => arr.length); if (this.historicalData.length) { this.calculateIntervals(); - this.timeUpdated(this.currentTime && this.currentTime > this.minTime ? this.currentTime : this.minTime); + this.timeUpdated(this.minTime); } this.mapWidget.map.map?.invalidateSize(); this.cd.detectChanges(); @@ -138,34 +141,41 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy timeUpdated(time: number) { this.currentTime = time; - const currentPosition = this.interpolatedTimeData + let currentPosition = this.interpolatedTimeData .map(dataSource => dataSource[time]) - .filter(ds => ds); - if (isUndefined(currentPosition[0])) { - const timePoints = Object.keys(this.interpolatedTimeData[0]).map(item => parseInt(item, 10)); - for (let i = 1; i < timePoints.length; i++) { - if (timePoints[i - 1] < time && timePoints[i] > time) { - const beforePosition = this.interpolatedTimeData[0][timePoints[i - 1]]; - const afterPosition = this.interpolatedTimeData[0][timePoints[i]]; - const ratio = getRatio(timePoints[i - 1], timePoints[i], time); - currentPosition[0] = { - ...beforePosition, - time, - ...interpolateOnLineSegment(beforePosition, afterPosition, this.settings.latKeyName, this.settings.lngKeyName, ratio) + for(let j = 0; j < this.interpolatedTimeData.length; j++) { + if (isUndefined(currentPosition[j])) { + const timePoints = Object.keys(this.interpolatedTimeData[j]).map(item => parseInt(item, 10)); + for (let i = 1; i < timePoints.length; i++) { + if (timePoints[i - 1] < time && timePoints[i] > time) { + const beforePosition = this.interpolatedTimeData[j][timePoints[i - 1]]; + const afterPosition = this.interpolatedTimeData[j][timePoints[i]]; + const ratio = getRatio(timePoints[i - 1], timePoints[i], time); + currentPosition[j] = { + ...beforePosition, + time, + ...interpolateOnLineSegment(beforePosition, afterPosition, this.settings.latKeyName, this.settings.lngKeyName, ratio) + } + break; } - break; } } } - 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) { - 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) { this.mapWidget.map.updatePolygons(this.interpolatedTimeData); } 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.activeTrip = trip; @@ -177,6 +187,23 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy 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() { this.historicalData.forEach((dataSource, index) => { this.minTime = dataSource[0]?.time || Infinity; @@ -194,23 +221,39 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy } } - calcTooltip = (point?: FormattedData): string => { - const data = point ? point : this.activeTrip; - const tooltipPattern: string = this.settings.useTooltipFunction ? - safeExecute(this.settings.tooltipFunction, [data, this.historicalData, point.dsIndex]) : this.settings.tooltipPattern; - const tooltipText = parseWithTranslation.parseTemplate(tooltipPattern, data, true); - this.mainTooltip = this.sanitizer.sanitize( - SecurityContext.HTML, tooltipText); - this.cd.detectChanges(); - this.activeTrip = point; + 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 tooltipPattern: string = this.settings.useTooltipFunction ? + safeExecute(this.settings.tooltipFunction, [data, this.historicalData, point.dsIndex]) : this.settings.tooltipPattern; + tooltipText = parseWithTranslation.parseTemplate(tooltipPattern, data, true); + if(isMainTooltip) { + this.mainTooltips.push(this.sanitizer.sanitize(SecurityContext.HTML, tooltipText)); + } + this.cd.detectChanges(); + this.activeTrip = point; + } return tooltipText; } - calcLabel() { - 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)); + calcLabel(formattedDataArr: FormattedData[]) { + // 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 ? + safeExecute(this.settings.labelFunction, [data, this.historicalData, data.dsIndex]) : this.settings.label; + const label = (parseWithTranslation.parseTemplate(labelText, data, true)); + this.label = this.label.length ? this.label + ',' + label : label; + } } interpolateArray(originData: FormattedData[]) {