Browse Source

some typing and poly improvements

pull/2535/head
Adsumus 7 years ago
parent
commit
f064f28053
  1. 68
      ui-ngx/package-lock.json
  2. 2
      ui-ngx/package.json
  3. 16
      ui-ngx/src/app/core/schema-utils.ts
  4. 6
      ui-ngx/src/app/core/utils.ts
  5. 19
      ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts
  6. 12
      ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts
  7. 29
      ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts
  8. 2
      ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.scss
  9. 45
      ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts
  10. 8
      ui-ngx/src/app/shared/components/time/history-selector/history-selector.component.ts
  11. 0
      ui-ngx/src/typings/add-marker.d.ts
  12. 3
      ui-ngx/tsconfig.json

68
ui-ngx/package-lock.json

@ -1897,6 +1897,15 @@
"@types/geojson": "*"
}
},
"@types/leaflet-polylinedecorator": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@types/leaflet-polylinedecorator/-/leaflet-polylinedecorator-1.6.0.tgz",
"integrity": "sha512-Z2BXZDjKEqHclwrAmhYdF1RwyFfa/NFxsoF79sitzaj5D/4YWHp/zDRcUZar5cQFKRgK66AYEIF7nKVuMzUGdw==",
"dev": true,
"requires": {
"@types/leaflet": "*"
}
},
"@types/lodash": {
"version": "4.14.149",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz",
@ -8274,11 +8283,24 @@
"leaflet": ">=0.7.0"
}
},
"leaflet-polylinedecorator": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/leaflet-polylinedecorator/-/leaflet-polylinedecorator-1.6.0.tgz",
"integrity": "sha1-nvef0bUwLWe3Lv6Vmo7NJVPycmY=",
"requires": {
"leaflet-rotatedmarker": "^0.2.0"
}
},
"leaflet-providers": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/leaflet-providers/-/leaflet-providers-1.9.1.tgz",
"integrity": "sha512-YpJB9y4/nT5NGicU9vuqlttJaCer6paD3J3b8Wrw+IIQvK9dtcdzE9CsTkDg7Dg9FeGp5NEr3hu17xcHbYI/2w=="
},
"leaflet-rotatedmarker": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/leaflet-rotatedmarker/-/leaflet-rotatedmarker-0.2.0.tgz",
"integrity": "sha1-RGf0n5jRv9VpWb2cZwUgPdJgEnc="
},
"leaflet.gridlayer.googlemutant": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/leaflet.gridlayer.googlemutant/-/leaflet.gridlayer.googlemutant-0.8.0.tgz",
@ -14425,7 +14447,7 @@
"dev": true,
"optional": true,
"requires": {
"balanced-match": "1.0.0",
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
@ -14465,7 +14487,7 @@
"dev": true,
"optional": true,
"requires": {
"ms": "2.1.2"
"ms": "^2.1.1"
}
},
"deep-extend": {
@ -14552,7 +14574,7 @@
"dev": true,
"optional": true,
"requires": {
"minimatch": "3.0.4"
"minimatch": "^3.0.4"
}
},
"inflight": {
@ -14583,7 +14605,7 @@
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "1.0.1"
"number-is-nan": "^1.0.0"
}
},
"isarray": {
@ -14598,7 +14620,7 @@
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "1.1.11"
"brace-expansion": "^1.1.7"
}
},
"minimist": {
@ -14676,8 +14698,8 @@
"dev": true,
"optional": true,
"requires": {
"abbrev": "1.1.1",
"osenv": "0.1.5"
"abbrev": "1",
"osenv": "^0.1.4"
}
},
"npm-bundled": {
@ -14686,7 +14708,7 @@
"dev": true,
"optional": true,
"requires": {
"npm-normalize-package-bin": "1.0.1"
"npm-normalize-package-bin": "^1.0.1"
}
},
"npm-normalize-package-bin": {
@ -14701,8 +14723,8 @@
"dev": true,
"optional": true,
"requires": {
"ignore-walk": "3.0.3",
"npm-bundled": "1.1.1"
"ignore-walk": "^3.0.1",
"npm-bundled": "^1.0.1"
}
},
"npmlog": {
@ -14756,8 +14778,8 @@
"dev": true,
"optional": true,
"requires": {
"os-homedir": "1.0.2",
"os-tmpdir": "1.0.2"
"os-homedir": "^1.0.0",
"os-tmpdir": "^1.0.0"
}
},
"path-is-absolute": {
@ -15398,7 +15420,7 @@
"dev": true,
"optional": true,
"requires": {
"ms": "2.1.2"
"ms": "^2.1.1"
}
},
"deep-extend": {
@ -15485,7 +15507,7 @@
"dev": true,
"optional": true,
"requires": {
"minimatch": "3.0.4"
"minimatch": "^3.0.4"
}
},
"inflight": {
@ -15516,7 +15538,7 @@
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "1.0.1"
"number-is-nan": "^1.0.0"
}
},
"isarray": {
@ -15531,7 +15553,7 @@
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "1.1.11"
"brace-expansion": "^1.1.7"
}
},
"minimist": {
@ -15609,8 +15631,8 @@
"dev": true,
"optional": true,
"requires": {
"abbrev": "1.1.1",
"osenv": "0.1.5"
"abbrev": "1",
"osenv": "^0.1.4"
}
},
"npm-bundled": {
@ -15619,7 +15641,7 @@
"dev": true,
"optional": true,
"requires": {
"npm-normalize-package-bin": "1.0.1"
"npm-normalize-package-bin": "^1.0.1"
}
},
"npm-normalize-package-bin": {
@ -15634,8 +15656,8 @@
"dev": true,
"optional": true,
"requires": {
"ignore-walk": "3.0.3",
"npm-bundled": "1.1.1"
"ignore-walk": "^3.0.1",
"npm-bundled": "^1.0.1"
}
},
"npmlog": {
@ -15689,8 +15711,8 @@
"dev": true,
"optional": true,
"requires": {
"os-homedir": "1.0.2",
"os-tmpdir": "1.0.2"
"os-homedir": "^1.0.0",
"os-tmpdir": "^1.0.0"
}
},
"path-is-absolute": {

2
ui-ngx/package.json

@ -58,6 +58,7 @@
"jstree-bootstrap-theme": "^1.0.1",
"leaflet": "^1.6.0",
"leaflet-geometryutil": "^0.9.3",
"leaflet-polylinedecorator": "^1.6.0",
"leaflet-providers": "^1.9.1",
"leaflet.gridlayer.googlemutant": "^0.8.0",
"leaflet.markercluster": "^1.4.1",
@ -105,6 +106,7 @@
"@types/js-beautify": "^1.8.1",
"@types/jstree": "^3.3.39",
"@types/leaflet": "^1.5.9",
"@types/leaflet-polylinedecorator": "^1.6.0",
"@types/lodash": "^4.14.149",
"@types/raphael": "^2.1.30",
"@types/react": "^16.9.20",

16
ui-ngx/src/app/core/schema-utils.ts

@ -14,8 +14,10 @@
/// limitations under the License.
///
import { JsonSchema, JsonSettingsSchema } from '@app/shared/public-api';
export function initSchema() {
export function initSchema(): JsonSettingsSchema {
return {
schema: {
type: 'object',
@ -27,21 +29,21 @@ export function initSchema() {
};
}
export function addGroupInfo(schema, title: string) {
export function addGroupInfo(schema: JsonSettingsSchema, title: string) {
schema.groupInfoes.push({
formIndex: schema.groupInfoes?.length || 0,
GroupTitle: title
});
}
export function addToSchema(schema, newSchema) {
export function addToSchema(schema: JsonSettingsSchema, newSchema: JsonSettingsSchema) {
Object.assign(schema.schema.properties, newSchema.schema.properties);
schema.schema.required = schema.schema.required.concat(newSchema.schema.required);
schema.form.push(newSchema.form);
}
export function mergeSchemes(schemes: any[]) {
return schemes.reduce((finalSchema, schema) => {
export function mergeSchemes(schemes: JsonSettingsSchema[]): JsonSettingsSchema {
return schemes.reduce((finalSchema: JsonSettingsSchema, schema: JsonSettingsSchema) => {
return {
schema: {
properties: {
@ -57,11 +59,11 @@ export function mergeSchemes(schemes: any[]) {
...finalSchema.form,
...schema.form
]
}
} as JsonSettingsSchema;
}, initSchema());
}
export function addCondition(schema, condition: String) {
export function addCondition(schema: JsonSettingsSchema, condition: String): JsonSettingsSchema {
schema.form = schema.form.map(element => {
if (typeof element === 'string') {
return {

6
ui-ngx/src/app/core/utils.ts

@ -529,6 +529,10 @@ export function parseTemplate(template: string, data: object) {
.match(/\{(.*?)\}/g) // find expressions
.map(exp => exp.replace(/{|}/g, '')) // remove brackets
.map(exp => exp.split(':'))
.map(arr => {
variables += `let ${arr[0]} = ''; `;
return arr;
})
.filter(arr => !!arr[1]) // filter expressions without format
.reduce((res, current) => {
res[current[0]] = current[1];
@ -537,7 +541,7 @@ export function parseTemplate(template: string, data: object) {
for (const key in data) {
if (!key.includes('|'))
variables += `let ${key} = '${expressions[key] ? padValue(data[key], +expressions[key]) : data[key]}';`;
variables += `${key} = '${expressions[key] ? padValue(data[key], +expressions[key]) : data[key]}';`;
}
template = template.replace(/:\d+}/g, '}');
res = safeExecute(parseFunction(variables + 'return' + '`' + template + '`'));

19
ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts

@ -15,7 +15,6 @@
///
import L from 'leaflet';
import './add-marker';
import 'leaflet-providers';
import 'leaflet.markercluster/dist/MarkerCluster.css'
@ -40,7 +39,7 @@ export default abstract class LeafletMap {
map$: BehaviorSubject<L.Map> = new BehaviorSubject(null);
ready$: Observable<L.Map> = this.map$.pipe(filter(map => !!map));
options: MapOptions;
isMarketCluster;
isMarketCluster: boolean;
bounds: L.LatLngBounds;
constructor($container: HTMLElement, options: MapOptions) {
@ -68,8 +67,8 @@ export default abstract class LeafletMap {
addMarkerControl() {
if (this.options.draggebleMarker)
L.Control.AddMarker = L.Control.extend({
onAdd (map) {
L.Control.AddMarker = L.Control.extend({
onAdd(map) {
const img = L.DomUtil.create('img') as any;
img.src = `assets/add_location.svg`;
img.style.width = '32px';
@ -77,10 +76,10 @@ export default abstract class LeafletMap {
img.onclick = this.dragMarker;
return img;
},
addHooks () {
addHooks() {
L.DomEvent.on(window as any, 'onclick', this.enableDragMode, this);
},
onRemove (map) {
onRemove(map) {
},
dragMarker: ($event) => {
this.dragMode = !this.dragMode;
@ -122,15 +121,15 @@ export default abstract class LeafletMap {
return this.map;
}
createLatLng(lat, lng) {
createLatLng(lat: number, lng: number): L.LatLng {
return L.latLng(lat, lng);
}
createBounds() {
createBounds(): L.LatLngBounds {
return this.map.getBounds();
}
extendBounds(bounds, polyline) {
extendBounds(bounds: L.LatLngBounds, polyline: L.Polyline) {
if (polyline && polyline.getLatLngs() && polyline.getBounds()) {
bounds.extend(polyline.getBounds());
}
@ -204,7 +203,7 @@ export default abstract class LeafletMap {
}
// polyline
// Polyline
updatePolylines(polyData: Array<Array<any>>) {
polyData.forEach(data => {

12
ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts

@ -17,7 +17,7 @@
import L from 'leaflet';
import _ from 'lodash';
export function createTooltip(target, settings) {
export function createTooltip(target: L.Layer, settings): L.Popup {
const popup = L.popup();
popup.setContent('');
target.bindPopup(popup, { autoClose: settings.autocloseTooltip, closeOnClick: false });
@ -33,3 +33,13 @@ export function createTooltip(target, settings) {
return popup;
}
export function getRatio(firsMoment: number, secondMoment: number, intermediateMoment: number): number {
return (intermediateMoment - firsMoment) / (secondMoment - firsMoment);
};
export function findAngle(startPoint, endPoint) {
let angle = -Math.atan2(endPoint.latitude - startPoint.latitude, endPoint.longitude - startPoint.longitude);
angle = angle * 180 / Math.PI;
return parseInt(angle.toFixed(2));
}

29
ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts

@ -14,7 +14,9 @@
/// limitations under the License.
///
import L from 'leaflet';
import L, { PolylineDecoratorOptions } from 'leaflet';
import 'leaflet-polylinedecorator';
import { safeExecute } from '@app/core/utils';
export class Polyline {
@ -26,9 +28,30 @@ export class Polyline {
constructor(private map: L.Map, locations, data, dataSources, settings) {
this.dataSources = dataSources;
this.data = data;
this.leafletPoly = L.polyline(locations,
this.getPolyStyle(settings, data, dataSources)
).addTo(this.map);
if (settings.usePolylineDecorator) {
L.polylineDecorator(this.leafletPoly, {
patterns: [
{
offset: settings.decoratorOffset,
endOffset: settings.endDecoratorOffset,
repeat: settings.decoratorRepeat,
symbol: L.Symbol[settings.decoratorSymbol]({
pixelSize: settings.decoratorSymbolSize,
polygon: false,
pathOptions: {
color: settings.useDecoratorCustomColor ? settings.decoratorCustomColor : this.getPolyStyle(settings, data, dataSources).color,
stroke: true
}
})
}
],
interactive: false,
} as PolylineDecoratorOptions).addTo(this.map);
}
}
updatePolyline(settings, data, dataSources) {
@ -38,8 +61,8 @@ export class Polyline {
getPolyStyle(settings, data, dataSources): L.PolylineOptions {
return {
color: settings.useColorFunction ? safeExecute(settings.colorFunction, [data, dataSources, data[0]?.dsIndex]) : settings.color,
opacity: settings.strokeOpacity,
weight: settings.strokeWeight
opacity: settings.useStrokeOpacityFunction ? safeExecute(settings.strokeOpacityFunction, [data, dataSources, data[0]?.dsIndex]) : settings.strokeOpacity,
weight: settings.useStrokeWeightFunction ? safeExecute(settings.strokeWeightFunction, [data, dataSources, data[0]?.dsIndex]) : settings.strokeWeight,
}
}

2
ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.scss

@ -76,7 +76,7 @@
position: absolute;
top: 38px;
right: 0;
z-index: 2;
z-index: 400;
padding: 10px;
background-color: #fff;
transition: 0.3s ease-in-out;

45
ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts

@ -26,8 +26,9 @@ import { parseArray, parseTemplate, safeExecute } from '@app/core/utils';
import { initSchema, addToSchema, addGroupInfo } from '@app/core/schema-utils';
import { tripAnimationSchema } from '../lib/maps/schemes';
import { DomSanitizer } from '@angular/platform-browser';
import { WidgetConfig } from '@app/shared/public-api';
import { WidgetConfig, JsonSchema, JsonSettingsSchema } from '@app/shared/public-api';
import { WidgetContext } from '@app/modules/home/models/widget-component.models';
import { getRatio, findAngle } from '../lib/maps/maps-utils';
@Component({
@ -37,7 +38,7 @@ import { WidgetContext } from '@app/modules/home/models/widget-component.models'
})
export class TripAnimationComponent implements OnInit, AfterViewInit {
constructor(private cd: ChangeDetectorRef,private sanitizer: DomSanitizer) { }
constructor(private cd: ChangeDetectorRef, private sanitizer: DomSanitizer) { }
@Input() ctx: WidgetContext;
@ -48,13 +49,13 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
intervals;
normalizationStep = 1000;
interpolatedData = [];
widgetConfig;
widgetConfig: WidgetConfig;
settings;
mainTooltip = '';
visibleTooltip = false;
activeTrip;
static getSettingsSchema() {
static getSettingsSchema(): JsonSettingsSchema {
const schema = initSchema();
addToSchema(schema, TbMapWidgetV2.getProvidersSchema());
addGroupInfo(schema, 'Map Provider Settings');
@ -79,6 +80,8 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
this.activeTrip = this.historicalData[0][0];
this.calculateIntervals();
this.timeUpdated(this.intervals[0]);
this.mapWidget.map.updatePolylines(this.interpolatedData.map(ds => _.values(ds)));
this.mapWidget.map.map?.invalidateSize();
this.cd.detectChanges();
}
@ -91,16 +94,20 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
this.mapWidget = new MapWidgetController(MapProviders.openstreet, false, ctxCopy, this.mapContainer.nativeElement);
}
timeUpdated(time) {
timeUpdated(time: number) {
const currentPosition = this.interpolatedData.map(dataSource => dataSource[time]);
this.activeTrip = currentPosition[0];
this.mapWidget.map.updatePolylines(this.interpolatedData);
console.log("TripAnimationComponent -> timeUpdated -> this.interpolatedData", this.interpolatedData)
if (this.settings.showPolygon) {
this.mapWidget.map.updatePolygons(this.interpolatedData);
}
this.mapWidget.map.updateMarkers(currentPosition);
}
setActiveTrip() {
}
calculateIntervals() {
this.historicalData.forEach((dataSource, index) => {
this.intervals = [];
@ -113,24 +120,16 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
}
showHideTooltip() {
console.log(this.activeTrip);
const tooltipText: string = this.settings.useTooltipFunction ? safeExecute(this.settings.tooolTipFunction) :
// this.mainTooltip = this.sanitizer.sanitize(SecurityContext.HTML, parseTemplate(tooltipText, this.activeTrip))
this.visibleTooltip = !this.visibleTooltip;
const tooltipText: string = this.settings.useTooltipFunction ? safeExecute(this.settings.tooolTipFunction, [this.activeTrip, this.historicalData, 0])
: this.settings.tooltipPattern;
this.mainTooltip = this.sanitizer.sanitize(SecurityContext.HTML, parseTemplate(tooltipText, this.activeTrip))
console.log("TripAnimationComponent -> showHideTooltip -> this.mainTooltip", this.mainTooltip)
this.visibleTooltip = !this.visibleTooltip;
}
interpolateArray(originData, interpolatedIntervals) {
const getRatio = (firsMoment, secondMoment, intermediateMoment) => {
return (intermediateMoment - firsMoment) / (secondMoment - firsMoment);
};
function findAngle(startPoint, endPoint) {
let angle = -Math.atan2(endPoint.latitude - startPoint.latitude, endPoint.longitude - startPoint.longitude);
angle = angle * 180 / Math.PI;
return parseInt(angle.toFixed(2));
}
const result = {};
for (let i = 1, j = 0; i < originData.length, j < interpolatedIntervals.length;) {
@ -151,6 +150,8 @@ export class TripAnimationComponent implements OnInit, AfterViewInit {
j++;
}
return result;
}}
}
}
export let TbTripAnimationWidget = TripAnimationComponent;
export let TbTripAnimationWidget = TripAnimationComponent;

8
ui-ngx/src/app/shared/components/time/history-selector/history-selector.component.ts

@ -15,7 +15,7 @@
///
import { Component, OnInit, OnChanges, Input, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';
import { interval, Subscription } from 'rxjs';
import { interval, Subscription, Subscriber, SubscriptionLike, Observer } from 'rxjs';
import { filter, tap } from 'rxjs/operators';
@Component({
@ -28,7 +28,7 @@ export class HistorySelectorComponent implements OnInit, OnChanges {
@Input() settings
@Input() intervals = [];
@Output() onTimeUpdated = new EventEmitter();
@Output() onTimeUpdated: EventEmitter<number> = new EventEmitter();
animationTime;
minTimeIndex = 0;
@ -70,12 +70,14 @@ export class HistorySelectorComponent implements OnInit, OnChanges {
this.playing = false;
this.interval = null;
this.cd.detectChanges();
});
});
}
reeneble() {
if (this.playing) {
let position = this.index;
this.interval.complete();
this.index = position;
this.play();
}
}

0
ui-ngx/src/app/modules/home/components/widget/lib/maps/add-marker.ts → ui-ngx/src/typings/add-marker.d.ts

3
ui-ngx/tsconfig.json

@ -19,7 +19,8 @@
"src/typings/jquery.typings.d.ts",
"src/typings/jquery.flot.typings.d.ts",
"src/typings/jquery.jstree.typings.d.ts",
"src/typings/split.js.typings.d.ts"
"src/typings/split.js.typings.d.ts",
"src/typings/add-marker.d.ts"
],
"paths": {
"@app/*": ["src/app/*"],

Loading…
Cancel
Save