Commit 643563ec6a8cdce5df02b1e4adfc8d7a8d9c00ae

Authored by Dmitriymush
1 parent c3623be8

bug-fix: trip animation for multiple devices

@@ -599,26 +599,32 @@ export default abstract class LeafletMap { @@ -599,26 +599,32 @@ export default abstract class LeafletMap {
599 return polygon; 599 return polygon;
600 } 600 }
601 601
602 - updatePoints(pointsData: FormattedData[], getTooltip: (point: FormattedData, setTooltip?: boolean) => string) {  
603 - if (this.points) { 602 + updatePoints(pointsData: FormattedData[][], getTooltip: (point: FormattedData[], setTooltip?: boolean) => string) {
  603 + for(let i = 0; i < pointsData.length; i++) {
  604 + let pointsList = pointsData[i];
  605 + if(i === 0) {
  606 + if (this.points) {
604 this.map.removeLayer(this.points); 607 this.map.removeLayer(this.points);
  608 + }
  609 + this.points = new FeatureGroup();
605 } 610 }
606 - this.points = new FeatureGroup();  
607 - pointsData.filter(pdata => !!this.convertPosition(pdata)).forEach(data => {  
608 - const point = L.circleMarker(this.convertPosition(data), {  
609 - color: this.options.pointColor,  
610 - radius: this.options.pointSize  
611 - });  
612 - if (!this.options.pointTooltipOnRightPanel) {  
613 - point.on('click', () => getTooltip(data));  
614 - }  
615 - else {  
616 - createTooltip(point, this.options, data.$datasource, getTooltip(data, false));  
617 - }  
618 - this.points.addLayer(point); 611 + pointsList.filter(pdata => !!this.convertPosition(pdata)).forEach(data => {
  612 + const point = L.circleMarker(this.convertPosition(data), {
  613 + color: this.options.pointColor,
  614 + radius: this.options.pointSize
  615 + });
  616 + if (!this.options.pointTooltipOnRightPanel) {
  617 + point.on('click', () => getTooltip([data]));
  618 + } else {
  619 + createTooltip(point, this.options, data.$datasource, getTooltip([data], false));
  620 + }
  621 + this.points.addLayer(point);
619 }); 622 });
620 - this.map.addLayer(this.points); 623 + if(i === 0) {
  624 + this.map.addLayer(this.points);
  625 + }
621 } 626 }
  627 + }
622 628
623 // Polyline 629 // Polyline
624 630
@@ -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();
@@ -138,34 +141,41 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy @@ -138,34 +141,41 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
138 141
139 timeUpdated(time: number) { 142 timeUpdated(time: number) {
140 this.currentTime = time; 143 this.currentTime = time;
141 - const currentPosition = this.interpolatedTimeData 144 + let 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 }
160 - this.calcLabel();  
161 - this.calcTooltip(currentPosition.find(position => position.entityName === this.activeTrip.entityName)); 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 + }
  169 + this.calcLabel(currentPosition);
  170 + this.calcTooltip(currentPosition, true);
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, 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,23 +221,39 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy @@ -194,23 +221,39 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
194 } 221 }
195 } 222 }
196 223
197 - calcTooltip = (point?: FormattedData): string => {  
198 - const data = point ? point : this.activeTrip;  
199 - const tooltipPattern: string = this.settings.useTooltipFunction ?  
200 - 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; 224 + calcTooltip = (points?: FormattedData[], isMainTooltip: boolean = false): string => {
  225 + let tooltipText;
  226 + if(isMainTooltip) {
  227 + this.mainTooltips = []
  228 + }
  229 + for (let point of points) {
  230 + const data = point ? point : this.activeTrip;
  231 + const tooltipPattern: string = this.settings.useTooltipFunction ?
  232 + safeExecute(this.settings.tooltipFunction, [data, this.historicalData, point.dsIndex]) : this.settings.tooltipPattern;
  233 + tooltipText = parseWithTranslation.parseTemplate(tooltipPattern, data, true);
  234 + if(isMainTooltip) {
  235 + this.mainTooltips.push(this.sanitizer.sanitize(SecurityContext.HTML, tooltipText));
  236 + }
  237 + this.cd.detectChanges();
  238 + this.activeTrip = point;
  239 + }
206 return tooltipText; 240 return tooltipText;
207 } 241 }
208 242
209 - calcLabel() {  
210 - const data = this.activeTrip;  
211 - const labelText: string = this.settings.useLabelFunction ?  
212 - safeExecute(this.settings.labelFunction, [data, this.historicalData, data.dsIndex]) : this.settings.label;  
213 - this.label = (parseWithTranslation.parseTemplate(labelText, data, true)); 243 + calcLabel(formattedDataArr: FormattedData[]) {
  244 + // const data = this.activeTrip;
  245 + // const labelText: string = this.settings.useLabelFunction ?
  246 + // safeExecute(this.settings.labelFunction, [data, this.historicalData, data.dsIndex]) : this.settings.label;
  247 + // this.label = (parseWithTranslation.parseTemplate(labelText, data, true));
  248 + // console.log(this.label, 'this.label');
  249 + this.label = '';
  250 + for (let formattedData of formattedDataArr) {
  251 + const data = formattedData;
  252 + const labelText: string = this.settings.useLabelFunction ?
  253 + safeExecute(this.settings.labelFunction, [data, this.historicalData, data.dsIndex]) : this.settings.label;
  254 + const label = (parseWithTranslation.parseTemplate(labelText, data, true));
  255 + this.label = this.label.length ? this.label + ',' + label : label;
  256 + }
214 } 257 }
215 258
216 interpolateArray(originData: FormattedData[]) { 259 interpolateArray(originData: FormattedData[]) {