Commit 77d5e6c44fda131038ca2bf21ad6943b5209a763
Committed by
GitHub
Merge pull request #3701 from Dmitriymush/master
[3.2.1] bug-fix: Trip-animation
Showing
4 changed files
with
85 additions
and
42 deletions
... | ... | @@ -608,26 +608,32 @@ export default abstract class LeafletMap { |
608 | 608 | return polygon; |
609 | 609 | } |
610 | 610 | |
611 | - updatePoints(pointsData: FormattedData[], getTooltip: (point: FormattedData, setTooltip?: boolean) => string) { | |
611 | + updatePoints(pointsData: FormattedData[][], getTooltip: (point: FormattedData) => string) { | |
612 | + if(pointsData.length) { | |
612 | 613 | if (this.points) { |
613 | - this.map.removeLayer(this.points); | |
614 | + this.map.removeLayer(this.points); | |
614 | 615 | } |
615 | 616 | this.points = new FeatureGroup(); |
616 | - pointsData.filter(pdata => !!this.convertPosition(pdata)).forEach(data => { | |
617 | - const point = L.circleMarker(this.convertPosition(data), { | |
618 | - color: this.options.pointColor, | |
619 | - radius: this.options.pointSize | |
620 | - }); | |
621 | - if (!this.options.pointTooltipOnRightPanel) { | |
622 | - point.on('click', () => getTooltip(data)); | |
623 | - } | |
624 | - else { | |
625 | - createTooltip(point, this.options, data.$datasource, getTooltip(data, false)); | |
626 | - } | |
627 | - this.points.addLayer(point); | |
617 | + } | |
618 | + for(let i = 0; i < pointsData.length; i++) { | |
619 | + const pointsList = pointsData[i]; | |
620 | + pointsList.filter(pdata => !!this.convertPosition(pdata)).forEach(data => { | |
621 | + const point = L.circleMarker(this.convertPosition(data), { | |
622 | + color: this.options.pointColor, | |
623 | + radius: this.options.pointSize | |
624 | + }); | |
625 | + if (!this.options.pointTooltipOnRightPanel) { | |
626 | + point.on('click', () => getTooltip(data)); | |
627 | + } else { | |
628 | + createTooltip(point, this.options, data.$datasource, getTooltip(data)); | |
629 | + } | |
630 | + this.points.addLayer(point); | |
628 | 631 | }); |
632 | + } | |
633 | + if(pointsData.length) { | |
629 | 634 | this.map.addLayer(this.points); |
630 | 635 | } |
636 | + } | |
631 | 637 | |
632 | 638 | // Polyline |
633 | 639 | ... | ... |
... | ... | @@ -28,8 +28,12 @@ |
28 | 28 | </button> |
29 | 29 | </div> |
30 | 30 | <div class="trip-animation-tooltip md-whiteframe-z4" fxLayout="column" |
31 | - [ngClass]="{'trip-animation-tooltip-hidden':!visibleTooltip}" [innerHTML]="mainTooltip" | |
32 | - [ngStyle]="{'background-color': settings.tooltipColor, 'opacity': settings.tooltipOpacity, 'color': settings.tooltipFontColor}"> | |
31 | + [ngClass]="{'trip-animation-tooltip-hidden':!visibleTooltip}" | |
32 | + [ngStyle]="{'background-color': settings.tooltipColor, 'opacity': settings.tooltipOpacity, 'color': settings.tooltipFontColor}"> | |
33 | + <div *ngFor="let mainTooltip of mainTooltips" | |
34 | + [innerHTML]="mainTooltip" | |
35 | + style="padding: 10px 0"> | |
36 | + </div> | |
33 | 37 | </div> |
34 | 38 | </div> |
35 | 39 | <tb-history-selector *ngIf="historicalData" | ... | ... |
... | ... | @@ -47,6 +47,9 @@ import moment from 'moment'; |
47 | 47 | import { isUndefined } from '@core/utils'; |
48 | 48 | import { ResizeObserver } from '@juggle/resize-observer'; |
49 | 49 | |
50 | +interface dataMap { | |
51 | + [key: string] : FormattedData | |
52 | +} | |
50 | 53 | |
51 | 54 | @Component({ |
52 | 55 | // tslint:disable-next-line:component-selector |
... | ... | @@ -70,7 +73,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
70 | 73 | interpolatedTimeData = []; |
71 | 74 | widgetConfig: WidgetConfig; |
72 | 75 | settings: TripAnimationSettings; |
73 | - mainTooltip = ''; | |
76 | + mainTooltips = []; | |
74 | 77 | visibleTooltip = false; |
75 | 78 | activeTrip: FormattedData; |
76 | 79 | label: string; |
... | ... | @@ -115,7 +118,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
115 | 118 | this.historicalData = parseArray(this.ctx.data).filter(arr => arr.length); |
116 | 119 | if (this.historicalData.length) { |
117 | 120 | this.calculateIntervals(); |
118 | - this.timeUpdated(this.currentTime && this.currentTime > this.minTime ? this.currentTime : this.minTime); | |
121 | + this.timeUpdated(this.minTime); | |
119 | 122 | } |
120 | 123 | this.mapWidget.map.map?.invalidateSize(); |
121 | 124 | this.cd.detectChanges(); |
... | ... | @@ -140,32 +143,39 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
140 | 143 | this.currentTime = time; |
141 | 144 | const currentPosition = this.interpolatedTimeData |
142 | 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 | 169 | this.calcLabel(); |
161 | - this.calcTooltip(currentPosition.find(position => position.entityName === this.activeTrip.entityName)); | |
170 | + this.calcMainTooltip(currentPosition); | |
162 | 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 | 174 | if (this.settings.showPolygon) { |
165 | 175 | this.mapWidget.map.updatePolygons(this.interpolatedTimeData); |
166 | 176 | } |
167 | 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 | 180 | this.mapWidget.map.updateMarkers(currentPosition, true, (trip) => { |
171 | 181 | this.activeTrip = trip; |
... | ... | @@ -177,6 +187,23 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
177 | 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 | 207 | calculateIntervals() { |
181 | 208 | this.historicalData.forEach((dataSource, index) => { |
182 | 209 | this.minTime = dataSource[0]?.time || Infinity; |
... | ... | @@ -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 | 225 | const data = point ? point : this.activeTrip; |
199 | 226 | const tooltipPattern: string = this.settings.useTooltipFunction ? |
200 | 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 | 239 | calcLabel() { | ... | ... |