Logs: Use GraphNG to plot log histograms (#34531)

* Switch to GraphNG for Logs Histogram

* Remove redundant timeZone

It was used just to format timestamp in the tooltip but it's not needed anymore.

* Add tests for creating logs histogram data

* Update decoractors tests

* Adjust bar width to be more like in the old graph

* Fix tooltip pointer color

* Test tooltip pointer color

* Decouple graph config from uPlot internals

* Ensure nested properties are not mutated when overrides are applied

* Add legend toggling for Explore graphs

* Remove unused component

ExploreGraphNGPanel is now used in Explore

* Code formatting

* allow multiple bars pathBuilders to be globally cached with different settings

Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
Piotr Jamróz
2021-06-01 09:28:25 +02:00
committed by GitHub
parent c6a78a6bd7
commit f4a40a4d85
17 changed files with 272 additions and 402 deletions

View File

@@ -1,4 +1,5 @@
import {
ArrayVector,
DataFrame,
FieldType,
LogLevel,
@@ -208,7 +209,7 @@ const emptyLogsModel: any = {
describe('dataFrameToLogsModel', () => {
it('given empty series should return empty logs model', () => {
expect(dataFrameToLogsModel([] as DataFrame[], 0, 'utc')).toMatchObject(emptyLogsModel);
expect(dataFrameToLogsModel([] as DataFrame[], 0)).toMatchObject(emptyLogsModel);
});
it('given series without correct series name should return empty logs model', () => {
@@ -217,7 +218,7 @@ describe('dataFrameToLogsModel', () => {
fields: [],
}),
];
expect(dataFrameToLogsModel(series, 0, 'utc')).toMatchObject(emptyLogsModel);
expect(dataFrameToLogsModel(series, 0)).toMatchObject(emptyLogsModel);
});
it('given series without a time field should return empty logs model', () => {
@@ -232,7 +233,7 @@ describe('dataFrameToLogsModel', () => {
],
}),
];
expect(dataFrameToLogsModel(series, 0, 'utc')).toMatchObject(emptyLogsModel);
expect(dataFrameToLogsModel(series, 0)).toMatchObject(emptyLogsModel);
});
it('given series without a string field should return empty logs model', () => {
@@ -247,7 +248,7 @@ describe('dataFrameToLogsModel', () => {
],
}),
];
expect(dataFrameToLogsModel(series, 0, 'utc')).toMatchObject(emptyLogsModel);
expect(dataFrameToLogsModel(series, 0)).toMatchObject(emptyLogsModel);
});
it('given one series should return expected logs model', () => {
@@ -282,7 +283,7 @@ describe('dataFrameToLogsModel', () => {
},
}),
];
const logsModel = dataFrameToLogsModel(series, 1, 'utc');
const logsModel = dataFrameToLogsModel(series, 1);
expect(logsModel.hasUniqueLabels).toBeFalsy();
expect(logsModel.rows).toHaveLength(2);
expect(logsModel.rows).toMatchObject([
@@ -303,6 +304,22 @@ describe('dataFrameToLogsModel', () => {
]);
expect(logsModel.series).toHaveLength(2);
expect(logsModel.series).toMatchObject([
{
name: 'info',
fields: [
{ type: 'time', values: new ArrayVector([1556270891000, 1556289770000]) },
{ type: 'number', values: new ArrayVector([1, 0]) },
],
},
{
name: 'error',
fields: [
{ type: 'time', values: new ArrayVector([1556289770000]) },
{ type: 'number', values: new ArrayVector([1]) },
],
},
]);
expect(logsModel.meta).toHaveLength(2);
expect(logsModel.meta![0]).toMatchObject({
label: 'Common labels',
@@ -352,7 +369,7 @@ describe('dataFrameToLogsModel', () => {
},
}),
];
const logsModel = dataFrameToLogsModel(series, 1, 'utc');
const logsModel = dataFrameToLogsModel(series, 1);
expect(logsModel.hasUniqueLabels).toBeFalsy();
expect(logsModel.rows).toHaveLength(2);
expect(logsModel.rows).toMatchObject([
@@ -413,7 +430,7 @@ describe('dataFrameToLogsModel', () => {
],
}),
];
const logsModel = dataFrameToLogsModel(series, 1, 'utc');
const logsModel = dataFrameToLogsModel(series, 1);
expect(logsModel.rows).toHaveLength(1);
expect(logsModel.rows).toMatchObject([
{
@@ -477,7 +494,7 @@ describe('dataFrameToLogsModel', () => {
],
}),
];
const logsModel = dataFrameToLogsModel(series, 1, 'utc');
const logsModel = dataFrameToLogsModel(series, 1);
expect(logsModel.hasUniqueLabels).toBeTruthy();
expect(logsModel.rows).toHaveLength(3);
expect(logsModel.rows).toMatchObject([
@@ -502,6 +519,22 @@ describe('dataFrameToLogsModel', () => {
]);
expect(logsModel.series).toHaveLength(2);
expect(logsModel.series).toMatchObject([
{
name: 'error',
fields: [
{ type: 'time', values: new ArrayVector([0, 1000, 2000]) },
{ type: 'number', values: new ArrayVector([1, 0, 1]) },
],
},
{
name: 'debug',
fields: [
{ type: 'time', values: new ArrayVector([1000, 2000]) },
{ type: 'number', values: new ArrayVector([1, 0]) },
],
},
]);
expect(logsModel.meta).toHaveLength(1);
expect(logsModel.meta![0]).toMatchObject({
label: 'Common labels',
@@ -587,7 +620,7 @@ describe('dataFrameToLogsModel', () => {
],
}),
];
const logsModel = dataFrameToLogsModel(series, 1, 'utc');
const logsModel = dataFrameToLogsModel(series, 1);
expect(logsModel.hasUniqueLabels).toBeTruthy();
expect(logsModel.rows).toHaveLength(4);
expect(logsModel.rows).toMatchObject([
@@ -650,7 +683,7 @@ describe('dataFrameToLogsModel', () => {
},
}),
];
const logsModel = dataFrameToLogsModel(series, 1, 'utc', { from: 1556270591353, to: 1556289770991 });
const logsModel = dataFrameToLogsModel(series, 1, { from: 1556270591353, to: 1556289770991 });
expect(logsModel.meta).toHaveLength(2);
expect(logsModel.meta![0]).toMatchObject({
label: 'Common labels',
@@ -682,7 +715,7 @@ describe('dataFrameToLogsModel', () => {
],
}),
];
const logsModel = dataFrameToLogsModel(series, 1, 'utc');
const logsModel = dataFrameToLogsModel(series, 1);
expect(logsModel.rows[0].uid).toBe('0');
});
});
@@ -763,7 +796,7 @@ describe('logSeriesToLogsModel', () => {
}),
];
const logsModel = dataFrameToLogsModel(logSeries, 0, 'utc');
const logsModel = dataFrameToLogsModel(logSeries, 0);
expect(logsModel.meta).toMatchObject([
{ kind: 2, label: 'Common labels', value: { foo: 'bar', level: 'dbug' } },
{ kind: 0, label: LIMIT_LABEL, value: 2000 },
@@ -818,7 +851,7 @@ describe('logSeriesToLogsModel', () => {
}),
];
const logsModel = dataFrameToLogsModel(logSeries, 0, 'utc');
const logsModel = dataFrameToLogsModel(logSeries, 0);
expect(logsModel.rows).toHaveLength(3);
expect(logsModel.rows).toMatchObject([
{