diff --git a/application/pom.xml b/application/pom.xml index c11306448b..9364cfc16a 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT thingsboard org.thingsboard diff --git a/common/data/pom.xml b/common/data/pom.xml index bb23177339..ffee17c00d 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT common org.thingsboard.common diff --git a/common/message/pom.xml b/common/message/pom.xml index d3f770b303..5362f685ef 100644 --- a/common/message/pom.xml +++ b/common/message/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT common org.thingsboard.common diff --git a/common/pom.xml b/common/pom.xml index 6342c05962..798bec4ca7 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT thingsboard org.thingsboard diff --git a/common/transport/pom.xml b/common/transport/pom.xml index 9b66c2f46e..c5377563a1 100644 --- a/common/transport/pom.xml +++ b/common/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT common org.thingsboard.common diff --git a/dao/pom.xml b/dao/pom.xml index 83598ee2c8..cc3804feda 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT thingsboard org.thingsboard diff --git a/extensions-api/pom.xml b/extensions-api/pom.xml index 804333e265..87ad867e63 100644 --- a/extensions-api/pom.xml +++ b/extensions-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT thingsboard org.thingsboard diff --git a/extensions-core/pom.xml b/extensions-core/pom.xml index b1b874471e..923d474eca 100644 --- a/extensions-core/pom.xml +++ b/extensions-core/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT thingsboard org.thingsboard diff --git a/extensions/extension-kafka/pom.xml b/extensions/extension-kafka/pom.xml index 029c626061..6c35bd2cd9 100644 --- a/extensions/extension-kafka/pom.xml +++ b/extensions/extension-kafka/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT extensions org.thingsboard.extensions diff --git a/extensions/extension-rabbitmq/pom.xml b/extensions/extension-rabbitmq/pom.xml index 9f8da6919c..941165d794 100644 --- a/extensions/extension-rabbitmq/pom.xml +++ b/extensions/extension-rabbitmq/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT extensions org.thingsboard.extensions diff --git a/extensions/extension-rest-api-call/pom.xml b/extensions/extension-rest-api-call/pom.xml index 6a4e548a70..a732dc8040 100644 --- a/extensions/extension-rest-api-call/pom.xml +++ b/extensions/extension-rest-api-call/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT extensions org.thingsboard.extensions diff --git a/extensions/pom.xml b/extensions/pom.xml index ff3b14692f..2c1fdfe388 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT thingsboard org.thingsboard diff --git a/pom.xml b/pom.xml index f602b41974..fe95d9b9d9 100755 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard thingsboard - 1.2.3 + 1.3.0-SNAPSHOT pom Thingsboard diff --git a/tools/pom.xml b/tools/pom.xml index 67f0369ae8..2b83e13125 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT thingsboard org.thingsboard diff --git a/transport/coap/pom.xml b/transport/coap/pom.xml index eebfbaedd2..8f15edc027 100644 --- a/transport/coap/pom.xml +++ b/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/http/pom.xml b/transport/http/pom.xml index 0fa84c4e09..004c57eccd 100644 --- a/transport/http/pom.xml +++ b/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/mqtt/pom.xml b/transport/mqtt/pom.xml index aa7cfd3f82..2de70a7eb9 100644 --- a/transport/mqtt/pom.xml +++ b/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/pom.xml b/transport/pom.xml index f2b6ddde29..fb47647898 100644 --- a/transport/pom.xml +++ b/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT thingsboard org.thingsboard diff --git a/ui/package.json b/ui/package.json index ddcc96e4f7..73d7bcd347 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,7 +1,7 @@ { "name": "thingsboard", "private": true, - "version": "1.2.3", + "version": "1.3.0", "description": "Thingsboard UI", "licenses": [ { diff --git a/ui/pom.xml b/ui/pom.xml index cf5406d907..1efb29ac7c 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 1.2.3 + 1.3.0-SNAPSHOT thingsboard org.thingsboard diff --git a/ui/src/app/api/subscription.js b/ui/src/app/api/subscription.js index 633bcc36c5..fb774a1f0a 100644 --- a/ui/src/app/api/subscription.js +++ b/ui/src/app/api/subscription.js @@ -126,6 +126,7 @@ export default class Subscription { dataKey: dataKey, dataIndex: dataIndex++ }; + legendKey.dataKey.hidden = false; this.legendData.keys.push(legendKey); var legendKeyData = { min: null, @@ -146,11 +147,11 @@ export default class Subscription { this.legendData.keys = this.ctx.$filter('orderBy')(this.legendData.keys, '+label'); registration = this.ctx.$scope.$watch( function() { - return subscription.legendData.data; + return subscription.legendData.keys; }, function (newValue, oldValue) { for(var i = 0; i < newValue.length; i++) { - if(newValue[i].hidden != oldValue[i].hidden) { + if(newValue[i].dataKey.hidden != oldValue[i].dataKey.hidden) { subscription.updateDataVisibility(i); } } @@ -307,7 +308,7 @@ export default class Subscription { } updateDataVisibility(index) { - var hidden = this.legendData.data[index].hidden; + var hidden = this.legendData.keys[index].dataKey.hidden; if (hidden) { this.hiddenData[index].data = this.data[index].data; this.data[index].data = []; @@ -418,7 +419,7 @@ export default class Subscription { this.notifyDataLoaded(); var update = true; var currentData; - if (this.displayLegend && this.legendData.data[datasourceIndex + dataKeyIndex].hidden) { + if (this.displayLegend && this.legendData.keys[datasourceIndex + dataKeyIndex].dataKey.hidden) { currentData = this.hiddenData[datasourceIndex + dataKeyIndex]; } else { currentData = this.data[datasourceIndex + dataKeyIndex]; @@ -445,18 +446,21 @@ export default class Subscription { } updateLegend(dataIndex, data, apply) { + var dataKey = this.legendData.keys[dataIndex].dataKey; + var decimals = angular.isDefined(dataKey.decimals) ? dataKey.decimals : this.decimals; + var units = dataKey.units && dataKey.units.length ? dataKey.units : this.units; var legendKeyData = this.legendData.data[dataIndex]; if (this.legendConfig.showMin) { - legendKeyData.min = this.ctx.widgetUtils.formatValue(calculateMin(data), this.decimals, this.units); + legendKeyData.min = this.ctx.widgetUtils.formatValue(calculateMin(data), decimals, units); } if (this.legendConfig.showMax) { - legendKeyData.max = this.ctx.widgetUtils.formatValue(calculateMax(data), this.decimals, this.units); + legendKeyData.max = this.ctx.widgetUtils.formatValue(calculateMax(data), decimals, units); } if (this.legendConfig.showAvg) { - legendKeyData.avg = this.ctx.widgetUtils.formatValue(calculateAvg(data), this.decimals, this.units); + legendKeyData.avg = this.ctx.widgetUtils.formatValue(calculateAvg(data), decimals, units); } if (this.legendConfig.showTotal) { - legendKeyData.total = this.ctx.widgetUtils.formatValue(calculateTotal(data), this.decimals, this.units); + legendKeyData.total = this.ctx.widgetUtils.formatValue(calculateTotal(data), decimals, units); } this.callbacks.legendDataUpdated(this, apply !== false); } diff --git a/ui/src/app/components/datakey-config.directive.js b/ui/src/app/components/datakey-config.directive.js index 9b3081ecef..90810afeb2 100644 --- a/ui/src/app/components/datakey-config.directive.js +++ b/ui/src/app/components/datakey-config.directive.js @@ -76,6 +76,8 @@ function DatakeyConfig($compile, $templateCache, $q, types) { scope.model.name = ngModelCtrl.$viewValue.name; scope.model.label = ngModelCtrl.$viewValue.label; scope.model.color = ngModelCtrl.$viewValue.color; + scope.model.units = ngModelCtrl.$viewValue.units; + scope.model.decimals = ngModelCtrl.$viewValue.decimals; scope.model.funcBody = ngModelCtrl.$viewValue.funcBody; scope.model.postFuncBody = ngModelCtrl.$viewValue.postFuncBody; scope.model.usePostProcessing = scope.model.postFuncBody ? true : false; @@ -97,6 +99,8 @@ function DatakeyConfig($compile, $templateCache, $q, types) { value.name = scope.model.name; value.label = scope.model.label; value.color = scope.model.color; + value.units = scope.model.units; + value.decimals = scope.model.decimals; value.funcBody = scope.model.funcBody; if (!scope.model.postFuncBody) { delete value.postFuncBody; diff --git a/ui/src/app/components/datakey-config.tpl.html b/ui/src/app/components/datakey-config.tpl.html index f170220883..755c4f49a8 100644 --- a/ui/src/app/components/datakey-config.tpl.html +++ b/ui/src/app/components/datakey-config.tpl.html @@ -48,6 +48,16 @@ md-color-history="false"> +
+ + + + + + + + +
datakey.data-generation-func
diff --git a/ui/src/app/components/legend.directive.js b/ui/src/app/components/legend.directive.js index 196629cde6..39c8e58712 100644 --- a/ui/src/app/components/legend.directive.js +++ b/ui/src/app/components/legend.directive.js @@ -45,7 +45,7 @@ function Legend($compile, $templateCache, types) { scope.legendConfig.position === types.position.top.value; scope.toggleHideData = function(index) { - scope.legendData.data[index].hidden = !scope.legendData.data[index].hidden; + scope.legendData.keys[index].dataKey.hidden = !scope.legendData.keys[index].dataKey.hidden; } $compile(element.contents())(scope); diff --git a/ui/src/app/components/legend.tpl.html b/ui/src/app/components/legend.tpl.html index 8350320499..18c91377e0 100644 --- a/ui/src/app/components/legend.tpl.html +++ b/ui/src/app/components/legend.tpl.html @@ -30,7 +30,7 @@ + ng-class="{ 'tb-hidden-label': legendData.keys[legendKey.dataIndex].dataKey.hidden, 'tb-horizontal': isHorizontal }"> {{ legendKey.dataKey.label }} {{ legendData.data[legendKey.dataIndex].min }} diff --git a/ui/src/app/components/widget-config.directive.js b/ui/src/app/components/widget-config.directive.js index 122889d4c1..c3793be294 100644 --- a/ui/src/app/components/widget-config.directive.js +++ b/ui/src/app/components/widget-config.directive.js @@ -355,10 +355,10 @@ function WidgetConfig($compile, $templateCache, $rootScope, $timeout, types, uti var matches = false; do { matches = false; - if (value.datasources) { - for (var d in value.datasources) { - var datasource = value.datasources[d]; - for (var k in datasource.dataKeys) { + if (value.config.datasources) { + for (var d=0;d + ng-model="vm.dashboardCtx.dashboardTimewindow"> 0 ? settings.units : ctx.units; + } + } + + function getValueDec(settings) { + var dataKey; + if (ctx.data && ctx.data[0]) { + dataKey = ctx.data[0].dataKey; + } + if (dataKey && angular.isDefined(dataKey.decimals)) { + return dataKey.decimals; + } else { + return (angular.isDefined(settings.valueDec) && settings.valueDec !== null) + ? settings.valueDec : ctx.decimals; + } + } + + function getFontFamily(fontSettings) { var family = fontSettings && fontSettings.family ? fontSettings.family : 'Roboto'; if (family === 'RobotoDraft') { @@ -92,7 +117,7 @@ export default class TbAnalogueLinearGauge { maxValue: maxValue, majorTicks: majorTicks, minorTicks: settings.minorTicks || 2, - units: angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units, + units: getUnits(settings), title: ((settings.showUnitTitle !== false) ? (settings.unitTitle && settings.unitTitle.length > 0 ? settings.unitTitle : dataKey.label) : ''), diff --git a/ui/src/app/widget/lib/analogue-radial-gauge.js b/ui/src/app/widget/lib/analogue-radial-gauge.js index 3a526bd3d1..76a2c383aa 100644 --- a/ui/src/app/widget/lib/analogue-radial-gauge.js +++ b/ui/src/app/widget/lib/analogue-radial-gauge.js @@ -42,8 +42,7 @@ export default class TbAnalogueRadialGauge { var valueInt = settings.valueInt || 3; - var valueDec = (angular.isDefined(settings.valueDec) && settings.valueDec !== null) - ? settings.valueDec : ctx.decimals; + var valueDec = getValueDec(settings); step = parseFloat(parseFloat(step).toFixed(valueDec)); @@ -71,6 +70,31 @@ export default class TbAnalogueRadialGauge { var colorNumbers = tinycolor(keyColor).darken(20).toRgbString(); + function getUnits(settings) { + var dataKey; + if (ctx.data && ctx.data[0]) { + dataKey = ctx.data[0].dataKey; + } + if (dataKey && dataKey.units && dataKey.units.length) { + return dataKey.units; + } else { + return angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units; + } + } + + function getValueDec(settings) { + var dataKey; + if (ctx.data && ctx.data[0]) { + dataKey = ctx.data[0].dataKey; + } + if (dataKey && angular.isDefined(dataKey.decimals)) { + return dataKey.decimals; + } else { + return (angular.isDefined(settings.valueDec) && settings.valueDec !== null) + ? settings.valueDec : ctx.decimals; + } + } + function getFontFamily(fontSettings) { var family = fontSettings && fontSettings.family ? fontSettings.family : 'Roboto'; if (family === 'RobotoDraft') { @@ -89,7 +113,7 @@ export default class TbAnalogueRadialGauge { maxValue: maxValue, majorTicks: majorTicks, minorTicks: settings.minorTicks || 2, - units: angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units, + units: getUnits(settings), title: ((settings.showUnitTitle !== false) ? (settings.unitTitle && settings.unitTitle.length > 0 ? settings.unitTitle : dataKey.label) : ''), diff --git a/ui/src/app/widget/lib/canvas-digital-gauge.js b/ui/src/app/widget/lib/canvas-digital-gauge.js index 33283ef693..1290f5f344 100644 --- a/ui/src/app/widget/lib/canvas-digital-gauge.js +++ b/ui/src/app/widget/lib/canvas-digital-gauge.js @@ -54,10 +54,13 @@ export default class TbCanvasDigitalGauge { this.localSettings.levelColors = settings.levelColors.slice(); } - this.localSettings.decimals = (angular.isDefined(settings.decimals) && settings.decimals !== null) - ? settings.decimals : ctx.decimals; + this.localSettings.decimals = angular.isDefined(dataKey.decimals) ? dataKey.decimals : + ((angular.isDefined(settings.decimals) && settings.decimals !== null) + ? settings.decimals : ctx.decimals); + + this.localSettings.units = dataKey.units && dataKey.units.length ? dataKey.units : + (angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units); - this.localSettings.units = angular.isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units; this.localSettings.hideValue = settings.showValue !== true; this.localSettings.hideMinMax = settings.showMinMax !== true; diff --git a/ui/src/app/widget/lib/flot-widget.js b/ui/src/app/widget/lib/flot-widget.js index af70de184b..56eb278d1d 100644 --- a/ui/src/app/widget/lib/flot-widget.js +++ b/ui/src/app/widget/lib/flot-widget.js @@ -104,8 +104,10 @@ export default class TbFlot { if (this.chartType === 'pie') { ctx.tooltipFormatter = function(item) { + var units = item.series.dataKey.units && item.series.dataKey.units.length ? item.series.dataKey.units : tbFlot.ctx.trackUnits; + var decimals = angular.isDefined(item.series.dataKey.decimals) ? item.series.dataKey.decimals : tbFlot.ctx.trackDecimals; var divElement = seriesInfoDiv(item.series.dataKey.label, item.series.dataKey.color, - item.datapoint[1][0][1], tbFlot.ctx.trackUnits, tbFlot.ctx.trackDecimals, true, item.series.percent); + item.datapoint[1][0][1], units, decimals, true, item.series.percent); return divElement.prop('outerHTML'); }; } else { @@ -127,18 +129,19 @@ export default class TbFlot { if (tbFlot.ctx.tooltipIndividual && seriesHoverInfo.index !== seriesIndex) { continue; } + var units = seriesHoverInfo.units && seriesHoverInfo.units.length ? seriesHoverInfo.units : tbFlot.ctx.trackUnits; + var decimals = angular.isDefined(seriesHoverInfo.decimals) ? seriesHoverInfo.decimals : tbFlot.ctx.trackDecimals; var divElement = seriesInfoDiv(seriesHoverInfo.label, seriesHoverInfo.color, - seriesHoverInfo.value, tbFlot.ctx.trackUnits, tbFlot.ctx.trackDecimals, seriesHoverInfo.index === seriesIndex); + seriesHoverInfo.value, units, decimals, seriesHoverInfo.index === seriesIndex); content += divElement.prop('outerHTML'); } return content; }; } - ctx.trackDecimals = angular.isDefined(settings.decimals) ? - settings.decimals : ctx.decimals; + ctx.trackDecimals = ctx.decimals; - ctx.trackUnits = angular.isDefined(settings.units) ? settings.units : ctx.units; + ctx.trackUnits = ctx.units; ctx.tooltipIndividual = this.chartType === 'pie' || (angular.isDefined(settings.tooltipIndividual) ? settings.tooltipIndividual : false); ctx.tooltipCumulative = angular.isDefined(settings.tooltipCumulative) ? settings.tooltipCumulative : false; @@ -172,7 +175,7 @@ export default class TbFlot { font: angular.copy(font), labelFont: angular.copy(font) }; - options.yaxis = { + this.yaxis = { font: angular.copy(font), labelFont: angular.copy(font) }; @@ -188,32 +191,33 @@ export default class TbFlot { options.xaxis.labelFont.size = options.xaxis.font.size+2; options.xaxis.labelFont.weight = "bold"; } - if (settings.yaxis) { + + ctx.yAxisTickFormatter = function(value/*, axis*/) { if (settings.yaxis.showLabels === false) { - options.yaxis.tickFormatter = function() { - return ''; - }; - } else if (ctx.trackUnits && ctx.trackUnits.length > 0) { - options.yaxis.tickFormatter = function(value, axis) { - var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1, - formatted = "" + Math.round(value * factor) / factor; - if (axis.tickDecimals != null) { - var decimal = formatted.indexOf("."), - precision = decimal === -1 ? 0 : formatted.length - decimal - 1; - - if (precision < axis.tickDecimals) { - formatted = (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision); - } - } - formatted += ' ' + tbFlot.ctx.trackUnits; - return formatted; - }; + return ''; + } + var factor = this.tickDecimals ? Math.pow(10, this.tickDecimals) : 1, + formatted = "" + Math.round(value * factor) / factor; + if (this.tickDecimals != null) { + var decimal = formatted.indexOf("."), + precision = decimal === -1 ? 0 : formatted.length - decimal - 1; + + if (precision < this.tickDecimals) { + formatted = (precision ? formatted : formatted + ".") + ("" + factor).substr(1, this.tickDecimals - precision); + } } - options.yaxis.font.color = settings.yaxis.color || options.yaxis.font.color; - options.yaxis.label = settings.yaxis.title || null; - options.yaxis.labelFont.color = options.yaxis.font.color; - options.yaxis.labelFont.size = options.yaxis.font.size+2; - options.yaxis.labelFont.weight = "bold"; + formatted += ' ' + this.tickUnits; + return formatted; + } + + this.yaxis.tickFormatter = ctx.yAxisTickFormatter; + + if (settings.yaxis) { + this.yaxis.font.color = settings.yaxis.color || this.yaxis.font.color; + this.yaxis.label = settings.yaxis.title || null; + this.yaxis.labelFont.color = this.yaxis.font.color; + this.yaxis.labelFont.size = this.yaxis.font.size+2; + this.yaxis.labelFont.weight = "bold"; } options.grid.borderWidth = 1; @@ -229,7 +233,7 @@ export default class TbFlot { options.xaxis.tickLength = 0; } if (settings.grid.horizontalLines === false) { - options.yaxis.tickLength = 0; + this.yaxis.tickLength = 0; } } @@ -311,6 +315,8 @@ export default class TbFlot { this.subscription = subscription; this.$element = $element; var colors = []; + this.yaxes = []; + var yaxesMap = {}; for (var i = 0; i < this.subscription.data.length; i++) { var series = this.subscription.data[i]; colors.push(series.dataKey.color); @@ -342,8 +348,29 @@ export default class TbFlot { series.highlightColor = lineColor.toRgbString(); + if (this.yaxis) { + var units = series.dataKey.units && series.dataKey.units.length ? series.dataKey.units : this.ctx.trackUnits; + var yaxis; + if (keySettings.showSeparateAxis) { + yaxis = this.createYAxis(keySettings, units); + this.yaxes.push(yaxis); + } else { + yaxis = yaxesMap[units]; + if (!yaxis) { + yaxis = this.createYAxis(keySettings, units); + yaxesMap[units] = yaxis; + this.yaxes.push(yaxis); + } + } + series.yaxisIndex = this.yaxes.indexOf(yaxis); + series.yaxis = series.yaxisIndex+1; + yaxis.keysInfo[i] = {hidden: false}; + yaxis.hidden = false; + } } + this.options.colors = colors; + this.options.yaxes = angular.copy(this.yaxes); if (this.chartType === 'line' || this.chartType === 'bar') { if (this.chartType === 'bar') { this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6; @@ -373,6 +400,23 @@ export default class TbFlot { } } + createYAxis(keySettings, units) { + var yaxis = angular.copy(this.yaxis); + + var label = keySettings.axisTitle && keySettings.axisTitle.length ? keySettings.axisTitle : yaxis.label; + var tickDecimals = angular.isDefined(keySettings.axisTickDecimals) ? keySettings.axisTickDecimals : 0; + var position = keySettings.axisPosition && keySettings.axisPosition.length ? keySettings.axisPosition : "left"; + + yaxis.label = label; + yaxis.tickUnits = units; + yaxis.tickDecimals = tickDecimals; + yaxis.alignTicksWithAxis = position == "right" ? 1 : null; + yaxis.position = position; + + yaxis.keysInfo = []; + return yaxis; + } + update() { if (this.updateTimeoutHandle) { this.ctx.$scope.$timeout.cancel(this.updateTimeoutHandle); @@ -381,17 +425,64 @@ export default class TbFlot { if (this.subscription) { if (!this.isMouseInteraction && this.ctx.plot) { if (this.chartType === 'line' || this.chartType === 'bar') { + + var axisVisibilityChanged = false; + if (this.yaxis) { + for (var i = 0; i < this.subscription.data.length; i++) { + var series = this.subscription.data[i]; + var yaxisIndex = series.yaxisIndex; + if (this.yaxes[yaxisIndex].keysInfo[i].hidden != series.dataKey.hidden) { + this.yaxes[yaxisIndex].keysInfo[i].hidden = series.dataKey.hidden; + axisVisibilityChanged = true; + } + } + if (axisVisibilityChanged) { + this.options.yaxes.length = 0; + for (var y = 0; y < this.yaxes.length; y++) { + var yaxis = this.yaxes[y]; + var hidden = true; + for (var k = 0; k < yaxis.keysInfo.length; k++) { + if (yaxis.keysInfo[k]) { + hidden = hidden && yaxis.keysInfo[k].hidden; + } + } + yaxis.hidden = hidden + var newIndex = -1; + if (!yaxis.hidden) { + this.options.yaxes.push(yaxis); + newIndex = this.options.yaxes.length; + } + for (k = 0; k < yaxis.keysInfo.length; k++) { + if (yaxis.keysInfo[k]) { + this.subscription.data[k].yaxis = newIndex; + } + } + + } + this.options.yaxis = { + show: this.options.yaxes.length ? true : false + }; + } + } + this.options.xaxis.min = this.subscription.timeWindow.minTime; this.options.xaxis.max = this.subscription.timeWindow.maxTime; - this.ctx.plot.getOptions().xaxes[0].min = this.subscription.timeWindow.minTime; - this.ctx.plot.getOptions().xaxes[0].max = this.subscription.timeWindow.maxTime; if (this.chartType === 'bar') { this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6; - this.ctx.plot.getOptions().series.bars.barWidth = this.subscription.timeWindow.interval * 0.6; } - this.ctx.plot.setData(this.subscription.data); - this.ctx.plot.setupGrid(); - this.ctx.plot.draw(); + + if (axisVisibilityChanged) { + this.redrawPlot(); + } else { + this.ctx.plot.getOptions().xaxes[0].min = this.subscription.timeWindow.minTime; + this.ctx.plot.getOptions().xaxes[0].max = this.subscription.timeWindow.maxTime; + if (this.chartType === 'bar') { + this.ctx.plot.getOptions().series.bars.barWidth = this.subscription.timeWindow.interval * 0.6; + } + this.ctx.plot.setData(this.subscription.data); + this.ctx.plot.setupGrid(); + this.ctx.plot.draw(); + } } else if (this.chartType === 'pie') { if (this.ctx.animatedPie) { this.nextPieDataAnimation(true); @@ -720,6 +811,26 @@ export default class TbFlot { "title": "Show points", "type": "boolean", "default": false + }, + "showSeparateAxis": { + "title": "Show separate axis", + "type": "boolean", + "default": false + }, + "axisTitle": { + "title": "Axis title", + "type": "string", + "default": "" + }, + "axisTickDecimals": { + "title": "Axis tick number of digits after floating point", + "type": "number", + "default": 0 + }, + "axisPosition": { + "title": "Axis position", + "type": "string", + "default": "left" } }, "required": ["showLines", "fillLines", "showPoints"] @@ -727,7 +838,26 @@ export default class TbFlot { "form": [ "showLines", "fillLines", - "showPoints" + "showPoints", + "showSeparateAxis", + "axisTitle", + "axisTickDecimals", + { + "key": "axisPosition", + "type": "rc-select", + "multiple": false, + "items": [ + { + "value": "left", + "label": "Left" + }, + { + "value": "right", + "label": "Right" + } + ] + } + ] } } @@ -754,6 +884,17 @@ export default class TbFlot { } } + redrawPlot() { + if (this.ctx.plot) { + this.ctx.plot.destroy(); + if (this.chartType === 'pie' && this.ctx.animatedPie) { + this.ctx.plot = $.plot(this.$element, this.pieData, this.options); + } else { + this.ctx.plot = $.plot(this.$element, this.subscription.data, this.options); + } + } + } + destroy() { if (this.ctx.plot) { this.ctx.plot.destroy(); @@ -968,6 +1109,8 @@ export default class TbFlot { hoverIndex: hoverIndex, color: series.dataKey.color, label: series.dataKey.label, + units: series.dataKey.units, + decimals: series.dataKey.decimals, time: pointTime, distance: hoverDistance, index: i