Browse Source

UI: Improve data simulation performance. Improve processing of default zoom level by map widgets.

pull/78/head
Igor Kulikov 10 years ago
parent
commit
5f606912fc
  1. 59
      ui/src/app/api/data-aggregator.js
  2. 39
      ui/src/app/api/datasource.service.js
  3. 31
      ui/src/app/widget/lib/google-map.js
  4. 10
      ui/src/app/widget/lib/map-widget.js
  5. 29
      ui/src/app/widget/lib/openstreet-map.js

59
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);

39
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);
}
}

31
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();
}

10
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) {

29
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();
}

Loading…
Cancel
Save