thingsboard-aplcache
Changes
ui/src/app/api/data-aggregator.js 59(+31 -28)
ui/src/app/api/datasource.service.js 39(+35 -4)
ui/src/app/widget/lib/google-map.js 31(+18 -13)
ui/src/app/widget/lib/map-widget.js 10(+5 -5)
ui/src/app/widget/lib/openstreet-map.js 29(+17 -12)
Details
ui/src/app/api/data-aggregator.js 59(+31 -28)
diff --git a/ui/src/app/api/data-aggregator.js b/ui/src/app/api/data-aggregator.js
index 76d3b1c..68b0d91 100644
--- a/ui/src/app/api/data-aggregator.js
+++ b/ui/src/app/api/data-aggregator.js
@@ -19,6 +19,10 @@ export default class DataAggregator {
constructor(onDataCb, tsKeyNames, startTs, limit, aggregationType, timeWindow, interval, types, $timeout, $filter) {
this.onDataCb = onDataCb;
this.tsKeyNames = tsKeyNames;
+ this.dataBuffer = {};
+ for (var k in tsKeyNames) {
+ this.dataBuffer[tsKeyNames[k]] = [];
+ }
this.startTs = startTs;
this.aggregationType = aggregationType;
this.types = types;
@@ -120,11 +124,11 @@ export default class DataAggregator {
if (delta || !this.data) {
this.startTs += delta * this.interval;
this.endTs += delta * this.interval;
- this.data = toData(this.tsKeyNames, this.aggregationMap, this.startTs, this.endTs, this.$filter, this.limit);
+ this.data = this.updateData();
this.elapsed = this.elapsed - delta * this.interval;
}
} else {
- this.data = toData(this.tsKeyNames, this.aggregationMap, this.startTs, this.endTs, this.$filter, this.limit);
+ this.data = this.updateData();
}
if (this.onDataCb) {
this.onDataCb(this.data, this.startTs, this.endTs, apply);
@@ -138,6 +142,31 @@ export default class DataAggregator {
}
}
+ updateData() {
+ for (var k in this.tsKeyNames) {
+ this.dataBuffer[this.tsKeyNames[k]] = [];
+ }
+ for (var key in this.aggregationMap) {
+ var aggKeyData = this.aggregationMap[key];
+ var keyData = this.dataBuffer[key];
+ for (var aggTimestamp in aggKeyData) {
+ if (aggTimestamp <= this.startTs) {
+ delete aggKeyData[aggTimestamp];
+ } else if (aggTimestamp <= this.endTs) {
+ var aggData = aggKeyData[aggTimestamp];
+ var kvPair = [Number(aggTimestamp), aggData.aggValue];
+ keyData.push(kvPair);
+ }
+ }
+ keyData = this.$filter('orderBy')(keyData, '+this[0]');
+ if (keyData.length > this.limit) {
+ keyData = keyData.slice(keyData.length - this.limit);
+ }
+ this.dataBuffer[key] = keyData;
+ }
+ return this.dataBuffer;
+ }
+
destroy() {
if (this.intervalTimeoutHandle) {
this.$timeout.cancel(this.intervalTimeoutHandle);
@@ -208,32 +237,6 @@ function updateAggregatedData(aggregationMap, isCount, noAggregation, aggFunctio
}
}
-function toData(tsKeyNames, aggregationMap, startTs, endTs, $filter, limit) {
- var data = {};
- for (var k in tsKeyNames) {
- data[tsKeyNames[k]] = [];
- }
- for (var key in aggregationMap) {
- var aggKeyData = aggregationMap[key];
- var keyData = data[key];
- for (var aggTimestamp in aggKeyData) {
- if (aggTimestamp <= startTs) {
- delete aggKeyData[aggTimestamp];
- } else if (aggTimestamp <= endTs) {
- var aggData = aggKeyData[aggTimestamp];
- var kvPair = [Number(aggTimestamp), aggData.aggValue];
- keyData.push(kvPair);
- }
- }
- keyData = $filter('orderBy')(keyData, '+this[0]');
- if (keyData.length > limit) {
- keyData = keyData.slice(keyData.length - limit);
- }
- data[key] = keyData;
- }
- return data;
-}
-
function convertValue(value, noAggregation) {
if (!noAggregation || value && isNumeric(value)) {
return Number(value);
ui/src/app/api/datasource.service.js 39(+35 -4)
diff --git a/ui/src/app/api/datasource.service.js b/ui/src/app/api/datasource.service.js
index 8b49cf4..7a2486d 100644
--- a/ui/src/app/api/datasource.service.js
+++ b/ui/src/app/api/datasource.service.js
@@ -110,6 +110,8 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
datasourceSubscription.subscriptionTimewindow.realtimeWindowMs;
var timer;
var frequency;
+ var tickElapsed = 0;
+ var tickScheduledTime = 0;
var dataAggregator;
var subscription = {
@@ -353,11 +355,14 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
}
dataAggregator = createRealtimeDataAggregator(subsTw, tsKeyNames, types.dataKeyType.function);
}
+ tickScheduledTime = currentTime();
if (history) {
onTick(false);
} else {
timer = $timeout(
- function() {onTick(true)},
+ function() {
+ onTick(true)
+ },
0,
false
);
@@ -393,6 +398,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
function unsubscribe() {
if (timer) {
$timeout.cancel(timer);
+ timer = null;
}
if (datasourceType === types.datasourceType.device) {
for (var cmdId in subscribers) {
@@ -456,15 +462,39 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
}
}
+ /* eslint-disable */
+ function currentTime() {
+ return window.performance && window.performance.now ?
+ window.performance.now() : Date.now();
+ }
+ /* eslint-enable */
+
+
function onTick(apply) {
+
+ var now = currentTime();
+ tickElapsed += now - tickScheduledTime;
+ tickScheduledTime = now;
+
+ if (timer) {
+ $timeout.cancel(timer);
+ timer = null;
+ }
+
var key;
if (datasourceSubscription.type === types.widgetType.timeseries.value) {
var startTime;
var endTime;
+ var delta;
var generatedData = {
data: {
}
};
+ if (!history) {
+ delta = Math.floor(tickElapsed / frequency);
+ }
+ var deltaElapsed = history ? frequency : delta * frequency;
+ tickElapsed = tickElapsed - deltaElapsed;
for (key in dataKeys) {
var dataKeyList = dataKeys[key];
for (var index = 0; index < dataKeyList.length; index ++) {
@@ -472,11 +502,12 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
if (!startTime) {
if (realtime) {
if (dataKey.lastUpdateTime) {
- startTime = dataKey.lastUpdateTime + frequency
+ startTime = dataKey.lastUpdateTime + frequency;
+ endTime = dataKey.lastUpdateTime + deltaElapsed;
} else {
startTime = datasourceSubscription.subscriptionTimewindow.startTs;
+ endTime = startTime + datasourceSubscription.subscriptionTimewindow.realtimeWindowMs + frequency;
}
- endTime = startTime + datasourceSubscription.subscriptionTimewindow.realtimeWindowMs;
} else {
startTime = datasourceSubscription.subscriptionTimewindow.fixedWindow.startTimeMs;
endTime = datasourceSubscription.subscriptionTimewindow.fixedWindow.endTimeMs;
@@ -494,7 +525,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
}
if (!history) {
- timer = $timeout(function() {onTick(true)}, frequency / 2, false);
+ timer = $timeout(function() {onTick(true)}, frequency, false);
}
}
ui/src/app/widget/lib/google-map.js 31(+18 -13)
diff --git a/ui/src/app/widget/lib/google-map.js b/ui/src/app/widget/lib/google-map.js
index 027b145..100f1b3 100644
--- a/ui/src/app/widget/lib/google-map.js
+++ b/ui/src/app/widget/lib/google-map.js
@@ -246,26 +246,31 @@ export default class TbGoogleMap {
}
/* eslint-enable no-undef */
+ /* eslint-disable no-undef */
fitBounds(bounds) {
- var tbMap = this;
- google.maps.event.addListenerOnce(this.map, 'bounds_changed', function() { // eslint-disable-line no-undef
- var newZoomLevel = tbMap.map.getZoom();
- if (tbMap.dontFitMapBounds && tbMap.defaultZoomLevel) {
- newZoomLevel = tbMap.defaultZoomLevel;
- }
- tbMap.map.setZoom(newZoomLevel);
-
- if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
- tbMap.map.setZoom(tbMap.minZoomLevel);
- }
- });
- this.map.fitBounds(bounds);
+ if (this.dontFitMapBounds && this.defaultZoomLevel) {
+ this.map.setZoom(this.defaultZoomLevel);
+ this.map.setCenter(bounds.getCenter());
+ } else {
+ var tbMap = this;
+ google.maps.event.addListenerOnce(this.map, 'bounds_changed', function() { // eslint-disable-line no-undef
+ if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
+ tbMap.map.setZoom(tbMap.minZoomLevel);
+ }
+ });
+ this.map.fitBounds(bounds);
+ }
}
+ /* eslint-enable no-undef */
createLatLng(lat, lng) {
return new google.maps.LatLng(lat, lng); // eslint-disable-line no-undef
}
+ extendBoundsWithMarker(bounds, marker) {
+ bounds.extend(marker.getPosition());
+ }
+
getMarkerPosition(marker) {
return marker.getPosition();
}
ui/src/app/widget/lib/map-widget.js 10(+5 -5)
diff --git a/ui/src/app/widget/lib/map-widget.js b/ui/src/app/widget/lib/map-widget.js
index 52079f3..7402ee6 100644
--- a/ui/src/app/widget/lib/map-widget.js
+++ b/ui/src/app/widget/lib/map-widget.js
@@ -386,7 +386,7 @@ export default class TbMapWidget {
if (location.polyline) {
tbMap.map.extendBounds(bounds, location.polyline);
} else if (location.marker) {
- bounds.extend(tbMap.map.getMarkerPosition(location.marker));
+ tbMap.map.extendBoundsWithMarker(bounds, location.marker);
}
}
}
@@ -403,10 +403,10 @@ export default class TbMapWidget {
if (location.polyline) {
tbMap.map.extendBounds(bounds, location.polyline);
} else if (location.marker) {
- bounds.extend(tbMap.map.getMarkerPosition(location.marker));
+ tbMap.map.extendBoundsWithMarker(bounds, location.marker);
}
}
- if (!tbMap.dontFitMapBounds && locationsChanged) {
+ if (locationsChanged) {
tbMap.map.fitBounds(bounds);
}
}
@@ -448,10 +448,10 @@ export default class TbMapWidget {
resize() {
if (this.map && this.map.inited()) {
this.map.invalidateSize();
- if (!this.dontFitMapBounds && this.locations && this.locations.size > 0) {
+ if (this.locations && this.locations.size > 0) {
var bounds = this.map.createBounds();
for (var m in this.markers) {
- bounds.extend(this.map.getMarkerPosition(this.markers[m]));
+ this.map.extendBoundsWithMarker(bounds, this.markers[m]);
}
if (this.polylines) {
for (var p in this.polylines) {
ui/src/app/widget/lib/openstreet-map.js 29(+17 -12)
diff --git a/ui/src/app/widget/lib/openstreet-map.js b/ui/src/app/widget/lib/openstreet-map.js
index 4ebcf94..74438a4 100644
--- a/ui/src/app/widget/lib/openstreet-map.js
+++ b/ui/src/app/widget/lib/openstreet-map.js
@@ -146,25 +146,30 @@ export default class TbOpenStreetMap {
}
fitBounds(bounds) {
- var tbMap = this;
- this.map.once('zoomend', function() {
- var newZoomLevel = tbMap.map.getZoom();
- if (tbMap.dontFitMapBounds && tbMap.defaultZoomLevel) {
- newZoomLevel = tbMap.defaultZoomLevel;
- }
- tbMap.map.setZoom(newZoomLevel, {animate: false});
-
- if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
- tbMap.map.setZoom(tbMap.minZoomLevel, {animate: false});
+ if (bounds.isValid()) {
+ if (this.dontFitMapBounds && this.defaultZoomLevel) {
+ this.map.setZoom(this.defaultZoomLevel, {animate: false});
+ this.map.panTo(bounds.getCenter(), {animate: false});
+ } else {
+ var tbMap = this;
+ this.map.once('zoomend', function() {
+ if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
+ tbMap.map.setZoom(tbMap.minZoomLevel, {animate: false});
+ }
+ });
+ this.map.fitBounds(bounds, {padding: [50, 50], animate: false});
}
- });
- this.map.fitBounds(bounds, {padding: [50, 50], animate: false});
+ }
}
createLatLng(lat, lng) {
return L.latLng(lat, lng);
}
+ extendBoundsWithMarker(bounds, marker) {
+ bounds.extend(marker.getLatLng());
+ }
+
getMarkerPosition(marker) {
return marker.getLatLng();
}