Browse Source

Features/flot thresholds (#2412)

* Thresholds draft

* Make generated thresholds unique

* Code refactoring
pull/2434/head
Chantsova Ekaterina 7 years ago
committed by GitHub
parent
commit
37173bba10
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 210
      ui/src/app/widget/lib/flot-widget.js

210
ui/src/app/widget/lib/flot-widget.js

@ -33,7 +33,8 @@ export default class TbFlot {
this.ctx = ctx; this.ctx = ctx;
this.chartType = chartType || 'line'; this.chartType = chartType || 'line';
var settings = ctx.settings; var settings = ctx.settings;
var utils = this.ctx.$scope.$injector.get('utils'); this.utils = this.ctx.$scope.$injector.get('utils');
this.types = this.ctx.$scope.$injector.get('types');
ctx.tooltip = $('#flot-series-tooltip'); ctx.tooltip = $('#flot-series-tooltip');
if (ctx.tooltip.length === 0) { if (ctx.tooltip.length === 0) {
@ -242,7 +243,8 @@ export default class TbFlot {
grid: { grid: {
hoverable: true, hoverable: true,
mouseActiveRadius: 10, mouseActiveRadius: 10,
autoHighlight: ctx.tooltipIndividual === true autoHighlight: ctx.tooltipIndividual === true,
markings: []
}, },
selection : { mode : ctx.isMobile ? null : 'x' }, selection : { mode : ctx.isMobile ? null : 'x' },
legend : { legend : {
@ -264,7 +266,7 @@ export default class TbFlot {
}; };
if (settings.xaxis) { if (settings.xaxis) {
this.xaxis.font.color = settings.xaxis.color || this.xaxis.font.color; this.xaxis.font.color = settings.xaxis.color || this.xaxis.font.color;
this.xaxis.label = utils.customTranslation(settings.xaxis.title, settings.xaxis.title) || null; this.xaxis.label = this.utils.customTranslation(settings.xaxis.title, settings.xaxis.title) || null;
this.xaxis.labelFont.color = this.xaxis.font.color; this.xaxis.labelFont.color = this.xaxis.font.color;
this.xaxis.labelFont.size = this.xaxis.font.size+2; this.xaxis.labelFont.size = this.xaxis.font.size+2;
this.xaxis.labelFont.weight = "bold"; this.xaxis.labelFont.weight = "bold";
@ -301,7 +303,7 @@ export default class TbFlot {
this.yaxis.font.color = settings.yaxis.color || this.yaxis.font.color; this.yaxis.font.color = settings.yaxis.color || this.yaxis.font.color;
this.yaxis.min = angular.isDefined(settings.yaxis.min) ? settings.yaxis.min : null; this.yaxis.min = angular.isDefined(settings.yaxis.min) ? settings.yaxis.min : null;
this.yaxis.max = angular.isDefined(settings.yaxis.max) ? settings.yaxis.max : null; this.yaxis.max = angular.isDefined(settings.yaxis.max) ? settings.yaxis.max : null;
this.yaxis.label = utils.customTranslation(settings.yaxis.title, settings.yaxis.title) || null; this.yaxis.label = this.utils.customTranslation(settings.yaxis.title, settings.yaxis.title) || null;
this.yaxis.labelFont.color = this.yaxis.font.color; this.yaxis.labelFont.color = this.yaxis.font.color;
this.yaxis.labelFont.size = this.yaxis.font.size+2; this.yaxis.labelFont.size = this.yaxis.font.size+2;
this.yaxis.labelFont.weight = "bold"; this.yaxis.labelFont.weight = "bold";
@ -364,7 +366,7 @@ export default class TbFlot {
return ''; return '';
}; };
} }
xaxis.label = utils.customTranslation(settings.xaxisSecond.title, settings.xaxisSecond.title) || null; xaxis.label = this.utils.customTranslation(settings.xaxisSecond.title, settings.xaxisSecond.title) || null;
xaxis.position = settings.xaxisSecond.axisPosition; xaxis.position = settings.xaxisSecond.axisPosition;
} }
xaxis.tickLength = 0; xaxis.tickLength = 0;
@ -390,6 +392,10 @@ export default class TbFlot {
} }
} }
if (this.chartType === 'line' && isFinite(settings.thresholdsLineWidth)) {
options.grid.markingsLineWidth = settings.thresholdsLineWidth;
}
if (this.chartType === 'bar') { if (this.chartType === 'bar') {
options.series.lines = { options.series.lines = {
show: false, show: false,
@ -471,6 +477,7 @@ export default class TbFlot {
var colors = []; var colors = [];
this.yaxes = []; this.yaxes = [];
var yaxesMap = {}; var yaxesMap = {};
let predefinedThresholds = [], thresholdsDatasources = [];
var tooltipValueFormatFunction = null; var tooltipValueFormatFunction = null;
if (this.ctx.settings.tooltipValueFormatter && this.ctx.settings.tooltipValueFormatter.length) { if (this.ctx.settings.tooltipValueFormatter && this.ctx.settings.tooltipValueFormatter.length) {
@ -485,6 +492,7 @@ export default class TbFlot {
var series = this.subscription.data[i]; var series = this.subscription.data[i];
colors.push(series.dataKey.color); colors.push(series.dataKey.color);
var keySettings = series.dataKey.settings; var keySettings = series.dataKey.settings;
series.dataKey.tooltipValueFormatFunction = tooltipValueFormatFunction; series.dataKey.tooltipValueFormatFunction = tooltipValueFormatFunction;
if (keySettings.tooltipValueFormatter && keySettings.tooltipValueFormatter.length) { if (keySettings.tooltipValueFormatter && keySettings.tooltipValueFormatter.length) {
try { try {
@ -570,9 +578,58 @@ export default class TbFlot {
series.yaxis = series.yaxisIndex+1; series.yaxis = series.yaxisIndex+1;
yaxis.keysInfo[i] = {hidden: false}; yaxis.keysInfo[i] = {hidden: false};
yaxis.show = true; yaxis.show = true;
if (keySettings.thresholds && keySettings.thresholds.length) {
for (let j = 0; j < keySettings.thresholds.length; j++) {
let threshold = keySettings.thresholds[j];
if (threshold.thresholdValueSource === 'predefinedValue' && isFinite(threshold.thresholdValue)) {
let colorIndex = this.subscription.data.length + predefinedThresholds.length;
this.generateThreshold(predefinedThresholds, series.yaxis, threshold.lineWidth, threshold.color, colorIndex, threshold.thresholdValue);
} else if (threshold.thresholdEntityAlias && threshold.thresholdAttribute) {
let entityAliasId = this.ctx.aliasController.getEntityAliasId(threshold.thresholdEntityAlias);
if (!entityAliasId) {
continue;
}
let datasource = thresholdsDatasources.filter((datasource) => {
return datasource.entityAliasId === entityAliasId;
})[0];
let dataKey = {
type: this.types.dataKeyType.attribute,
name: threshold.thresholdAttribute,
label: threshold.thresholdAttribute,
settings: {
yaxis: series.yaxis,
lineWidth: threshold.lineWidth,
color: threshold.color
},
_hash: Math.random()
};
if (datasource) {
datasource.dataKeys.push(dataKey);
} else {
datasource = {
type: this.types.datasourceType.entity,
name: threshold.thresholdEntityAlias,
aliasName: threshold.thresholdEntityAlias,
entityAliasId: entityAliasId,
dataKeys: [ dataKey ]
};
thresholdsDatasources.push(datasource);
}
}
}
}
} }
} }
this.subscribeForThresholdsAttributes(thresholdsDatasources);
this.options.grid.markings = predefinedThresholds;
this.predefinedThresholds = predefinedThresholds;
this.options.colors = colors; this.options.colors = colors;
this.options.yaxes = angular.copy(this.yaxes); this.options.yaxes = angular.copy(this.yaxes);
if (this.chartType === 'line' || this.chartType === 'bar' || this.chartType === 'state') { if (this.chartType === 'line' || this.chartType === 'bar' || this.chartType === 'state') {
@ -657,6 +714,74 @@ export default class TbFlot {
return yaxis; return yaxis;
} }
subscribeForThresholdsAttributes(datasources) {
let tbFlot = this;
let thresholdsSourcesSubscriptionOptions = {
datasources: datasources,
useDashboardTimewindow: false,
type: this.types.widgetType.latest.value,
callbacks: {
onDataUpdated: (subscription) => {tbFlot.thresholdsSourcesDataUpdated(subscription.data)}
}
};
this.ctx.subscriptionApi.createSubscription(thresholdsSourcesSubscriptionOptions, true).then(
(subscription) => {
tbFlot.thresholdsSourcesSubscription = subscription;
}
);
}
thresholdsSourcesDataUpdated(data) {
let allThresholds = angular.copy(this.predefinedThresholds);
for (let i = 0; i < data.length; i++) {
let keyData = data[i];
if (keyData && keyData.data && keyData.data[0]) {
let attrValue = keyData.data[0][1];
if (isFinite(attrValue)) {
let settings = keyData.dataKey.settings;
let colorIndex = this.subscription.data.length + allThresholds.length;
this.generateThreshold(allThresholds, settings.yaxis, settings.lineWidth, settings.color, colorIndex, attrValue);
}
}
}
this.options.grid.markings = allThresholds;
this.redrawPlot();
}
generateThreshold(existingThresholds, yaxis, lineWidth, color, defaultColorIndex, thresholdValue) {
let marking = {};
let markingYAxis;
if (yaxis !== 1) {
markingYAxis = 'y' + yaxis + 'axis';
} else {
markingYAxis = 'yaxis';
}
if (isFinite(lineWidth)) {
marking.lineWidth = lineWidth;
}
if (angular.isDefined(color)) {
marking.color = color;
} else {
marking.color = this.utils.getMaterialColor(defaultColorIndex);
}
marking[markingYAxis] = {
from: thresholdValue,
to: thresholdValue
};
let similarMarkings = existingThresholds.filter((existingMarking) => {
return angular.equals(existingMarking[markingYAxis], marking[markingYAxis]);
});
if (!similarMarkings.length) {
existingThresholds.push(marking);
}
}
update() { update() {
if (this.updateTimeoutHandle) { if (this.updateTimeoutHandle) {
this.ctx.$scope.$timeout.cancel(this.updateTimeoutHandle); this.ctx.$scope.$timeout.cancel(this.updateTimeoutHandle);
@ -982,6 +1107,12 @@ export default class TbFlot {
"default": "left" "default": "left"
}; };
} }
if (chartType === 'graph' || chartType === 'bar') {
properties["thresholdsLineWidth"] = {
"title": "Default line width for all thresholds",
"type": "number"
};
}
properties["shadowSize"] = { properties["shadowSize"] = {
"title": "Shadow size", "title": "Shadow size",
"type": "number", "type": "number",
@ -1151,6 +1282,9 @@ export default class TbFlot {
] ]
}); });
} }
if (chartType === 'graph' || chartType === 'bar') {
schema["form"].push("thresholdsLineWidth");
}
schema["form"].push("shadowSize"); schema["form"].push("shadowSize");
schema["form"].push({ schema["form"].push({
"key": "fontColor", "key": "fontColor",
@ -1456,7 +1590,73 @@ export default class TbFlot {
}; };
var properties = schema["schema"]["properties"]; var properties = schema["schema"]["properties"];
if (chartType === 'graph' || chartType === 'bar') { if (chartType === 'graph' || chartType === 'bar') {
properties["thresholds"] = {
"title": "Thresholds",
"type": "array",
"items": {
"title": "Threshold",
"type": "object",
"properties": {
"thresholdValueSource": {
"title": "Threshold value source",
"type": "string",
"default": "predefinedValue"
},
"thresholdEntityAlias": {
"title": "Thresholds source entity alias",
"type": "string"
},
"thresholdAttribute": {
"title": "Threshold source entity attribute",
"type": "string"
},
"thresholdValue": {
"title": "Threshold value (if predefined value is selected)",
"type": "number"
},
"lineWidth": {
"title": "Line width",
"type": "number"
},
"color": {
"title": "Color",
"type": "string"
}
}
},
"required": []
};
schema["form"].push({
"key": "thresholds",
"items": [
{
"key": "thresholds[].thresholdValueSource",
"type": "rc-select",
"multiple": false,
"items": [
{
"value": "predefinedValue",
"label": "Predefined value (Default)"
},
{
"value": "entityAttribute",
"label": "Value taken from entity attribute"
}
]
},
"thresholds[].thresholdValue",
"thresholds[].thresholdEntityAlias",
"thresholds[].thresholdAttribute",
{
"key": "thresholds[].color",
"type": "color"
},
"thresholds[].lineWidth"
]
});
properties["comparisonSettings"] = { properties["comparisonSettings"] = {
"title": "Comparison Settings", "title": "Comparison Settings",
"type": "object", "type": "object",

Loading…
Cancel
Save