Skip to content

Commit

Permalink
Fix connecting y values for ql timeline chart (#167)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladimir Chernitsyn authored Nov 7, 2023
1 parent ff6ee6e commit 6a0b27e
Show file tree
Hide file tree
Showing 14 changed files with 324 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const expectedResult = {
name: 'Query #0',
color: 'rgb(0,127,0)',
data: [1, 1],
spanGaps: true,
spanGaps: false,
},
{
id: 'Query #1',
Expand All @@ -20,7 +20,7 @@ export const expectedResult = {
name: 'Query #1',
color: 'rgb(255,255,0)',
data: [2, 2],
spanGaps: true,
spanGaps: false,
},
{
id: 'Query #2',
Expand All @@ -29,7 +29,7 @@ export const expectedResult = {
name: 'Query #2',
color: 'rgb(255,0,0)',
data: [3, 3],
spanGaps: true,
spanGaps: false,
},
{
id: 'Query #3',
Expand All @@ -38,7 +38,7 @@ export const expectedResult = {
name: 'Query #3',
color: 'rgb(191,0,127)',
data: [4, 4],
spanGaps: true,
spanGaps: false,
},
],
axes: [{scale: 'x', plotLines: [{width: 3, color: '#ffa0a0'}]}],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ function prepareLineTime(options: PrepareFunctionArgs) {
const xFieldIndex = findIndexInOrder(order, xField, idToTitle[xField.guid] || xField.title);
const xFieldIsDate = isDateField(xField);

const yPlaceholderSettings = placeholders[1]?.settings || {};

const yFields = placeholders[1].items;
const yFieldIndexes = yFields.map((yField) =>
findIndexInOrder(order, yField, idToTitle[yField.guid] || yField.title),
Expand Down Expand Up @@ -125,7 +127,11 @@ function prepareLineTime(options: PrepareFunctionArgs) {
if (typeof dataCell === 'object' && dataCell !== null) {
colorValues.forEach((colorValue: QLValue, i) => {
if (typeof dataCell[String(colorValue)] === 'undefined') {
graphs[i].data.push(null);
if (yPlaceholderSettings.nulls === 'as-0') {
graphs[i].data.push(0);
} else {
graphs[i].data.push(null);
}
} else {
graphs[i].data.push(dataCell[String(colorValue)]);
}
Expand Down Expand Up @@ -216,7 +222,7 @@ function prepareLineTime(options: PrepareFunctionArgs) {

result.graphs.forEach((graph, i) => {
graph.color = colorData[i];
graph.spanGaps = true;
graph.spanGaps = yPlaceholderSettings.nulls === 'connect';
});
}

Expand Down
16 changes: 16 additions & 0 deletions src/shared/constants/ql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,19 @@ export const VISUALIZATION_IDS = {
METRIC: 'metric',
TABLE: 'table',
};

export enum QLChartType {
Sql = 'sql',
Promql = 'promql',
Monitoringql = 'monitoringql',
}

export enum QLParamType {
String = 'string',
Number = 'number',
Boolean = 'boolean',
Date = 'date',
Datetime = 'datetime',
DateInterval = 'date-interval',
DatetimeInterval = 'datetime-interval',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type {QLEntryDataShared} from '../../../../types';
import {QlConfigVersions} from '../../../../types/ql/versions';
import {mapQlConfigToLatestVersion} from '../mapQlConfigToLatestVersion';

describe('mapQlConfigToLatestVersion', () => {
it('should return config of the latest version', () => {
const versions = Object.values(QlConfigVersions);

const latest = versions[versions.length - 1];

const config = {} as QLEntryDataShared;

const latestConfig = mapQlConfigToLatestVersion(config);

expect(latestConfig.version).toEqual(latest);
});

it('should use only string versions', () => {
const versions = Object.values(QlConfigVersions);

for (const version of versions) {
expect(typeof version).toBe('string');
}
});
});
63 changes: 63 additions & 0 deletions src/shared/modules/config/ql/__tests__/v1.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {QLEntryDataShared} from '../../../../types';
import {mapUndefinedConfigToV1} from '../v1/mapUndefinedConfigToV1';

describe('mapUndefinedConfigToV1', () => {
it('should set "nulls" setting for y placeholder to connect, if it is ignore', () => {
const config = {
visualization: {
placeholders: [
{id: 'y', settings: {nulls: 'ignore'}},
{id: 'y', settings: {nulls: 'ignore'}},
],
},
version: undefined,
} as unknown as QLEntryDataShared;

const result = mapUndefinedConfigToV1(config);

expect(result).toMatchObject({
version: '1',
visualization: {
placeholders: [
{id: 'y', settings: {nulls: 'connect'}},
{id: 'y', settings: {nulls: 'connect'}},
],
},
});
});

it('should leave "nulls" setting for y placeholder as it is, if it is not ignore', () => {
const config = {
visualization: {
placeholders: [
{id: 'y', settings: {nulls: 'ignore'}},
{id: 'y', settings: {nulls: 'as-0'}},
{id: 'y', settings: {nulls: 'connect'}},
],
},
version: undefined,
} as unknown as QLEntryDataShared;

const result = mapUndefinedConfigToV1(config);

expect(result).toMatchObject({
version: '1',
visualization: {
placeholders: [
{id: 'y', settings: {nulls: 'connect'}},
{id: 'y', settings: {nulls: 'as-0'}},
{id: 'y', settings: {nulls: 'connect'}},
],
},
});
});

it.each([{version: undefined, visualization: {id: 'line'}}, {version: undefined}])(
'should return same config if placeholders does not exists',
(config) => {
const result = mapUndefinedConfigToV1(config as QLEntryDataShared);

expect(result).toMatchObject({...config, version: '1'});
},
);
});
10 changes: 9 additions & 1 deletion src/shared/modules/config/ql/mapQlConfigToLatestVersion.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import type {QlConfig, QlExtendedConfig} from '../../../types';

export const mapQlConfigToLatestVersion = (config: QlExtendedConfig): QlConfig => {
import {mapUndefinedConfigToV1} from './v1/mapUndefinedConfigToV1';

export const mapQlConfigToLatestVersion = (extendedConfig: QlExtendedConfig): QlConfig => {
let config = extendedConfig;

if (typeof config.version === 'undefined') {
config = mapUndefinedConfigToV1(config);
}

return config;
};
41 changes: 41 additions & 0 deletions src/shared/modules/config/ql/v1/mapUndefinedConfigToV1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {PlaceholderId} from '../../../../constants';
import {QLEntryDataShared} from '../../../../types';
import {QlConfigV1} from '../../../../types/config/ql/v1';
import {QlConfigVersions} from '../../../../types/ql/versions';

export const mapUndefinedConfigToV1 = (config: QLEntryDataShared): QlConfigV1 => {
const isPlaceholdersExists = config.visualization && 'placeholders' in config.visualization;

if (!isPlaceholdersExists) {
return {
...config,
version: QlConfigVersions.V1,
};
}

const updatedVisualization = {
...config.visualization,
placeholders: config.visualization.placeholders.map((placeholder) => {
if (placeholder.id === PlaceholderId.Y || placeholder.id === PlaceholderId.Y2) {
return {
...placeholder,
settings: {
...placeholder.settings,
nulls:
placeholder.settings?.nulls === 'ignore'
? 'connect'
: placeholder.settings?.nulls,
},
};
}

return placeholder;
}),
};

return {
...config,
visualization: updatedVisualization,
version: QlConfigVersions.V1,
};
};
56 changes: 29 additions & 27 deletions src/shared/types/config/ql/index.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
import type {
MonitoringPresetV1,
MonitoringPresetV2,
QLEntryDataShared,
QLParam,
QLParamInterval,
QLPreviewTableData,
QLPreviewTableDataColumn,
QLPreviewTableDataRow,
QLQuery,
QLRequestParam,
QLResultEntryMetadataDataColumn,
QLResultEntryMetadataDataColumnOrGroup,
QLResultEntryMetadataDataGroup,
} from '../../ql/common';
import type {MonitoringPresetV1, MonitoringPresetV2, QLEntryDataShared} from '../../ql/common';

export type QlConfig = QLEntryDataShared;
import {
QLParamIntervalV1,
QLParamV1,
QLPreviewTableDataColumnV1,
QLPreviewTableDataRowV1,
QLPreviewTableDataV1,
QLQueryV1,
QLRequestParamV1,
QLResultEntryMetadataDataColumnOrGroupV1,
QLResultEntryMetadataDataColumnV1,
QLResultEntryMetadataDataGroupV1,
QlConfigV1,
} from './v1';

export type QlExtendedConfig = QlConfig;
export type QlConfig = QlConfigV1;

export type QLConfigQuery = QLQuery;
export type QlPreviousConfig = QLEntryDataShared;

export type QlConfigResultEntryMetadataDataGroup = QLResultEntryMetadataDataGroup;
export type QlExtendedConfig = QlConfig | QlPreviousConfig;

export type QlConfigResultEntryMetadataDataColumn = QLResultEntryMetadataDataColumn;
export type QLConfigQuery = QLQueryV1;

export type QlConfigParamInterval = QLParamInterval;
export type QlConfigResultEntryMetadataDataGroup = QLResultEntryMetadataDataGroupV1;

export type QlConfigParam = QLParam;
export type QlConfigResultEntryMetadataDataColumn = QLResultEntryMetadataDataColumnV1;

export type QlConfigRequestParam = QLRequestParam;
export type QlConfigParamInterval = QLParamIntervalV1;

export type QlConfigResultEntryMetadataDataColumnOrGroup = QLResultEntryMetadataDataColumnOrGroup;
export type QlConfigParam = QLParamV1;

export type QlConfigPreviewTableDataColumn = QLPreviewTableDataColumn;
export type QlConfigRequestParam = QLRequestParamV1;

export type QlConfigPreviewTableDataRow = QLPreviewTableDataRow;
export type QlConfigResultEntryMetadataDataColumnOrGroup = QLResultEntryMetadataDataColumnOrGroupV1;

export type QlConfigPreviewTableData = QLPreviewTableData;
export type QlConfigPreviewTableDataColumn = QLPreviewTableDataColumnV1;

export type QlConfigPreviewTableDataRow = QLPreviewTableDataRowV1;

export type QlConfigPreviewTableData = QLPreviewTableDataV1;

export type MonitoringPreset = MonitoringPresetV1 | MonitoringPresetV2;
Loading

0 comments on commit 6a0b27e

Please sign in to comment.