mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
wip: moving react graph component to grafana/ui
This commit is contained in:
4
packages/grafana-build/README.md
Normal file
4
packages/grafana-build/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Shared build scripts
|
||||||
|
|
||||||
|
Shared build scripts for plugins & internal packages.
|
||||||
|
|
||||||
12
packages/grafana-build/package.json
Normal file
12
packages/grafana-build/package.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "@grafana/build",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
||||||
3
packages/grafana-ui/README.md
Normal file
3
packages/grafana-ui/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Grafana (WIP) shared component library
|
||||||
|
|
||||||
|
Used by internal & external plugins.
|
||||||
@@ -10,17 +10,19 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@torkelo/react-select": "2.1.1",
|
||||||
|
"moment": "^2.22.2",
|
||||||
"react": "^16.6.3",
|
"react": "^16.6.3",
|
||||||
"react-dom": "^16.6.3",
|
"react-dom": "^16.6.3",
|
||||||
"react-popper": "^1.3.0",
|
|
||||||
"react-highlight-words": "0.11.0",
|
"react-highlight-words": "0.11.0",
|
||||||
"@torkelo/react-select": "2.1.1",
|
"react-popper": "^1.3.0",
|
||||||
"react-transition-group": "^2.2.1",
|
"react-transition-group": "^2.2.1",
|
||||||
"moment": "^2.22.2",
|
"lodash": "^4.17.10",
|
||||||
"react-virtualized": "^9.21.0"
|
"react-virtualized": "^9.21.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^23.3.2",
|
"@types/jest": "^23.3.2",
|
||||||
|
"@types/lodash": "^4.17.10",
|
||||||
"@types/react": "^16.7.6",
|
"@types/react": "^16.7.6",
|
||||||
"typescript": "^3.2.2"
|
"typescript": "^3.2.2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
// Libraries
|
// Libraries
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import 'vendor/flot/jquery.flot';
|
|
||||||
import 'vendor/flot/jquery.flot.time';
|
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { TimeRange, TimeSeriesVMs } from '@grafana/ui';
|
import { TimeRange, TimeSeriesVMs } from '../../types';
|
||||||
|
|
||||||
interface GraphProps {
|
interface GraphProps {
|
||||||
timeSeries: TimeSeriesVMs;
|
timeSeries: TimeSeriesVMs;
|
||||||
@@ -1 +1,2 @@
|
|||||||
export { DeleteButton } from './DeleteButton/DeleteButton';
|
export { DeleteButton } from './DeleteButton/DeleteButton';
|
||||||
|
export { Graph } from './Graph/Graph';
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
export * from './components';
|
export * from './components';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
|
export * from './utils';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export enum LoadingState {
|
|||||||
Error = 'Error',
|
Error = 'Error',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TimeSeriesValue = string | number | null;
|
export type TimeSeriesValue = number | null;
|
||||||
|
|
||||||
export type TimeSeriesPoints = TimeSeriesValue[][];
|
export type TimeSeriesPoints = TimeSeriesValue[][];
|
||||||
|
|
||||||
@@ -24,9 +24,9 @@ export interface TimeSeriesVM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface TimeSeriesStats {
|
export interface TimeSeriesStats {
|
||||||
total: number;
|
total: number | null;
|
||||||
max: number;
|
max: number | null;
|
||||||
min: number;
|
min: number | null;
|
||||||
logmin: number;
|
logmin: number;
|
||||||
avg: number | null;
|
avg: number | null;
|
||||||
current: number | null;
|
current: number | null;
|
||||||
|
|||||||
1
packages/grafana-ui/src/utils/index.ts
Normal file
1
packages/grafana-ui/src/utils/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './processTimeSeries';
|
||||||
174
packages/grafana-ui/src/utils/processTimeSeries.ts
Normal file
174
packages/grafana-ui/src/utils/processTimeSeries.ts
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
// Libraries
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import { TimeSeries, TimeSeriesVMs, NullValueMode, TimeSeriesValue } from '../types';
|
||||||
|
|
||||||
|
interface Options {
|
||||||
|
timeSeries: TimeSeries[];
|
||||||
|
nullValueMode: NullValueMode;
|
||||||
|
colorPalette: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function processTimeSeries({ timeSeries, nullValueMode, colorPalette }: Options): TimeSeriesVMs {
|
||||||
|
const vmSeries = timeSeries.map((item, index) => {
|
||||||
|
const colorIndex = index % colorPalette.length;
|
||||||
|
const label = item.target;
|
||||||
|
const result = [];
|
||||||
|
|
||||||
|
// stat defaults
|
||||||
|
let total = 0;
|
||||||
|
let max: TimeSeriesValue = -Number.MAX_VALUE;
|
||||||
|
let min: TimeSeriesValue = Number.MAX_VALUE;
|
||||||
|
let logmin = Number.MAX_VALUE;
|
||||||
|
let avg: TimeSeriesValue = null;
|
||||||
|
let current: TimeSeriesValue = null;
|
||||||
|
let first: TimeSeriesValue = null;
|
||||||
|
let delta: TimeSeriesValue = 0;
|
||||||
|
let diff: TimeSeriesValue = null;
|
||||||
|
let range: TimeSeriesValue = null;
|
||||||
|
let timeStep = Number.MAX_VALUE;
|
||||||
|
let allIsNull = true;
|
||||||
|
let allIsZero = true;
|
||||||
|
|
||||||
|
const ignoreNulls = nullValueMode === NullValueMode.Ignore;
|
||||||
|
const nullAsZero = nullValueMode === NullValueMode.AsZero;
|
||||||
|
|
||||||
|
let currentTime: TimeSeriesValue = null;
|
||||||
|
let currentValue: TimeSeriesValue = null;
|
||||||
|
let nonNulls = 0;
|
||||||
|
let previousTime: TimeSeriesValue = null;
|
||||||
|
let previousValue = 0;
|
||||||
|
let previousDeltaUp = true;
|
||||||
|
|
||||||
|
for (let i = 0; i < item.datapoints.length; i++) {
|
||||||
|
currentValue = item.datapoints[i][0];
|
||||||
|
currentTime = item.datapoints[i][1];
|
||||||
|
|
||||||
|
if (typeof currentTime !== 'number') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof currentValue !== 'number') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Due to missing values we could have different timeStep all along the series
|
||||||
|
// so we have to find the minimum one (could occur with aggregators such as ZimSum)
|
||||||
|
if (previousTime !== null && currentTime !== null) {
|
||||||
|
const currentStep = currentTime - previousTime;
|
||||||
|
if (currentStep < timeStep) {
|
||||||
|
timeStep = currentStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
previousTime = currentTime;
|
||||||
|
|
||||||
|
if (currentValue === null) {
|
||||||
|
if (ignoreNulls) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nullAsZero) {
|
||||||
|
currentValue = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentValue !== null) {
|
||||||
|
if (_.isNumber(currentValue)) {
|
||||||
|
total += currentValue;
|
||||||
|
allIsNull = false;
|
||||||
|
nonNulls++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentValue > max) {
|
||||||
|
max = currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentValue < min) {
|
||||||
|
min = currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first === null) {
|
||||||
|
first = currentValue;
|
||||||
|
} else {
|
||||||
|
if (previousValue > currentValue) {
|
||||||
|
// counter reset
|
||||||
|
previousDeltaUp = false;
|
||||||
|
if (i === item.datapoints.length - 1) {
|
||||||
|
// reset on last
|
||||||
|
delta += currentValue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (previousDeltaUp) {
|
||||||
|
delta += currentValue - previousValue; // normal increment
|
||||||
|
} else {
|
||||||
|
delta += currentValue; // account for counter reset
|
||||||
|
}
|
||||||
|
previousDeltaUp = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previousValue = currentValue;
|
||||||
|
|
||||||
|
if (currentValue < logmin && currentValue > 0) {
|
||||||
|
logmin = currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentValue !== 0) {
|
||||||
|
allIsZero = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push([currentTime, currentValue]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max === -Number.MAX_VALUE) {
|
||||||
|
max = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min === Number.MAX_VALUE) {
|
||||||
|
min = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.length && !allIsNull) {
|
||||||
|
avg = total / nonNulls;
|
||||||
|
current = result[result.length - 1][1];
|
||||||
|
if (current === null && result.length > 1) {
|
||||||
|
current = result[result.length - 2][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max !== null && min !== null) {
|
||||||
|
range = max - min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current !== null && first !== null) {
|
||||||
|
diff = current - first;
|
||||||
|
}
|
||||||
|
|
||||||
|
const count = result.length;
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: result,
|
||||||
|
label: label,
|
||||||
|
color: colorPalette[colorIndex],
|
||||||
|
stats: {
|
||||||
|
total,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
current,
|
||||||
|
logmin,
|
||||||
|
avg,
|
||||||
|
diff,
|
||||||
|
delta,
|
||||||
|
timeStep,
|
||||||
|
range,
|
||||||
|
count,
|
||||||
|
first,
|
||||||
|
allIsZero,
|
||||||
|
allIsNull,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return vmSeries;
|
||||||
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
// Libraries
|
// Libraries
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
import colors from 'app/core/utils/colors';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import Graph from 'app/viz/Graph';
|
import { Graph } from '@grafana/ui';
|
||||||
|
|
||||||
// Services & Utils
|
// Services & Utils
|
||||||
import { getTimeSeriesVMs } from 'app/viz/state/timeSeries';
|
import { processTimeSeries } from '@grafana/ui';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { PanelProps, NullValueMode } from '@grafana/ui';
|
import { PanelProps, NullValueMode } from '@grafana/ui';
|
||||||
@@ -23,9 +24,10 @@ export class GraphPanel extends PureComponent<Props> {
|
|||||||
const { timeSeries, timeRange, width, height } = this.props;
|
const { timeSeries, timeRange, width, height } = this.props;
|
||||||
const { showLines, showBars, showPoints } = this.props.options;
|
const { showLines, showBars, showPoints } = this.props.options;
|
||||||
|
|
||||||
const vmSeries = getTimeSeriesVMs({
|
const vmSeries = processTimeSeries({
|
||||||
timeSeries: timeSeries,
|
timeSeries: timeSeries,
|
||||||
nullValueMode: NullValueMode.Ignore,
|
nullValueMode: NullValueMode.Ignore,
|
||||||
|
colorPalette: colors,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1029,6 +1029,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.4.tgz#cc43ae176a91dcb1504839b0b9d6659386cf0af5"
|
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.4.tgz#cc43ae176a91dcb1504839b0b9d6659386cf0af5"
|
||||||
integrity sha512-46jSw0QMerCRkhJZbOwPA0Eb9T1p74HtECsfa0GXdgjkenSGhgvK96w+e2PEPu4GF0/brUK5WQKq/rUQQFyAxA==
|
integrity sha512-46jSw0QMerCRkhJZbOwPA0Eb9T1p74HtECsfa0GXdgjkenSGhgvK96w+e2PEPu4GF0/brUK5WQKq/rUQQFyAxA==
|
||||||
|
|
||||||
|
"@types/lodash@^4.14.119":
|
||||||
|
version "4.14.119"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.119.tgz#be847e5f4bc3e35e46d041c394ead8b603ad8b39"
|
||||||
|
integrity sha512-Z3TNyBL8Vd/M9D9Ms2S3LmFq2sSMzahodD6rCS9V2N44HUMINb75jNkSuwAx7eo2ufqTdfOdtGQpNbieUjPQmw==
|
||||||
|
|
||||||
"@types/node@*":
|
"@types/node@*":
|
||||||
version "10.11.4"
|
version "10.11.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.4.tgz#e8bd933c3f78795d580ae41d86590bfc1f4f389d"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.4.tgz#e8bd933c3f78795d580ae41d86590bfc1f4f389d"
|
||||||
@@ -1083,7 +1088,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@16.7.6", "@types/react@^16.1.0", "@types/react@^16.7.6":
|
"@types/react@*", "@types/react@^16.1.0", "@types/react@^16.7.6":
|
||||||
version "16.7.6"
|
version "16.7.6"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.7.6.tgz#80e4bab0d0731ad3ae51f320c4b08bdca5f03040"
|
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.7.6.tgz#80e4bab0d0731ad3ae51f320c4b08bdca5f03040"
|
||||||
integrity sha512-QBUfzftr/8eg/q3ZRgf/GaDP6rTYc7ZNem+g4oZM38C9vXyV8AWRWaTQuW5yCoZTsfHrN7b3DeEiUnqH9SrnpA==
|
integrity sha512-QBUfzftr/8eg/q3ZRgf/GaDP6rTYc7ZNem+g4oZM38C9vXyV8AWRWaTQuW5yCoZTsfHrN7b3DeEiUnqH9SrnpA==
|
||||||
@@ -3153,7 +3158,7 @@ caniuse-api@^1.5.2:
|
|||||||
lodash.memoize "^4.1.2"
|
lodash.memoize "^4.1.2"
|
||||||
lodash.uniq "^4.5.0"
|
lodash.uniq "^4.5.0"
|
||||||
|
|
||||||
caniuse-db@1.0.30000772, caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
|
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
|
||||||
version "1.0.30000772"
|
version "1.0.30000772"
|
||||||
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000772.tgz#51aae891768286eade4a3d8319ea76d6a01b512b"
|
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000772.tgz#51aae891768286eade4a3d8319ea76d6a01b512b"
|
||||||
integrity sha1-UarokXaChureSj2DGep21qAbUSs=
|
integrity sha1-UarokXaChureSj2DGep21qAbUSs=
|
||||||
|
|||||||
Reference in New Issue
Block a user