mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
GraphPanel: show results for all SeriesData (#16966)
* Graph panel should support SeriesData * Graph panel should support SeriesData * same path for all series * merge master * support docs * add test for processor * Graph: removed old unused data processing logic * Graph: minor refactoring data processing * fix histogram * set Count as title
This commit is contained in:
parent
cf39a264ca
commit
813e3ffc15
@ -10,7 +10,7 @@ export class AxesEditorCtrl {
|
|||||||
xNameSegment: any;
|
xNameSegment: any;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private $scope, private $q) {
|
constructor(private $scope) {
|
||||||
this.panelCtrl = $scope.ctrl;
|
this.panelCtrl = $scope.ctrl;
|
||||||
this.panel = this.panelCtrl.panel;
|
this.panel = this.panelCtrl.panel;
|
||||||
this.$scope.ctrl = this;
|
this.$scope.ctrl = this;
|
||||||
@ -65,15 +65,6 @@ export class AxesEditorCtrl {
|
|||||||
xAxisValueChanged() {
|
xAxisValueChanged() {
|
||||||
this.panelCtrl.onDataReceived(this.panelCtrl.dataList);
|
this.panelCtrl.onDataReceived(this.panelCtrl.dataList);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDataFieldNames(onlyNumbers) {
|
|
||||||
const props = this.panelCtrl.processor.getDataFieldNames(this.panelCtrl.dataList, onlyNumbers);
|
|
||||||
const items = props.map(prop => {
|
|
||||||
return { text: prop, value: prop };
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.$q.when(items);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { colors, getColorFromHexRgbOrName } from '@grafana/ui';
|
import { TimeRange, colors, getColorFromHexRgbOrName, FieldCache, FieldType, Field, SeriesData } from '@grafana/ui';
|
||||||
import TimeSeries from 'app/core/time_series2';
|
import TimeSeries from 'app/core/time_series2';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
import { LegacyResponseData, TimeRange } from '@grafana/ui';
|
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
dataList: LegacyResponseData[];
|
dataList: SeriesData[];
|
||||||
range?: TimeRange;
|
range?: TimeRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -13,68 +12,81 @@ export class DataProcessor {
|
|||||||
constructor(private panel) {}
|
constructor(private panel) {}
|
||||||
|
|
||||||
getSeriesList(options: Options): TimeSeries[] {
|
getSeriesList(options: Options): TimeSeries[] {
|
||||||
if (!options.dataList || options.dataList.length === 0) {
|
const list: TimeSeries[] = [];
|
||||||
return [];
|
const { dataList, range } = options;
|
||||||
|
|
||||||
|
if (!dataList || !dataList.length) {
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
// auto detect xaxis mode
|
for (const series of dataList) {
|
||||||
let firstItem;
|
const { fields } = series;
|
||||||
if (options.dataList && options.dataList.length > 0) {
|
const cache = new FieldCache(fields);
|
||||||
firstItem = options.dataList[0];
|
const time = cache.getFirstFieldOfType(FieldType.time);
|
||||||
const autoDetectMode = this.getAutoDetectXAxisMode(firstItem);
|
|
||||||
if (this.panel.xaxis.mode !== autoDetectMode) {
|
|
||||||
this.panel.xaxis.mode = autoDetectMode;
|
|
||||||
this.setPanelDefaultsForNewXAxisMode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (this.panel.xaxis.mode) {
|
if (!time) {
|
||||||
case 'series':
|
continue;
|
||||||
case 'time': {
|
|
||||||
return options.dataList.map((item, index) => {
|
|
||||||
return this.timeSeriesHandler(item, index, options);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
case 'histogram': {
|
|
||||||
let histogramDataList;
|
const seriesName = series.name ? series.name : series.refId;
|
||||||
if (this.panel.stack) {
|
|
||||||
histogramDataList = options.dataList;
|
for (let i = 0; i < fields.length; i++) {
|
||||||
} else {
|
if (fields[i].type !== FieldType.number) {
|
||||||
histogramDataList = [
|
continue;
|
||||||
{
|
|
||||||
target: 'count',
|
|
||||||
datapoints: _.concat([], _.flatten(_.map(options.dataList, 'datapoints'))),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
return histogramDataList.map((item, index) => {
|
|
||||||
return this.timeSeriesHandler(item, index, options);
|
const field = fields[i];
|
||||||
});
|
let name = field.title;
|
||||||
}
|
|
||||||
case 'field': {
|
if (!field.title) {
|
||||||
return this.customHandler(firstItem);
|
name = field.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seriesName && dataList.length > 0 && name !== seriesName) {
|
||||||
|
name = seriesName + ' ' + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const datapoints = [];
|
||||||
|
for (const row of series.rows) {
|
||||||
|
datapoints.push([row[i], row[time.index]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
list.push(this.toTimeSeries(field, name, datapoints, list.length, range));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
// Merge all the rows if we want to show a histogram
|
||||||
|
if (this.panel.xaxis.mode === 'histogram' && !this.panel.stack && list.length > 1) {
|
||||||
|
const first = list[0];
|
||||||
|
first.alias = first.aliasEscaped = 'Count';
|
||||||
|
for (let i = 1; i < list.length; i++) {
|
||||||
|
first.datapoints = first.datapoints.concat(list[i].datapoints);
|
||||||
|
}
|
||||||
|
return [first];
|
||||||
|
}
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAutoDetectXAxisMode(firstItem) {
|
private toTimeSeries(field: Field, alias: string, datapoints: any[][], index: number, range?: TimeRange) {
|
||||||
switch (firstItem.type) {
|
const colorIndex = index % colors.length;
|
||||||
case 'docs':
|
const color = this.panel.aliasColors[alias] || colors[colorIndex];
|
||||||
return 'field';
|
|
||||||
case 'table':
|
const series = new TimeSeries({
|
||||||
return 'field';
|
datapoints: datapoints || [],
|
||||||
default: {
|
alias: alias,
|
||||||
if (this.panel.xaxis.mode === 'series') {
|
color: getColorFromHexRgbOrName(color, config.theme.type),
|
||||||
return 'series';
|
unit: field.unit,
|
||||||
}
|
});
|
||||||
if (this.panel.xaxis.mode === 'histogram') {
|
|
||||||
return 'histogram';
|
if (datapoints && datapoints.length > 0 && range) {
|
||||||
}
|
const last = datapoints[datapoints.length - 1][1];
|
||||||
return 'time';
|
const from = range.from;
|
||||||
|
|
||||||
|
if (last - from.valueOf() < -10000) {
|
||||||
|
series.isOutsideRange = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return series;
|
||||||
}
|
}
|
||||||
|
|
||||||
setPanelDefaultsForNewXAxisMode() {
|
setPanelDefaultsForNewXAxisMode() {
|
||||||
@ -110,43 +122,6 @@ export class DataProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timeSeriesHandler(seriesData: LegacyResponseData, index: number, options: Options) {
|
|
||||||
const datapoints = seriesData.datapoints || [];
|
|
||||||
const alias = seriesData.target;
|
|
||||||
|
|
||||||
const colorIndex = index % colors.length;
|
|
||||||
|
|
||||||
const color = this.panel.aliasColors[alias] || colors[colorIndex];
|
|
||||||
|
|
||||||
const series = new TimeSeries({
|
|
||||||
datapoints: datapoints,
|
|
||||||
alias: alias,
|
|
||||||
color: getColorFromHexRgbOrName(color, config.theme.type),
|
|
||||||
unit: seriesData.unit,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (datapoints && datapoints.length > 0) {
|
|
||||||
const last = datapoints[datapoints.length - 1][1];
|
|
||||||
const from = options.range.from;
|
|
||||||
|
|
||||||
if (last - from.valueOf() < -10000) {
|
|
||||||
series.isOutsideRange = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return series;
|
|
||||||
}
|
|
||||||
|
|
||||||
customHandler(dataItem) {
|
|
||||||
const nameField = this.panel.xaxis.name;
|
|
||||||
if (!nameField) {
|
|
||||||
throw {
|
|
||||||
message: 'No field name specified to use for x-axis, check your axes settings',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
validateXAxisSeriesValue() {
|
validateXAxisSeriesValue() {
|
||||||
switch (this.panel.xaxis.mode) {
|
switch (this.panel.xaxis.mode) {
|
||||||
case 'series': {
|
case 'series': {
|
||||||
@ -165,40 +140,6 @@ export class DataProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getDataFieldNames(dataList, onlyNumbers) {
|
|
||||||
if (dataList.length === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const fields = [];
|
|
||||||
const firstItem = dataList[0];
|
|
||||||
const fieldParts = [];
|
|
||||||
|
|
||||||
function getPropertiesRecursive(obj) {
|
|
||||||
_.forEach(obj, (value, key) => {
|
|
||||||
if (_.isObject(value)) {
|
|
||||||
fieldParts.push(key);
|
|
||||||
getPropertiesRecursive(value);
|
|
||||||
} else {
|
|
||||||
if (!onlyNumbers || _.isNumber(value)) {
|
|
||||||
const field = fieldParts.concat(key).join('.');
|
|
||||||
fields.push(field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
fieldParts.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstItem.type === 'docs') {
|
|
||||||
if (firstItem.datapoints.length === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
getPropertiesRecursive(firstItem.datapoints[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
getXAxisValueOptions(options) {
|
getXAxisValueOptions(options) {
|
||||||
switch (this.panel.xaxis.mode) {
|
switch (this.panel.xaxis.mode) {
|
||||||
case 'series': {
|
case 'series': {
|
||||||
|
@ -11,7 +11,8 @@ import { DataProcessor } from './data_processor';
|
|||||||
import { axesEditorComponent } from './axes_editor';
|
import { axesEditorComponent } from './axes_editor';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
import TimeSeries from 'app/core/time_series2';
|
import TimeSeries from 'app/core/time_series2';
|
||||||
import { getColorFromHexRgbOrName, LegacyResponseData } from '@grafana/ui';
|
import { getColorFromHexRgbOrName, LegacyResponseData, SeriesData } from '@grafana/ui';
|
||||||
|
import { getProcessedSeriesData } from 'app/features/dashboard/state/PanelQueryState';
|
||||||
|
|
||||||
class GraphCtrl extends MetricsPanelCtrl {
|
class GraphCtrl extends MetricsPanelCtrl {
|
||||||
static template = template;
|
static template = template;
|
||||||
@ -19,7 +20,7 @@ class GraphCtrl extends MetricsPanelCtrl {
|
|||||||
renderError: boolean;
|
renderError: boolean;
|
||||||
hiddenSeries: any = {};
|
hiddenSeries: any = {};
|
||||||
seriesList: TimeSeries[] = [];
|
seriesList: TimeSeries[] = [];
|
||||||
dataList: LegacyResponseData[] = [];
|
dataList: SeriesData[] = [];
|
||||||
annotations: any = [];
|
annotations: any = [];
|
||||||
alertState: any;
|
alertState: any;
|
||||||
|
|
||||||
@ -188,9 +189,9 @@ class GraphCtrl extends MetricsPanelCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onDataReceived(dataList: LegacyResponseData[]) {
|
onDataReceived(dataList: LegacyResponseData[]) {
|
||||||
this.dataList = dataList;
|
this.dataList = getProcessedSeriesData(dataList);
|
||||||
this.seriesList = this.processor.getSeriesList({
|
this.seriesList = this.processor.getSeriesList({
|
||||||
dataList: dataList,
|
dataList: this.dataList,
|
||||||
range: this.range,
|
range: this.range,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -0,0 +1,233 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Graph DataProcessor getTimeSeries from LegacyResponseData Should return a new series for each field 1`] = `
|
||||||
|
Array [
|
||||||
|
TimeSeries {
|
||||||
|
"alias": "Value",
|
||||||
|
"aliasEscaped": "Value",
|
||||||
|
"bars": Object {
|
||||||
|
"fillColor": "#7EB26D",
|
||||||
|
},
|
||||||
|
"color": "#7EB26D",
|
||||||
|
"datapoints": Array [
|
||||||
|
Array [
|
||||||
|
1,
|
||||||
|
1001,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
2,
|
||||||
|
1002,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
3,
|
||||||
|
1003,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"hasMsResolution": false,
|
||||||
|
"id": "Value",
|
||||||
|
"label": "Value",
|
||||||
|
"legend": true,
|
||||||
|
"stats": Object {},
|
||||||
|
"unit": "watt",
|
||||||
|
"valueFormater": [Function],
|
||||||
|
},
|
||||||
|
TimeSeries {
|
||||||
|
"alias": "table_data v1",
|
||||||
|
"aliasEscaped": "table_data v1",
|
||||||
|
"bars": Object {
|
||||||
|
"fillColor": "#EAB839",
|
||||||
|
},
|
||||||
|
"color": "#EAB839",
|
||||||
|
"datapoints": Array [
|
||||||
|
Array [
|
||||||
|
0.1,
|
||||||
|
1001,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.2,
|
||||||
|
1002,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.3,
|
||||||
|
1003,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"hasMsResolution": false,
|
||||||
|
"id": "table_data v1",
|
||||||
|
"label": "table_data v1",
|
||||||
|
"legend": true,
|
||||||
|
"stats": Object {},
|
||||||
|
"unit": "ohm",
|
||||||
|
"valueFormater": [Function],
|
||||||
|
},
|
||||||
|
TimeSeries {
|
||||||
|
"alias": "table_data v2",
|
||||||
|
"aliasEscaped": "table_data v2",
|
||||||
|
"bars": Object {
|
||||||
|
"fillColor": "#6ED0E0",
|
||||||
|
},
|
||||||
|
"color": "#6ED0E0",
|
||||||
|
"datapoints": Array [
|
||||||
|
Array [
|
||||||
|
1.1,
|
||||||
|
1001,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
2.2,
|
||||||
|
1002,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
3.3,
|
||||||
|
1003,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"hasMsResolution": false,
|
||||||
|
"id": "table_data v2",
|
||||||
|
"label": "table_data v2",
|
||||||
|
"legend": true,
|
||||||
|
"stats": Object {},
|
||||||
|
"unit": undefined,
|
||||||
|
"valueFormater": [Function],
|
||||||
|
},
|
||||||
|
TimeSeries {
|
||||||
|
"alias": "series v1",
|
||||||
|
"aliasEscaped": "series v1",
|
||||||
|
"bars": Object {
|
||||||
|
"fillColor": "#EF843C",
|
||||||
|
},
|
||||||
|
"color": "#EF843C",
|
||||||
|
"datapoints": Array [
|
||||||
|
Array [
|
||||||
|
0.1,
|
||||||
|
1001,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.2,
|
||||||
|
1002,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.3,
|
||||||
|
1003,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"hasMsResolution": false,
|
||||||
|
"id": "series v1",
|
||||||
|
"label": "series v1",
|
||||||
|
"legend": true,
|
||||||
|
"stats": Object {},
|
||||||
|
"unit": undefined,
|
||||||
|
"valueFormater": [Function],
|
||||||
|
},
|
||||||
|
TimeSeries {
|
||||||
|
"alias": "series v2",
|
||||||
|
"aliasEscaped": "series v2",
|
||||||
|
"bars": Object {
|
||||||
|
"fillColor": "#E24D42",
|
||||||
|
},
|
||||||
|
"color": "#E24D42",
|
||||||
|
"datapoints": Array [
|
||||||
|
Array [
|
||||||
|
1.1,
|
||||||
|
1001,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
2.2,
|
||||||
|
1002,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
3.3,
|
||||||
|
1003,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"hasMsResolution": false,
|
||||||
|
"id": "series v2",
|
||||||
|
"label": "series v2",
|
||||||
|
"legend": true,
|
||||||
|
"stats": Object {},
|
||||||
|
"unit": undefined,
|
||||||
|
"valueFormater": [Function],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Graph DataProcessor getTimeSeries from LegacyResponseData Should return single histogram 1`] = `
|
||||||
|
Array [
|
||||||
|
TimeSeries {
|
||||||
|
"alias": "Count",
|
||||||
|
"aliasEscaped": "Count",
|
||||||
|
"bars": Object {
|
||||||
|
"fillColor": "#7EB26D",
|
||||||
|
},
|
||||||
|
"color": "#7EB26D",
|
||||||
|
"datapoints": Array [
|
||||||
|
Array [
|
||||||
|
1,
|
||||||
|
1001,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
2,
|
||||||
|
1002,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
3,
|
||||||
|
1003,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.1,
|
||||||
|
1001,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.2,
|
||||||
|
1002,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.3,
|
||||||
|
1003,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
1.1,
|
||||||
|
1001,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
2.2,
|
||||||
|
1002,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
3.3,
|
||||||
|
1003,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.1,
|
||||||
|
1001,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.2,
|
||||||
|
1002,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0.3,
|
||||||
|
1003,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
1.1,
|
||||||
|
1001,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
2.2,
|
||||||
|
1002,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
3.3,
|
||||||
|
1003,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"hasMsResolution": false,
|
||||||
|
"id": "Value",
|
||||||
|
"label": "Value",
|
||||||
|
"legend": true,
|
||||||
|
"stats": Object {},
|
||||||
|
"unit": "watt",
|
||||||
|
"valueFormater": [Function],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
@ -1,62 +1,60 @@
|
|||||||
import { DataProcessor } from '../data_processor';
|
import { DataProcessor } from '../data_processor';
|
||||||
|
import { getProcessedSeriesData } from 'app/features/dashboard/state/PanelQueryState';
|
||||||
|
|
||||||
describe('Graph DataProcessor', () => {
|
describe('Graph DataProcessor', () => {
|
||||||
const panel: any = {
|
const panel: any = {
|
||||||
xaxis: {},
|
xaxis: { mode: 'series' },
|
||||||
|
aliasColors: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const processor = new DataProcessor(panel);
|
const processor = new DataProcessor(panel);
|
||||||
|
|
||||||
describe('Given default xaxis options and query that returns docs', () => {
|
describe('getTimeSeries from LegacyResponseData', () => {
|
||||||
beforeEach(() => {
|
// Try each type of data
|
||||||
panel.xaxis.mode = 'time';
|
const dataList = getProcessedSeriesData([
|
||||||
panel.xaxis.name = 'hostname';
|
|
||||||
panel.xaxis.values = [];
|
|
||||||
|
|
||||||
processor.getSeriesList({
|
|
||||||
dataList: [
|
|
||||||
{
|
|
||||||
type: 'docs',
|
|
||||||
datapoints: [{ hostname: 'server1', avg: 10 }],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should automatically set xaxis mode to field', () => {
|
|
||||||
expect(panel.xaxis.mode).toBe('field');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getDataFieldNames(', () => {
|
|
||||||
const dataList = [
|
|
||||||
{
|
{
|
||||||
type: 'docs',
|
alias: 'First (time_series)',
|
||||||
datapoints: [
|
datapoints: [[1, 1001], [2, 1002], [3, 1003]],
|
||||||
{
|
unit: 'watt',
|
||||||
hostname: 'server1',
|
},
|
||||||
valueField: 11,
|
{
|
||||||
nested: {
|
name: 'table_data',
|
||||||
prop1: 'server2',
|
columns: [
|
||||||
value2: 23,
|
{ text: 'time' },
|
||||||
},
|
{ text: 'v1', unit: 'ohm' },
|
||||||
},
|
{ text: 'v2' }, // no unit
|
||||||
|
{ text: 'string' }, // skipped
|
||||||
|
],
|
||||||
|
rows: [
|
||||||
|
[1001, 0.1, 1.1, 'a'], // a
|
||||||
|
[1002, 0.2, 2.2, 'b'], // b
|
||||||
|
[1003, 0.3, 3.3, 'c'], // c
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
{
|
||||||
|
name: 'series',
|
||||||
|
fields: [
|
||||||
|
{ name: 'v1' }, // first
|
||||||
|
{ name: 'v2' }, // second
|
||||||
|
{ name: 'string' }, // skip
|
||||||
|
{ name: 'time' }, // Time is last column
|
||||||
|
],
|
||||||
|
rows: [[0.1, 1.1, 'a', 1001], [0.2, 2.2, 'b', 1002], [0.3, 3.3, 'c', 1003]],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
it('Should return all field names', () => {
|
it('Should return a new series for each field', () => {
|
||||||
const fields = processor.getDataFieldNames(dataList, false);
|
panel.xaxis.mode = 'series';
|
||||||
expect(fields).toContain('hostname');
|
const series = processor.getSeriesList({ dataList });
|
||||||
expect(fields).toContain('valueField');
|
expect(series.length).toEqual(5);
|
||||||
expect(fields).toContain('nested.prop1');
|
expect(series).toMatchSnapshot();
|
||||||
expect(fields).toContain('nested.value2');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should return all number fields', () => {
|
it('Should return single histogram', () => {
|
||||||
const fields = processor.getDataFieldNames(dataList, true);
|
panel.xaxis.mode = 'histogram';
|
||||||
expect(fields).toContain('valueField');
|
const series = processor.getSeriesList({ dataList });
|
||||||
expect(fields).toContain('nested.value2');
|
expect(series.length).toEqual(1);
|
||||||
|
expect(series).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user