Commit 87403999 by Torkel Ödegaard Committed by GitHub

BarGauge: Fix for negative min values (#17192)

parent fa9ffe38
...@@ -48,39 +48,39 @@ ...@@ -48,39 +48,39 @@
"y": 0 "y": 0
}, },
"headings": false, "headings": false,
"id": 8, "id": 2,
"limit": 1000, "limit": 1000,
"links": [], "links": [],
"query": "", "query": "",
"recent": false, "recent": false,
"search": true, "search": true,
"starred": false, "starred": false,
"tags": ["panel-demo"], "tags": ["panel-tests"],
"timeFrom": null, "timeFrom": null,
"timeShift": null, "timeShift": null,
"title": "tag: panel-demo", "title": "tag: panel-tests",
"type": "dashlist" "type": "dashlist"
}, },
{ {
"folderId": null, "folderId": null,
"gridPos": { "gridPos": {
"h": 13, "h": 26,
"w": 6, "w": 6,
"x": 12, "x": 12,
"y": 0 "y": 0
}, },
"headings": false, "headings": false,
"id": 2, "id": 3,
"limit": 1000, "limit": 1000,
"links": [], "links": [],
"query": "", "query": "",
"recent": false, "recent": false,
"search": true, "search": true,
"starred": false, "starred": false,
"tags": ["panel-tests"], "tags": ["gdev", "demo"],
"timeFrom": null, "timeFrom": null,
"timeShift": null, "timeShift": null,
"title": "tag: panel-tests", "title": "tag: dashboard-demo",
"type": "dashlist" "type": "dashlist"
}, },
{ {
...@@ -114,28 +114,6 @@ ...@@ -114,28 +114,6 @@
"y": 13 "y": 13
}, },
"headings": false, "headings": false,
"id": 3,
"limit": 1000,
"links": [],
"query": "",
"recent": false,
"search": true,
"starred": false,
"tags": ["gdev", "demo"],
"timeFrom": null,
"timeShift": null,
"title": "tag: dashboard-demo",
"type": "dashlist"
},
{
"folderId": null,
"gridPos": {
"h": 13,
"w": 6,
"x": 12,
"y": 13
},
"headings": false,
"id": 4, "id": 4,
"limit": 1000, "limit": 1000,
"links": [], "links": [],
...@@ -146,7 +124,7 @@ ...@@ -146,7 +124,7 @@
"tags": ["templating", "gdev"], "tags": ["templating", "gdev"],
"timeFrom": null, "timeFrom": null,
"timeShift": null, "timeShift": null,
"title": "tag: templating", "title": "tag: templating ",
"type": "dashlist" "type": "dashlist"
} }
], ],
...@@ -167,5 +145,5 @@ ...@@ -167,5 +145,5 @@
"timezone": "", "timezone": "",
"title": "Grafana Dev Overview & Home", "title": "Grafana Dev Overview & Home",
"uid": "j6T00KRZz", "uid": "j6T00KRZz",
"version": 1 "version": 2
} }
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"links": [],
"panels": [
{
"gridPos": {
"h": 7,
"w": 18,
"x": 0,
"y": 0
},
"id": 7,
"links": [],
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"max": 100,
"min": 0,
"unit": "watt"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "green",
"index": 0,
"value": null
},
{
"color": "orange",
"index": 1,
"value": 40
},
{
"color": "red",
"index": 2,
"value": 80
}
],
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.2.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "csv_metric_values",
"stringInput": "10003,33333"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
},
{
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"refId": "I",
"scenarioId": "random_walk"
},
{
"refId": "J",
"scenarioId": "random_walk"
},
{
"refId": "K",
"scenarioId": "random_walk"
},
{
"refId": "L",
"scenarioId": "random_walk"
},
{
"refId": "M",
"scenarioId": "random_walk"
},
{
"refId": "N",
"scenarioId": "random_walk"
},
{
"refId": "O",
"scenarioId": "random_walk"
},
{
"refId": "P",
"scenarioId": "random_walk"
},
{
"refId": "Q",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Usage",
"type": "bargauge"
},
{
"gridPos": {
"h": 20,
"w": 6,
"x": 18,
"y": 0
},
"id": 8,
"links": [],
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"max": 100,
"min": 0,
"unit": "watt"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "green",
"index": 0,
"value": null
},
{
"color": "orange",
"index": 1,
"value": 65
},
{
"color": "red",
"index": 2,
"value": 95
}
],
"values": false
},
"orientation": "horizontal"
},
"pluginVersion": "6.2.0-pre",
"targets": [
{
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "I",
"scenarioId": "random_walk"
},
{
"refId": "J",
"scenarioId": "random_walk"
},
{
"refId": "K",
"scenarioId": "random_walk"
},
{
"refId": "L",
"scenarioId": "random_walk"
},
{
"refId": "M",
"scenarioId": "random_walk"
},
{
"refId": "N",
"scenarioId": "random_walk"
},
{
"refId": "O",
"scenarioId": "random_walk"
},
{
"refId": "P",
"scenarioId": "random_walk"
},
{
"refId": "Q",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
},
{
"refId": "R",
"scenarioId": "random_walk"
},
{
"refId": "S",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Usage",
"type": "bargauge"
},
{
"gridPos": {
"h": 13,
"w": 18,
"x": 0,
"y": 7
},
"id": 6,
"links": [],
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"max": 100,
"min": 0,
"unit": "celsius"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "blue",
"index": 0,
"value": null
},
{
"color": "green",
"index": 1,
"value": 20
},
{
"color": "orange",
"index": 2,
"value": 40
},
{
"color": "red",
"index": 3,
"value": 80
}
],
"values": false
},
"orientation": "horizontal"
},
"pluginVersion": "6.2.0-pre",
"targets": [
{
"alias": "Inside",
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"refId": "A",
"scenarioId": "random_walk"
},
{
"alias": "Area B",
"refId": "B",
"scenarioId": "random_walk"
},
{
"alias": "Basement",
"refId": "C",
"scenarioId": "random_walk"
},
{
"alias": "Garage",
"refId": "D",
"scenarioId": "random_walk"
},
{
"alias": "Attic",
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Temperature",
"type": "bargauge"
}
],
"schemaVersion": 18,
"style": "dark",
"tags": ["gdev", "bargauge", "panel-demo"],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
},
"timezone": "",
"title": "Bar Gauge Gradient Demo",
"uid": "RndRQw6mz",
"version": 1
}
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"links": [],
"panels": [
{
"gridPos": {
"h": 8,
"w": 22,
"x": 0,
"y": 0
},
"id": 7,
"links": [],
"options": {
"displayMode": "lcd",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"max": 100,
"min": 0,
"unit": "watt"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "green",
"index": 0,
"value": null
},
{
"color": "orange",
"index": 1,
"value": 40
},
{
"color": "red",
"index": 2,
"value": 80
}
],
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.2.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "csv_metric_values",
"stringInput": "10003,33333"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
},
{
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"refId": "I",
"scenarioId": "random_walk"
},
{
"refId": "J",
"scenarioId": "random_walk"
},
{
"refId": "K",
"scenarioId": "random_walk"
},
{
"refId": "L",
"scenarioId": "random_walk"
},
{
"refId": "M",
"scenarioId": "random_walk"
},
{
"refId": "N",
"scenarioId": "random_walk"
},
{
"refId": "O",
"scenarioId": "random_walk"
},
{
"refId": "P",
"scenarioId": "random_walk"
},
{
"refId": "Q",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Usage",
"type": "bargauge"
},
{
"gridPos": {
"h": 21,
"w": 2,
"x": 22,
"y": 0
},
"id": 11,
"links": [],
"options": {
"displayMode": "lcd",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"max": 100,
"min": 0,
"unit": "percent"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "green",
"index": 0,
"value": null
},
{
"color": "red",
"index": 1,
"value": 80
}
],
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.2.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Progress",
"type": "bargauge"
},
{
"gridPos": {
"h": 13,
"w": 10,
"x": 0,
"y": 8
},
"id": 6,
"links": [],
"options": {
"displayMode": "lcd",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"max": 100,
"min": 0,
"unit": "celsius"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "green",
"index": 0,
"value": null
},
{
"color": "orange",
"index": 1,
"value": 40
},
{
"color": "red",
"index": 2,
"value": 80
}
],
"values": false
},
"orientation": "horizontal"
},
"pluginVersion": "6.2.0-pre",
"targets": [
{
"alias": "Inside",
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"refId": "A",
"scenarioId": "random_walk"
},
{
"alias": "Area B",
"refId": "B",
"scenarioId": "random_walk"
},
{
"alias": "Basement",
"refId": "C",
"scenarioId": "random_walk"
},
{
"alias": "Garage",
"refId": "D",
"scenarioId": "random_walk"
},
{
"alias": "Attic",
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Temperature",
"type": "bargauge"
},
{
"gridPos": {
"h": 13,
"w": 12,
"x": 10,
"y": 8
},
"id": 8,
"links": [],
"options": {
"displayMode": "lcd",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"max": 100,
"min": 0,
"unit": "watt"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "green",
"index": 0,
"value": null
},
{
"color": "orange",
"index": 1,
"value": 85
},
{
"color": "red",
"index": 2,
"value": 95
}
],
"values": false
},
"orientation": "horizontal"
},
"pluginVersion": "6.2.0-pre",
"targets": [
{
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "I",
"scenarioId": "random_walk"
},
{
"refId": "J",
"scenarioId": "random_walk"
},
{
"refId": "K",
"scenarioId": "random_walk"
},
{
"refId": "L",
"scenarioId": "random_walk"
},
{
"refId": "M",
"scenarioId": "random_walk"
},
{
"refId": "N",
"scenarioId": "random_walk"
},
{
"refId": "O",
"scenarioId": "random_walk"
},
{
"refId": "P",
"scenarioId": "random_walk"
},
{
"refId": "Q",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Usage",
"type": "bargauge"
}
],
"schemaVersion": 18,
"style": "dark",
"tags": ["gdev", "bargauge", "panel-demo"],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
},
"timezone": "",
"title": "Bar Gauge LED Demo",
"uid": "0G3rbkqmkaa",
"version": 1
}
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { BarGauge, Props, getValueColor, getBasicAndGradientStyles, getBarGradient, getTitleStyles } from './BarGauge'; import {
BarGauge,
Props,
getValueColor,
getBasicAndGradientStyles,
getBarGradient,
getTitleStyles,
getValuePercent,
} from './BarGauge';
import { VizOrientation, DisplayValue } from '../../types'; import { VizOrientation, DisplayValue } from '../../types';
import { getTheme } from '../../themes'; import { getTheme } from '../../themes';
...@@ -63,6 +71,24 @@ describe('BarGauge', () => { ...@@ -63,6 +71,24 @@ describe('BarGauge', () => {
}); });
}); });
describe('Get value percent', () => {
it('0 to 100 and value 40', () => {
expect(getValuePercent(40, 0, 100)).toEqual(0.4);
});
it('50 to 100 and value 75', () => {
expect(getValuePercent(75, 50, 100)).toEqual(0.5);
});
it('-30 to 30 and value 0', () => {
expect(getValuePercent(0, -30, 30)).toEqual(0.5);
});
it('-30 to 30 and value 30', () => {
expect(getValuePercent(30, -30, 30)).toEqual(1);
});
});
describe('Vertical bar without title', () => { describe('Vertical bar without title', () => {
it('should not include title height in height', () => { it('should not include title height in height', () => {
const props = getProps({ const props = getProps({
......
...@@ -161,7 +161,7 @@ export class BarGauge extends PureComponent<Props> { ...@@ -161,7 +161,7 @@ export class BarGauge extends PureComponent<Props> {
const cells: JSX.Element[] = []; const cells: JSX.Element[] = [];
for (let i = 0; i < cellCount; i++) { for (let i = 0; i < cellCount; i++) {
const currentValue = (valueRange / cellCount) * i; const currentValue = minValue + (valueRange / cellCount) * i;
const cellColor = this.getCellColor(currentValue); const cellColor = this.getCellColor(currentValue);
const cellStyles: CSSProperties = { const cellStyles: CSSProperties = {
borderRadius: '2px', borderRadius: '2px',
...@@ -345,11 +345,6 @@ function calculateBarAndValueDimensions(props: Props): BarAndValueDimensions { ...@@ -345,11 +345,6 @@ function calculateBarAndValueDimensions(props: Props): BarAndValueDimensions {
} }
} }
// console.log('titleDim', titleDim);
// console.log('valueWidth', valueWidth);
// console.log('width', width);
// console.log('total', titleDim.width + maxBarWidth + valueWidth);
return { return {
valueWidth, valueWidth,
valueHeight, valueHeight,
...@@ -360,6 +355,10 @@ function calculateBarAndValueDimensions(props: Props): BarAndValueDimensions { ...@@ -360,6 +355,10 @@ function calculateBarAndValueDimensions(props: Props): BarAndValueDimensions {
}; };
} }
export function getValuePercent(value: number, minValue: number, maxValue: number): number {
return Math.min((value - minValue) / (maxValue - minValue), 1);
}
/** /**
* Only exported to for unit test * Only exported to for unit test
*/ */
...@@ -367,7 +366,7 @@ export function getBasicAndGradientStyles(props: Props): BasicAndGradientStyles ...@@ -367,7 +366,7 @@ export function getBasicAndGradientStyles(props: Props): BasicAndGradientStyles
const { displayMode, maxValue, minValue, value } = props; const { displayMode, maxValue, minValue, value } = props;
const { valueWidth, valueHeight, maxBarHeight, maxBarWidth } = calculateBarAndValueDimensions(props); const { valueWidth, valueHeight, maxBarHeight, maxBarWidth } = calculateBarAndValueDimensions(props);
const valuePercent = Math.min(value.numeric / (maxValue - minValue), 1); const valuePercent = getValuePercent(value.numeric, minValue, maxValue);
const valueColor = getValueColor(props); const valueColor = getValueColor(props);
const valueStyles = getValueStyles(value.text, valueColor, valueWidth, valueHeight); const valueStyles = getValueStyles(value.text, valueColor, valueWidth, valueHeight);
const isBasic = displayMode === 'basic'; const isBasic = displayMode === 'basic';
...@@ -450,7 +449,7 @@ export function getBarGradient(props: Props, maxSize: number): string { ...@@ -450,7 +449,7 @@ export function getBarGradient(props: Props, maxSize: number): string {
for (let i = 0; i < thresholds.length; i++) { for (let i = 0; i < thresholds.length; i++) {
const threshold = thresholds[i]; const threshold = thresholds[i];
const color = getColorFromHexRgbOrName(threshold.color); const color = getColorFromHexRgbOrName(threshold.color);
const valuePercent = Math.min(threshold.value / (maxValue - minValue), 1); const valuePercent = getValuePercent(threshold.value, minValue, maxValue);
const pos = valuePercent * maxSize; const pos = valuePercent * maxSize;
const offset = Math.round(pos - (pos - lastpos) / 2); const offset = Math.round(pos - (pos - lastpos) / 2);
...@@ -499,30 +498,3 @@ function getValueStyles(value: string, color: string, width: number, height: num ...@@ -499,30 +498,3 @@ function getValueStyles(value: string, color: string, width: number, height: num
fontSize: fontSize.toFixed(2) + 'px', fontSize: fontSize.toFixed(2) + 'px',
}; };
} }
// let canvasElement: HTMLCanvasElement | null = null;
//
// interface TextDimensions {
// width: number;
// height: number;
// }
//
// /**
// * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
// *
// * @param {String} text The text to be rendered.
// * @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
// *
// * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
// */
// function getTextWidth(text: string): number {
// // re-use canvas object for better performance
// canvasElement = canvasElement || document.createElement('canvas');
// const context = canvasElement.getContext('2d');
// if (context) {
// context.font = 'normal 16px Roboto';
// const metrics = context.measureText(text);
// return metrics.width;
// }
// return 16;
// }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment