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 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 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 629 // Polyline
624 630
... ...
... ... @@ -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();
... ... @@ -138,34 +141,41 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy
138 141
139 142 timeUpdated(time: number) {
140 143 this.currentTime = time;
141   - const currentPosition = this.interpolatedTimeData
  144 + let 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 }
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 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, 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,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 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 259 interpolateArray(originData: FormattedData[]) {
... ...