Skip to content

Commit 49b56b4

Browse files
authored
fix(web): sort line chart data according to time order (#1639)
1 parent e1e94f9 commit 49b56b4

File tree

5 files changed

+47
-21
lines changed

5 files changed

+47
-21
lines changed

web/components/chart/autoChart/advisor/pipeline.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ export const getVisAdvices = (props: { data: Datum[]; myChartAdvisor: Advisor; d
7373
*/
7474
const customDataProps = dataMetaMap
7575
? Object.keys(dataMetaMap).map((item) => {
76-
return { name: item, ...dataMetaMap[item] };
77-
})
76+
return { name: item, ...dataMetaMap[item] };
77+
})
7878
: null;
7979

8080
// 可根据需要选择是否使用全部 fields 进行推荐
@@ -84,11 +84,11 @@ export const getVisAdvices = (props: { data: Datum[]; myChartAdvisor: Advisor; d
8484
const selectedFields =
8585
size(allFieldsInfo) > 2
8686
? allFieldsInfo?.filter((field) => {
87-
if (field.recommendation === 'string' || field.recommendation === 'date') {
88-
return field.distinct && field.distinct > 1;
89-
}
90-
return true;
91-
})
87+
if (field.recommendation === 'string' || field.recommendation === 'date') {
88+
return field.distinct && field.distinct > 1;
89+
}
90+
return true;
91+
})
9292
: allFieldsInfo;
9393

9494
const allAdvices = myChartAdvisor?.adviseWithLog({

web/components/chart/autoChart/charts/multi-line-chart.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { hasSubset, intersects } from '../advisor/utils';
2-
import { findOrdinalField, processDateEncode, findNominalField, isUniqueXValue, getLineSize } from './util';
1+
import { hasSubset } from '../advisor/utils';
2+
import { findOrdinalField, processDateEncode, findNominalField, getLineSize, sortData } from './util';
33
import type { ChartKnowledge, CustomChart, GetChartConfigProps, Specification } from '../types';
44
import type { Datum } from '@antv/ava';
55

6+
const MULTI_LINE_CHART = 'multi_line_chart'
67
const getChartSpec = (data: GetChartConfigProps['data'], dataProps: GetChartConfigProps['dataProps']) => {
78
const ordinalField = findOrdinalField(dataProps);
89
const nominalField = findNominalField(dataProps);
@@ -18,7 +19,7 @@ const getChartSpec = (data: GetChartConfigProps['data'], dataProps: GetChartConf
1819
const spec: Specification = {
1920
type: 'view',
2021
autoFit: true,
21-
data,
22+
data: sortData({ data, chartType: MULTI_LINE_CHART, xField: field4X }),
2223
children: [],
2324
};
2425

@@ -43,7 +44,7 @@ const getChartSpec = (data: GetChartConfigProps['data'], dataProps: GetChartConf
4344
};
4445

4546
const ckb: ChartKnowledge = {
46-
id: 'multi_line_chart',
47+
id: MULTI_LINE_CHART,
4748
name: 'multi_line_chart',
4849
alias: ['multi_line_chart'],
4950
family: ['LineCharts'],

web/components/chart/autoChart/charts/multi-measure-line-chart.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { hasSubset } from '../advisor/utils';
2-
import { findNominalField, findOrdinalField, getLineSize, processDateEncode } from './util';
2+
import { findNominalField, findOrdinalField, getLineSize, processDateEncode, sortData } from './util';
33
import type { ChartKnowledge, CustomChart, GetChartConfigProps, Specification } from '../types';
44
import { Datum } from '@antv/ava';
55

6+
const MULTI_MEASURE_LINE_CHART = 'multi_measure_line_chart'
67
const getChartSpec = (data: GetChartConfigProps['data'], dataProps: GetChartConfigProps['dataProps']) => {
78
try {
89
// @ts-ignore
@@ -12,7 +13,7 @@ const getChartSpec = (data: GetChartConfigProps['data'], dataProps: GetChartConf
1213

1314
const spec: Specification = {
1415
type: 'view',
15-
data,
16+
data: sortData({ data, chartType: MULTI_MEASURE_LINE_CHART, xField: field4Nominal }),
1617
children: [],
1718
};
1819

@@ -40,7 +41,7 @@ const getChartSpec = (data: GetChartConfigProps['data'], dataProps: GetChartConf
4041
};
4142

4243
const ckb: ChartKnowledge = {
43-
id: 'multi_measure_line_chart',
44+
id: MULTI_MEASURE_LINE_CHART,
4445
name: 'multi_measure_line_chart',
4546
alias: ['multi_measure_line_chart'],
4647
family: ['LineCharts'],

web/components/chart/autoChart/charts/util.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
import { Datum, FieldInfo } from '@antv/ava';
2-
import { hasSubset, intersects } from '../advisor/utils';
3-
import { uniq } from 'lodash';
4-
5-
type BasicDataPropertyForAdvice = any;
1+
import type { Datum, FieldInfo } from "@antv/ava";
2+
import { hasSubset, intersects } from "../advisor/utils";
3+
import { cloneDeep, uniq } from "lodash";
64

75
/**
86
* Process date column to new Date().
97
* @param field
108
* @param dataProps
119
* @returns
1210
*/
13-
export function processDateEncode(field: string, dataProps: BasicDataPropertyForAdvice[]) {
11+
export function processDateEncode(field: string, dataProps: FieldInfo[]) {
1412
const dp = dataProps.find((dataProp) => dataProp.name === field);
1513

1614
if (dp?.recommendation === 'date') {
@@ -50,3 +48,21 @@ export const getLineSize = (
5048
}
5149
return field4X?.name && isUniqueXValue({ data: allData, xField: field4X.name }) ? 5 : undefined;
5250
};
51+
52+
export const sortData = ({ data, chartType, xField }: {
53+
data: Datum[];
54+
xField?: FieldInfo;
55+
chartType: string;
56+
}) => {
57+
const sortedData = cloneDeep(data)
58+
try {
59+
// 折线图绘制需要将数据点按照日期从小到大的顺序排序和连线
60+
if (chartType.includes('line') && xField?.name && xField.recommendation === 'date') {
61+
sortedData.sort((datum1, datum2) => new Date(datum1[xField.name as string]).getTime() - new Date(datum2[xField.name as string]).getTime())
62+
return sortedData
63+
}
64+
} catch (err) {
65+
console.error(err)
66+
}
67+
return sortedData
68+
}

web/components/chart/autoChart/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { AutoChartProps, ChartType, CustomAdvisorConfig, CustomChart, Specificat
99
import { customCharts } from './charts';
1010
import { ChatContext } from '@/app/chat-context';
1111
import { compact, concat, uniq } from 'lodash';
12+
import { sortData } from './charts/util';
1213

1314
const { Option } = Select;
1415

@@ -81,14 +82,21 @@ export const AutoChart = (props: AutoChartProps) => {
8182
setAdvices(allAdvices);
8283
setRenderChartType(allAdvices[0]?.type as ChartType);
8384
}
84-
}, [data, advisor, chartType]);
85+
}, [JSON.stringify(data), advisor, chartType]);
8586

8687
const visComponent = useMemo(() => {
8788
/* Advices exist, render the chart. */
8889
if (advices?.length > 0) {
8990
const chartTypeInput = renderChartType ?? advices[0].type;
9091
const spec: Specification = advices?.find((item: Advice) => item.type === chartTypeInput)?.spec ?? undefined;
9192
if (spec) {
93+
if (spec.data && ['line_chart', 'step_line_chart'].includes(chartTypeInput)) {
94+
// 处理 ava 内置折线图的排序问题
95+
const dataAnalyzerOutput = advisor?.dataAnalyzer.execute({ data })
96+
if (dataAnalyzerOutput && 'dataProps' in dataAnalyzerOutput) {
97+
spec.data = sortData({ data: spec.data, xField: dataAnalyzerOutput.dataProps?.find(field => field.recommendation === 'date'), chartType: chartTypeInput });
98+
}
99+
}
92100
return (
93101
<Chart
94102
key={chartTypeInput}

0 commit comments

Comments
 (0)