part 2 of filter/sort drill down from charts (#16013)
in this PR, we will handle simple filter translations (ie, fields that use the contains operand)
This commit is contained in:
+47
@@ -0,0 +1,47 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type UrlFilterGroup } from './mapRecordFilterGroupToUrlFilterGroup';
|
||||
|
||||
export const appendNestedUrlFilterGroupsToQueryParams = (
|
||||
urlFilterGroups: UrlFilterGroup[],
|
||||
queryParamsPrefix: string,
|
||||
targetQueryParams: URLSearchParams,
|
||||
): void => {
|
||||
for (const [groupIndex, urlFilterGroup] of urlFilterGroups.entries()) {
|
||||
const currentGroupPrefix = `${queryParamsPrefix}[${groupIndex}]`;
|
||||
targetQueryParams.set(
|
||||
`${currentGroupPrefix}[operator]`,
|
||||
urlFilterGroup.operator,
|
||||
);
|
||||
|
||||
if (isDefined(urlFilterGroup.filters)) {
|
||||
for (const [filterIndex, urlFilter] of urlFilterGroup.filters.entries()) {
|
||||
targetQueryParams.set(
|
||||
`${currentGroupPrefix}[filters][${filterIndex}][field]`,
|
||||
urlFilter.field,
|
||||
);
|
||||
targetQueryParams.set(
|
||||
`${currentGroupPrefix}[filters][${filterIndex}][op]`,
|
||||
urlFilter.op,
|
||||
);
|
||||
targetQueryParams.set(
|
||||
`${currentGroupPrefix}[filters][${filterIndex}][value]`,
|
||||
urlFilter.value,
|
||||
);
|
||||
if (isDefined(urlFilter.subField)) {
|
||||
targetQueryParams.set(
|
||||
`${currentGroupPrefix}[filters][${filterIndex}][subField]`,
|
||||
urlFilter.subField,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(urlFilterGroup.groups)) {
|
||||
appendNestedUrlFilterGroupsToQueryParams(
|
||||
urlFilterGroup.groups,
|
||||
`${currentGroupPrefix}[groups]`,
|
||||
targetQueryParams,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
import { type BuildChartDrilldownQueryParamsInput } from '@/page-layout/widgets/graph/types/BuildChartDrilldownQueryParamsInput';
|
||||
import { buildFilterFromChartBucket } from '@/page-layout/widgets/graph/utils/buildFilterFromChartBucket';
|
||||
import { buildFilterQueryParams } from '@/page-layout/widgets/graph/utils/buildFilterQueryParams';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const buildChartDrilldownQueryParams = ({
|
||||
objectMetadataItem,
|
||||
configuration,
|
||||
clickedData,
|
||||
viewId,
|
||||
timezone,
|
||||
}: BuildChartDrilldownQueryParamsInput): URLSearchParams => {
|
||||
const drilldownQueryParams = new URLSearchParams();
|
||||
|
||||
if (isDefined(configuration.filter)) {
|
||||
const chartFilterParams = buildFilterQueryParams({
|
||||
recordFilters: configuration.filter.recordFilters ?? [],
|
||||
recordFilterGroups: configuration.filter.recordFilterGroups ?? [],
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
chartFilterParams.forEach((value, key) => {
|
||||
drilldownQueryParams.append(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
const primaryField = objectMetadataItem.fields.find(
|
||||
(field) => field.id === configuration.primaryAxisGroupByFieldMetadataId,
|
||||
);
|
||||
|
||||
if (isDefined(primaryField)) {
|
||||
const primaryFilters = buildFilterFromChartBucket({
|
||||
fieldMetadataItem: primaryField,
|
||||
bucketRawValue: clickedData.primaryBucketRawValue,
|
||||
dateGranularity: configuration.primaryAxisDateGranularity,
|
||||
subFieldName: configuration.primaryAxisGroupBySubFieldName,
|
||||
timezone,
|
||||
});
|
||||
|
||||
primaryFilters.forEach((filter) => {
|
||||
drilldownQueryParams.append(
|
||||
`filter[${filter.fieldName}][${filter.operand}]`,
|
||||
filter.value,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (isDefined(viewId)) {
|
||||
drilldownQueryParams.set('viewId', viewId);
|
||||
}
|
||||
|
||||
return drilldownQueryParams;
|
||||
};
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import {
|
||||
ViewFilterOperand,
|
||||
type ObjectRecordGroupByDateGranularity,
|
||||
} from 'twenty-shared/types';
|
||||
import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
type ChartFilter = {
|
||||
fieldName: string;
|
||||
operand: ViewFilterOperand;
|
||||
value: string;
|
||||
};
|
||||
|
||||
type BuildFilterFromChartBucketParams = {
|
||||
fieldMetadataItem: FieldMetadataItem;
|
||||
bucketRawValue: unknown;
|
||||
dateGranularity?: ObjectRecordGroupByDateGranularity | null; // TODO: Will be used for date filtering
|
||||
subFieldName?: string | null;
|
||||
timezone?: string; // TODO: Will be used for date filtering
|
||||
};
|
||||
|
||||
const formatChartFilterValue = (
|
||||
fieldType: FieldMetadataType,
|
||||
bucketRawValue: unknown,
|
||||
operand: ViewFilterOperand,
|
||||
): string => {
|
||||
const stringValue = String(bucketRawValue);
|
||||
|
||||
const needsJsonArray =
|
||||
operand === ViewFilterOperand.IS &&
|
||||
[
|
||||
FieldMetadataType.SELECT,
|
||||
FieldMetadataType.UUID,
|
||||
FieldMetadataType.RELATION,
|
||||
].includes(fieldType);
|
||||
|
||||
return needsJsonArray ? JSON.stringify([stringValue]) : stringValue;
|
||||
};
|
||||
|
||||
export const buildFilterFromChartBucket = ({
|
||||
fieldMetadataItem,
|
||||
bucketRawValue,
|
||||
subFieldName,
|
||||
}: BuildFilterFromChartBucketParams): ChartFilter[] => {
|
||||
const fieldName = isNonEmptyString(subFieldName)
|
||||
? `${fieldMetadataItem.name}.${subFieldName}`
|
||||
: fieldMetadataItem.name;
|
||||
|
||||
if (!isDefined(bucketRawValue) || !isNonEmptyString(String(bucketRawValue))) {
|
||||
return [
|
||||
{
|
||||
fieldName,
|
||||
operand: ViewFilterOperand.IS_EMPTY,
|
||||
value: '',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const availableOperands = getRecordFilterOperands({
|
||||
filterType: getFilterTypeFromFieldType(fieldMetadataItem.type),
|
||||
subFieldName: subFieldName ?? undefined,
|
||||
});
|
||||
|
||||
if (availableOperands.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const operand = availableOperands[0];
|
||||
|
||||
const value = formatChartFilterValue(
|
||||
fieldMetadataItem.type,
|
||||
bucketRawValue,
|
||||
operand,
|
||||
);
|
||||
|
||||
return [
|
||||
{
|
||||
fieldName,
|
||||
operand,
|
||||
value,
|
||||
},
|
||||
];
|
||||
};
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { appendNestedUrlFilterGroupsToQueryParams } from './appendNestedUrlFilterGroupsToQueryParams';
|
||||
import { mapRecordFilterToUrlFilter } from './mapRecordFilterToUrlFilter';
|
||||
import { mapRecordFilterGroupToUrlFilterGroup } from './mapRecordFilterGroupToUrlFilterGroup';
|
||||
|
||||
export const buildFilterQueryParams = ({
|
||||
recordFilters = [],
|
||||
recordFilterGroups = [],
|
||||
objectMetadataItem,
|
||||
}: {
|
||||
recordFilters?: RecordFilter[];
|
||||
recordFilterGroups?: RecordFilterGroup[];
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
}): URLSearchParams => {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
const rootGroup = recordFilterGroups.find(
|
||||
(group) => !isDefined(group.parentRecordFilterGroupId),
|
||||
);
|
||||
|
||||
if (isDefined(rootGroup)) {
|
||||
const urlFilterGroup = mapRecordFilterGroupToUrlFilterGroup({
|
||||
recordFilterGroupId: rootGroup.id,
|
||||
allRecordFilters: recordFilters,
|
||||
allRecordFilterGroups: recordFilterGroups,
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
if (isDefined(urlFilterGroup)) {
|
||||
params.set('filterGroup[operator]', urlFilterGroup.operator);
|
||||
|
||||
if (isDefined(urlFilterGroup.filters)) {
|
||||
for (const [index, filter] of urlFilterGroup.filters.entries()) {
|
||||
params.set(`filterGroup[filters][${index}][field]`, filter.field);
|
||||
params.set(`filterGroup[filters][${index}][op]`, filter.op);
|
||||
params.set(`filterGroup[filters][${index}][value]`, filter.value);
|
||||
if (isDefined(filter.subField)) {
|
||||
params.set(
|
||||
`filterGroup[filters][${index}][subField]`,
|
||||
filter.subField,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(urlFilterGroup.groups)) {
|
||||
appendNestedUrlFilterGroupsToQueryParams(
|
||||
urlFilterGroup.groups,
|
||||
'filterGroup[groups]',
|
||||
params,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const parentlessFilters = recordFilters.filter(
|
||||
(filter) => !isDefined(filter.recordFilterGroupId),
|
||||
);
|
||||
|
||||
for (const filter of parentlessFilters) {
|
||||
const urlFilter = mapRecordFilterToUrlFilter({
|
||||
recordFilter: filter,
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
if (isDefined(urlFilter)) {
|
||||
const fieldName = isDefined(urlFilter.subField)
|
||||
? `${urlFilter.field}.${urlFilter.subField}`
|
||||
: urlFilter.field;
|
||||
|
||||
params.append(`filter[${fieldName}][${urlFilter.op}]`, urlFilter.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
};
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { type RawDimensionValue } from '@/page-layout/widgets/graph/types/RawDimensionValue';
|
||||
import { type FormattedDimensionValue } from '@/page-layout/widgets/graph/utils/formatPrimaryDimensionValues';
|
||||
|
||||
export const buildFormattedToRawLookup = (
|
||||
formattedValues: FormattedDimensionValue[],
|
||||
): Map<string, RawDimensionValue> => {
|
||||
const lookup = new Map<string, RawDimensionValue>();
|
||||
|
||||
formattedValues.forEach(
|
||||
({ formattedPrimaryDimensionValue, rawPrimaryDimensionValue }) => {
|
||||
if (!lookup.has(formattedPrimaryDimensionValue)) {
|
||||
lookup.set(formattedPrimaryDimensionValue, rawPrimaryDimensionValue);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return lookup;
|
||||
};
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { type GroupByRawResult } from '@/page-layout/widgets/graph/types/GroupByRawResult';
|
||||
import { type RawDimensionValue } from '@/page-layout/widgets/graph/types/RawDimensionValue';
|
||||
import { formatDimensionValue } from '@/page-layout/widgets/graph/utils/formatDimensionValue';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type ObjectRecordGroupByDateGranularity } from '~/generated/graphql';
|
||||
|
||||
type FormatPrimaryDimensionValuesParameters = {
|
||||
groupByRawResults: GroupByRawResult[];
|
||||
primaryAxisGroupByField: FieldMetadataItem;
|
||||
primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity;
|
||||
primaryAxisGroupBySubFieldName?: string;
|
||||
};
|
||||
|
||||
export type FormattedDimensionValue = {
|
||||
formattedPrimaryDimensionValue: string;
|
||||
rawPrimaryDimensionValue: RawDimensionValue;
|
||||
};
|
||||
|
||||
export const formatPrimaryDimensionValues = ({
|
||||
groupByRawResults,
|
||||
primaryAxisGroupByField,
|
||||
primaryAxisDateGranularity,
|
||||
primaryAxisGroupBySubFieldName,
|
||||
}: FormatPrimaryDimensionValuesParameters): FormattedDimensionValue[] => {
|
||||
return groupByRawResults.reduce<FormattedDimensionValue[]>(
|
||||
(accumulator, rawResult) => {
|
||||
const groupByDimensionValues = rawResult.groupByDimensionValues;
|
||||
|
||||
if (!isDefined(groupByDimensionValues?.[0])) {
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
const rawPrimaryDimensionValue =
|
||||
groupByDimensionValues[0] as RawDimensionValue;
|
||||
|
||||
const formattedPrimaryDimensionValue = formatDimensionValue({
|
||||
value: rawPrimaryDimensionValue,
|
||||
fieldMetadata: primaryAxisGroupByField,
|
||||
dateGranularity: primaryAxisDateGranularity,
|
||||
subFieldName: primaryAxisGroupBySubFieldName,
|
||||
});
|
||||
|
||||
return [
|
||||
...accumulator,
|
||||
{
|
||||
formattedPrimaryDimensionValue,
|
||||
rawPrimaryDimensionValue,
|
||||
},
|
||||
];
|
||||
},
|
||||
[],
|
||||
);
|
||||
};
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
mapRecordFilterToUrlFilter,
|
||||
type UrlFilter,
|
||||
} from './mapRecordFilterToUrlFilter';
|
||||
|
||||
export type UrlFilterGroup = {
|
||||
operator: string;
|
||||
filters?: UrlFilter[];
|
||||
groups?: UrlFilterGroup[];
|
||||
};
|
||||
|
||||
export const mapRecordFilterGroupToUrlFilterGroup = ({
|
||||
recordFilterGroupId,
|
||||
allRecordFilters,
|
||||
allRecordFilterGroups,
|
||||
objectMetadataItem,
|
||||
}: {
|
||||
recordFilterGroupId: string;
|
||||
allRecordFilters: RecordFilter[];
|
||||
allRecordFilterGroups: RecordFilterGroup[];
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
}): UrlFilterGroup | null => {
|
||||
const currentGroup = allRecordFilterGroups.find(
|
||||
(group) => group.id === recordFilterGroupId,
|
||||
);
|
||||
|
||||
if (!isDefined(currentGroup)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const urlFilterGroup: UrlFilterGroup = {
|
||||
operator: currentGroup.logicalOperator,
|
||||
};
|
||||
|
||||
const filtersInGroup = allRecordFilters
|
||||
.filter((filter) => filter.recordFilterGroupId === recordFilterGroupId)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(a.positionInRecordFilterGroup ?? 0) -
|
||||
(b.positionInRecordFilterGroup ?? 0),
|
||||
);
|
||||
|
||||
if (filtersInGroup.length > 0) {
|
||||
const urlFilters = filtersInGroup
|
||||
.map((filter) =>
|
||||
mapRecordFilterToUrlFilter({
|
||||
recordFilter: filter,
|
||||
objectMetadataItem,
|
||||
}),
|
||||
)
|
||||
.filter(isDefined);
|
||||
|
||||
if (urlFilters.length > 0) {
|
||||
urlFilterGroup.filters = urlFilters;
|
||||
}
|
||||
}
|
||||
|
||||
const childGroups = allRecordFilterGroups
|
||||
.filter((group) => group.parentRecordFilterGroupId === recordFilterGroupId)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(a.positionInRecordFilterGroup ?? 0) -
|
||||
(b.positionInRecordFilterGroup ?? 0),
|
||||
);
|
||||
|
||||
if (childGroups.length > 0) {
|
||||
const urlChildGroups = childGroups
|
||||
.map((childGroup) =>
|
||||
mapRecordFilterGroupToUrlFilterGroup({
|
||||
recordFilterGroupId: childGroup.id,
|
||||
allRecordFilters,
|
||||
allRecordFilterGroups,
|
||||
objectMetadataItem,
|
||||
}),
|
||||
)
|
||||
.filter(isDefined);
|
||||
|
||||
if (urlChildGroups.length > 0) {
|
||||
urlFilterGroup.groups = urlChildGroups;
|
||||
}
|
||||
}
|
||||
|
||||
return urlFilterGroup;
|
||||
};
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export type UrlFilter = {
|
||||
field: string;
|
||||
op: string;
|
||||
value: string;
|
||||
subField?: string;
|
||||
};
|
||||
|
||||
export const mapRecordFilterToUrlFilter = ({
|
||||
recordFilter,
|
||||
objectMetadataItem,
|
||||
}: {
|
||||
recordFilter: RecordFilter;
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
}): UrlFilter | null => {
|
||||
const fieldMetadataItem = objectMetadataItem.fields.find(
|
||||
(field) => field.id === recordFilter.fieldMetadataId,
|
||||
);
|
||||
|
||||
if (!isDefined(fieldMetadataItem)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const urlFilter: UrlFilter = {
|
||||
field: fieldMetadataItem.name,
|
||||
op: recordFilter.operand,
|
||||
value: recordFilter.value,
|
||||
};
|
||||
|
||||
if (isNonEmptyString(recordFilter.subFieldName)) {
|
||||
urlFilter.subField = recordFilter.subFieldName;
|
||||
}
|
||||
|
||||
return urlFilter;
|
||||
};
|
||||
+4
@@ -5,6 +5,7 @@ import { type ExtendedAggregateOperations } from '@/object-record/record-table/t
|
||||
import { getGroupByQueryResultGqlFieldName } from '@/page-layout/utils/getGroupByQueryResultGqlFieldName';
|
||||
import { type LineChartSeries } from '@/page-layout/widgets/graph/graphWidgetLineChart/types/LineChartSeries';
|
||||
import { type GroupByRawResult } from '@/page-layout/widgets/graph/types/GroupByRawResult';
|
||||
import { type RawDimensionValue } from '@/page-layout/widgets/graph/types/RawDimensionValue';
|
||||
import { filterGroupByResults } from '@/page-layout/widgets/graph/utils/filterGroupByResults';
|
||||
import { transformOneDimensionalGroupByToLineChartData } from '@/page-layout/widgets/graph/utils/transformOneDimensionalGroupByToLineChartData';
|
||||
import { transformTwoDimensionalGroupByToLineChartData } from '@/page-layout/widgets/graph/utils/transformTwoDimensionalGroupByToLineChartData';
|
||||
@@ -27,6 +28,7 @@ type TransformGroupByDataToLineChartDataResult = {
|
||||
yAxisLabel?: string;
|
||||
showDataLabels: boolean;
|
||||
hasTooManyGroups: boolean;
|
||||
formattedToRawLookup: Map<string, RawDimensionValue>;
|
||||
};
|
||||
|
||||
const EMPTY_LINE_CHART_RESULT: TransformGroupByDataToLineChartDataResult = {
|
||||
@@ -35,6 +37,7 @@ const EMPTY_LINE_CHART_RESULT: TransformGroupByDataToLineChartDataResult = {
|
||||
yAxisLabel: undefined,
|
||||
showDataLabels: false,
|
||||
hasTooManyGroups: false,
|
||||
formattedToRawLookup: new Map(),
|
||||
};
|
||||
|
||||
export const transformGroupByDataToLineChartData = ({
|
||||
@@ -137,5 +140,6 @@ export const transformGroupByDataToLineChartData = ({
|
||||
xAxisLabel,
|
||||
yAxisLabel,
|
||||
showDataLabels,
|
||||
formattedToRawLookup: baseResult.formattedToRawLookup,
|
||||
};
|
||||
};
|
||||
|
||||
+15
@@ -7,6 +7,9 @@ import { type LineChartDataPoint } from '@/page-layout/widgets/graph/graphWidget
|
||||
import { type LineChartSeries } from '@/page-layout/widgets/graph/graphWidgetLineChart/types/LineChartSeries';
|
||||
import { type GraphColor } from '@/page-layout/widgets/graph/types/GraphColor';
|
||||
import { type GroupByRawResult } from '@/page-layout/widgets/graph/types/GroupByRawResult';
|
||||
import { type RawDimensionValue } from '@/page-layout/widgets/graph/types/RawDimensionValue';
|
||||
import { buildFormattedToRawLookup } from '@/page-layout/widgets/graph/utils/buildFormattedToRawLookup';
|
||||
import { formatPrimaryDimensionValues } from '@/page-layout/widgets/graph/utils/formatPrimaryDimensionValues';
|
||||
import { computeAggregateValueFromGroupByResult } from '@/page-layout/widgets/graph/utils/computeAggregateValueFromGroupByResult';
|
||||
import { formatDimensionValue } from '@/page-layout/widgets/graph/utils/formatDimensionValue';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -25,6 +28,7 @@ type TransformOneDimensionalGroupByToLineChartDataParams = {
|
||||
type TransformOneDimensionalGroupByToLineChartDataResult = {
|
||||
series: LineChartSeries[];
|
||||
hasTooManyGroups: boolean;
|
||||
formattedToRawLookup: Map<string, RawDimensionValue>;
|
||||
};
|
||||
|
||||
export const transformOneDimensionalGroupByToLineChartData = ({
|
||||
@@ -42,6 +46,16 @@ export const transformOneDimensionalGroupByToLineChartData = ({
|
||||
LINE_CHART_MAXIMUM_NUMBER_OF_DATA_POINTS,
|
||||
);
|
||||
|
||||
const formattedValues = formatPrimaryDimensionValues({
|
||||
groupByRawResults: limitedResults,
|
||||
primaryAxisGroupByField: groupByFieldX,
|
||||
primaryAxisDateGranularity:
|
||||
configuration.primaryAxisDateGranularity ?? undefined,
|
||||
primaryAxisGroupBySubFieldName: primaryAxisSubFieldName ?? undefined,
|
||||
});
|
||||
|
||||
const formattedToRawLookup = buildFormattedToRawLookup(formattedValues);
|
||||
|
||||
const data: LineChartDataPoint[] = limitedResults
|
||||
.map((result) => {
|
||||
const dimensionValues = result.groupByDimensionValues;
|
||||
@@ -90,5 +104,6 @@ export const transformOneDimensionalGroupByToLineChartData = ({
|
||||
series,
|
||||
hasTooManyGroups:
|
||||
rawResults.length > LINE_CHART_MAXIMUM_NUMBER_OF_DATA_POINTS,
|
||||
formattedToRawLookup,
|
||||
};
|
||||
};
|
||||
|
||||
+16
-1
@@ -6,6 +6,9 @@ import { type LineChartDataPoint } from '@/page-layout/widgets/graph/graphWidget
|
||||
import { type LineChartSeries } from '@/page-layout/widgets/graph/graphWidgetLineChart/types/LineChartSeries';
|
||||
import { type GraphColor } from '@/page-layout/widgets/graph/types/GraphColor';
|
||||
import { type GroupByRawResult } from '@/page-layout/widgets/graph/types/GroupByRawResult';
|
||||
import { type RawDimensionValue } from '@/page-layout/widgets/graph/types/RawDimensionValue';
|
||||
import { buildFormattedToRawLookup } from '@/page-layout/widgets/graph/utils/buildFormattedToRawLookup';
|
||||
import { formatPrimaryDimensionValues } from '@/page-layout/widgets/graph/utils/formatPrimaryDimensionValues';
|
||||
import { computeAggregateValueFromGroupByResult } from '@/page-layout/widgets/graph/utils/computeAggregateValueFromGroupByResult';
|
||||
import { formatDimensionValue } from '@/page-layout/widgets/graph/utils/formatDimensionValue';
|
||||
import { sortLineChartSeries } from '@/page-layout/widgets/graph/utils/sortLineChartSeries';
|
||||
@@ -26,6 +29,7 @@ type TransformTwoDimensionalGroupByToLineChartDataParams = {
|
||||
type TransformTwoDimensionalGroupByToLineChartDataResult = {
|
||||
series: LineChartSeries[];
|
||||
hasTooManyGroups: boolean;
|
||||
formattedToRawLookup: Map<string, RawDimensionValue>;
|
||||
};
|
||||
|
||||
export const transformTwoDimensionalGroupByToLineChartData = ({
|
||||
@@ -41,6 +45,14 @@ export const transformTwoDimensionalGroupByToLineChartData = ({
|
||||
const seriesMap = new Map<string, Map<string, number>>();
|
||||
const allXValues: string[] = [];
|
||||
const xValueSet = new Set<string>();
|
||||
const formattedValues = formatPrimaryDimensionValues({
|
||||
groupByRawResults: rawResults,
|
||||
primaryAxisGroupByField: groupByFieldX,
|
||||
primaryAxisDateGranularity:
|
||||
configuration.primaryAxisDateGranularity ?? undefined,
|
||||
primaryAxisGroupBySubFieldName: primaryAxisSubFieldName ?? undefined,
|
||||
});
|
||||
const formattedToRawLookup = buildFormattedToRawLookup(formattedValues);
|
||||
let hasTooManyGroups = false;
|
||||
|
||||
rawResults.forEach((result) => {
|
||||
@@ -70,8 +82,10 @@ export const transformTwoDimensionalGroupByToLineChartData = ({
|
||||
allXValues.push(xValue);
|
||||
}
|
||||
|
||||
const seriesRawValue = dimensionValues[1];
|
||||
|
||||
const seriesKey = formatDimensionValue({
|
||||
value: dimensionValues[1],
|
||||
value: seriesRawValue,
|
||||
fieldMetadata: groupByFieldY,
|
||||
dateGranularity:
|
||||
configuration.secondaryAxisGroupByDateGranularity ?? undefined,
|
||||
@@ -120,5 +134,6 @@ export const transformTwoDimensionalGroupByToLineChartData = ({
|
||||
return {
|
||||
series,
|
||||
hasTooManyGroups,
|
||||
formattedToRawLookup,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user