mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 04:35:58 +08:00
fix: column name with legend (#3200)
* fix: column name with legend * fix: render columns with data * fix: index * fix: render rows * fix: remove log * fix: return operators for entiry metric * fix: remove noop and rate for table metric * fix: for request * chore: allow count attribute to be empty --------- Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
This commit is contained in:
parent
a2c03243cb
commit
5469cd34fa
@ -125,7 +125,7 @@ export const initialFilters: TagFilter = {
|
||||
export const initialQueryBuilderFormValues: IBuilderQuery = {
|
||||
dataSource: DataSource.METRICS,
|
||||
queryName: createNewBuilderItemName({ existNames: [], sourceNames: alphabet }),
|
||||
aggregateOperator: MetricAggregateOperator.NOOP,
|
||||
aggregateOperator: MetricAggregateOperator.COUNT,
|
||||
aggregateAttribute: initialAutocompleteData,
|
||||
filters: { items: [], op: 'AND' },
|
||||
expression: createNewBuilderItemName({
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { mapOfOperators, PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { DataSource, StringOperators } from 'types/common/queryBuilder';
|
||||
import {
|
||||
DataSource,
|
||||
MetricAggregateOperator,
|
||||
StringOperators,
|
||||
} from 'types/common/queryBuilder';
|
||||
import { SelectOption } from 'types/common/select';
|
||||
|
||||
type GetQueryOperatorsParams = {
|
||||
@ -19,6 +23,13 @@ export const getOperatorsBySourceAndPanelType = ({
|
||||
(operator) => operator.value === StringOperators.NOOP,
|
||||
);
|
||||
}
|
||||
if (panelType === PANEL_TYPES.TABLE && dataSource === DataSource.METRICS) {
|
||||
operatorsByDataSource = operatorsByDataSource.filter(
|
||||
(operator) =>
|
||||
operator.value !== MetricAggregateOperator.NOOP &&
|
||||
operator.value !== MetricAggregateOperator.RATE,
|
||||
);
|
||||
}
|
||||
if (
|
||||
dataSource !== DataSource.METRICS &&
|
||||
panelType !== PANEL_TYPES.LIST &&
|
||||
|
@ -6,7 +6,6 @@ import {
|
||||
} from 'constants/queryBuilder';
|
||||
import { FORMULA_REGEXP } from 'constants/regExp';
|
||||
import { QueryTableProps } from 'container/QueryTable/QueryTable.intefaces';
|
||||
import { toCapitalize } from 'lib/toCapitalize';
|
||||
import { ReactNode } from 'react';
|
||||
import {
|
||||
IBuilderFormula,
|
||||
@ -145,7 +144,7 @@ const addOperatorFormulaColumns = (
|
||||
let formulaLabel = `${formulaQuery.queryName}(${formulaQuery.expression})`;
|
||||
|
||||
if (formulaQuery.legend) {
|
||||
formulaLabel += ` - ${formulaQuery.legend}`;
|
||||
formulaLabel = formulaQuery.legend;
|
||||
}
|
||||
|
||||
const formulaColumn: DynamicColumn = {
|
||||
@ -171,18 +170,14 @@ const addOperatorFormulaColumns = (
|
||||
}
|
||||
|
||||
if (currentQueryData.legend) {
|
||||
operatorLabel += ` - ${currentQueryData.legend}`;
|
||||
} else {
|
||||
operatorLabel += ` - ${currentQueryData.queryName}`;
|
||||
operatorLabel = currentQueryData.legend;
|
||||
}
|
||||
|
||||
const resultValue = `${toCapitalize(operatorLabel)}`;
|
||||
|
||||
const operatorColumn: DynamicColumn = {
|
||||
query,
|
||||
field: currentQueryData.queryName,
|
||||
dataIndex: currentQueryData.queryName,
|
||||
title: customLabel || resultValue,
|
||||
title: customLabel || operatorLabel,
|
||||
data: [],
|
||||
type: 'operator',
|
||||
// sortable: isNumber,
|
||||
@ -218,26 +213,24 @@ const getDynamicColumns: GetDynamicColumns = (queryTableData, query) => {
|
||||
const dynamicColumns: DynamicColumns = [];
|
||||
|
||||
queryTableData.forEach((currentQuery) => {
|
||||
const { series, queryName, list } = currentQuery;
|
||||
|
||||
const currentStagedQuery = getQueryByName(
|
||||
query.builder,
|
||||
currentQuery.queryName,
|
||||
isFormula(currentQuery.queryName) ? 'queryFormulas' : 'queryData',
|
||||
queryName,
|
||||
isFormula(queryName) ? 'queryFormulas' : 'queryData',
|
||||
);
|
||||
if (currentQuery.list) {
|
||||
currentQuery.list.forEach((listItem) => {
|
||||
if (list) {
|
||||
list.forEach((listItem) => {
|
||||
Object.keys(listItem.data).forEach((label) => {
|
||||
addListLabels(currentStagedQuery, label as ListItemKey, dynamicColumns);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (currentQuery.series) {
|
||||
const isValuesColumnExist = currentQuery.series.some(
|
||||
(item) => item.values.length > 0,
|
||||
);
|
||||
const isEveryValuesExist = currentQuery.series.every(
|
||||
(item) => item.values.length > 0,
|
||||
);
|
||||
if (series) {
|
||||
const isValuesColumnExist = series.some((item) => item.values.length > 0);
|
||||
const isEveryValuesExist = series.every((item) => item.values.length > 0);
|
||||
|
||||
if (isValuesColumnExist) {
|
||||
addOperatorFormulaColumns(
|
||||
@ -247,7 +240,7 @@ const getDynamicColumns: GetDynamicColumns = (queryTableData, query) => {
|
||||
);
|
||||
}
|
||||
|
||||
currentQuery.series.forEach((seria) => {
|
||||
series.forEach((seria) => {
|
||||
Object.keys(seria.labels).forEach((label) => {
|
||||
if (label === currentQuery?.queryName) return;
|
||||
|
||||
@ -277,12 +270,54 @@ const fillEmptyRowCells = (
|
||||
});
|
||||
};
|
||||
|
||||
const fillData = (
|
||||
seria: SeriesItem,
|
||||
columns: DynamicColumns,
|
||||
const findSeriaValueFromAnotherQuery = (
|
||||
currentLabels: Record<string, string>,
|
||||
nextQuery: QueryDataV3 | null,
|
||||
): SeriesItem | null => {
|
||||
if (!nextQuery || !nextQuery.series) return null;
|
||||
|
||||
let value = null;
|
||||
|
||||
const labelEntries = Object.entries(currentLabels);
|
||||
|
||||
nextQuery.series.forEach((seria) => {
|
||||
const localLabelEntries = Object.entries(seria.labels);
|
||||
if (localLabelEntries.length !== labelEntries.length) return;
|
||||
|
||||
const isExistLabels = localLabelEntries.find(([key, value]) =>
|
||||
labelEntries.find(
|
||||
([currentKey, currentValue]) =>
|
||||
currentKey === key && currentValue === value,
|
||||
),
|
||||
);
|
||||
|
||||
if (isExistLabels) {
|
||||
value = seria;
|
||||
}
|
||||
});
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
const isEqualQueriesByLabel = (
|
||||
equalQueries: string[],
|
||||
queryName: string,
|
||||
value?: SeriesItem['values'][number],
|
||||
): boolean => equalQueries.includes(queryName);
|
||||
|
||||
const fillDataFromSeries = (
|
||||
currentQuery: QueryDataV3,
|
||||
queryTableData: QueryDataV3[],
|
||||
columns: DynamicColumns,
|
||||
equalQueriesByLabels: string[],
|
||||
// TODO: fix it
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
): void => {
|
||||
const { series, queryName } = currentQuery;
|
||||
const isEqualQuery = isEqualQueriesByLabel(equalQueriesByLabels, queryName);
|
||||
|
||||
if (!series) return;
|
||||
|
||||
series.forEach((seria) => {
|
||||
const labelEntries = Object.entries(seria.labels);
|
||||
|
||||
const unusedColumnsKeys = new Set<keyof RowData>(
|
||||
@ -290,12 +325,41 @@ const fillData = (
|
||||
);
|
||||
|
||||
columns.forEach((column) => {
|
||||
if (queryName === column.field && value) {
|
||||
column.data.push(parseFloat(value.value).toFixed(2));
|
||||
if (queryName === column.field) {
|
||||
if (seria.values.length === 0) return;
|
||||
|
||||
column.data.push(parseFloat(seria.values[0].value).toFixed(2));
|
||||
unusedColumnsKeys.delete(column.field);
|
||||
return;
|
||||
}
|
||||
|
||||
if (column.type !== 'field' && column.field !== queryName) {
|
||||
const nextQueryData =
|
||||
queryTableData.find((q) => q.queryName === column.field) || null;
|
||||
|
||||
const targetSeria = findSeriaValueFromAnotherQuery(
|
||||
seria.labels,
|
||||
nextQueryData,
|
||||
);
|
||||
|
||||
if (targetSeria) {
|
||||
const isEqual = isEqualQueriesByLabel(equalQueriesByLabels, column.field);
|
||||
if (!isEqual) {
|
||||
equalQueriesByLabels.push(column.field);
|
||||
}
|
||||
|
||||
column.data.push(parseFloat(targetSeria.values[0].value).toFixed(2));
|
||||
} else {
|
||||
column.data.push('N/A');
|
||||
}
|
||||
|
||||
unusedColumnsKeys.delete(column.field);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEqualQuery) return;
|
||||
|
||||
labelEntries.forEach(([key, currentValue]) => {
|
||||
if (column.field === key) {
|
||||
column.data.push(currentValue);
|
||||
@ -305,21 +369,6 @@ const fillData = (
|
||||
|
||||
fillEmptyRowCells(unusedColumnsKeys, columns, column);
|
||||
});
|
||||
};
|
||||
|
||||
const fillDataFromSeria = (
|
||||
seria: SeriesItem,
|
||||
columns: DynamicColumns,
|
||||
queryName: string,
|
||||
): void => {
|
||||
if (seria.values.length === 0) {
|
||||
fillData(seria, columns, queryName);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
seria.values.forEach((value) => {
|
||||
fillData(seria, columns, queryName, value);
|
||||
});
|
||||
};
|
||||
|
||||
@ -348,15 +397,20 @@ const fillColumnsData: FillColumnData = (queryTableData, cols) => {
|
||||
const formulas = cols.filter((item) => item.type === 'formula');
|
||||
const resultColumns = [...fields, ...operators, ...formulas];
|
||||
|
||||
queryTableData.forEach((currentQuery) => {
|
||||
if (currentQuery.series) {
|
||||
currentQuery.series.forEach((seria) => {
|
||||
fillDataFromSeria(seria, resultColumns, currentQuery.queryName);
|
||||
});
|
||||
}
|
||||
const equalQueriesByLabels: string[] = [];
|
||||
|
||||
if (currentQuery.list) {
|
||||
currentQuery.list.forEach((listItem) => {
|
||||
queryTableData.forEach((currentQuery) => {
|
||||
const { list } = currentQuery;
|
||||
|
||||
fillDataFromSeries(
|
||||
currentQuery,
|
||||
queryTableData,
|
||||
resultColumns,
|
||||
equalQueriesByLabels,
|
||||
);
|
||||
|
||||
if (list) {
|
||||
list.forEach((listItem) => {
|
||||
fillDataFromList(listItem, resultColumns);
|
||||
});
|
||||
}
|
||||
|
@ -107,7 +107,8 @@ func (a AggregateOperator) RequireAttribute(dataSource DataSource) bool {
|
||||
switch dataSource {
|
||||
case DataSourceMetrics:
|
||||
switch a {
|
||||
case AggregateOperatorNoOp:
|
||||
case AggregateOperatorNoOp,
|
||||
AggregateOperatorCount:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
|
Loading…
x
Reference in New Issue
Block a user