From 083becde08e30e329f9373704ab8d4dbbafda3b7 Mon Sep 17 00:00:00 2001
From: chenluli <chenluuli@gmail.com>
Date: Wed, 17 Jul 2024 16:40:42 +0800
Subject: [PATCH] fix(web): fix line chart using interval field as xAxis & fix
 pie chart tooltip (#1697)

---
 .../chart/autoChart/charts/multi-line-chart.ts        | 11 ++++++-----
 .../autoChart/charts/multi-measure-line-chart.ts      |  5 +++--
 web/components/chart/autoChart/charts/util.ts         |  5 +++++
 web/components/chart/autoChart/index.tsx              |  4 ++++
 4 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/web/components/chart/autoChart/charts/multi-line-chart.ts b/web/components/chart/autoChart/charts/multi-line-chart.ts
index 051f17e67..574a6dd72 100644
--- a/web/components/chart/autoChart/charts/multi-line-chart.ts
+++ b/web/components/chart/autoChart/charts/multi-line-chart.ts
@@ -7,12 +7,13 @@ const MULTI_LINE_CHART = 'multi_line_chart'
 const getChartSpec = (data: GetChartConfigProps['data'], dataProps: GetChartConfigProps['dataProps']) => {
   const ordinalField = findOrdinalField(dataProps);
   const nominalField = findNominalField(dataProps);
-  // 放宽折线图的 x 轴条件,优先选择 time, ordinal 类型,没有的话使用 nominal 类型
-  const field4X = ordinalField ?? nominalField;
+  // 放宽折线图的 x 轴条件,优先选择 time, ordinal, nominal 类型,没有的话使用第一个字段作兜底
+  const field4X = ordinalField ?? nominalField ?? dataProps[0];
+  const remainFields = dataProps.filter((field) => field.name !== field4X?.name);
 
-  const field4Y = dataProps.filter((field) => field.levelOfMeasurements && hasSubset(field.levelOfMeasurements, ['Interval']));
-  const field4Nominal = dataProps.find(
-    (field) => field.name !== field4X?.name && field.levelOfMeasurements && hasSubset(field.levelOfMeasurements, ['Nominal']),
+  const field4Y = remainFields.filter((field) => field.levelOfMeasurements && hasSubset(field.levelOfMeasurements, ['Interval'])) ?? [remainFields[0]];
+  const field4Nominal = remainFields.filter(field => !field4Y.find(y => y.name === field.name)).find(
+    (field) => field.levelOfMeasurements && hasSubset(field.levelOfMeasurements, ['Nominal']),
   );
   if (!field4X || !field4Y) return null;
 
diff --git a/web/components/chart/autoChart/charts/multi-measure-line-chart.ts b/web/components/chart/autoChart/charts/multi-measure-line-chart.ts
index 8f6904592..f15c20772 100644
--- a/web/components/chart/autoChart/charts/multi-measure-line-chart.ts
+++ b/web/components/chart/autoChart/charts/multi-measure-line-chart.ts
@@ -6,9 +6,10 @@ import { Datum } from '@antv/ava';
 const MULTI_MEASURE_LINE_CHART = 'multi_measure_line_chart'
 const getChartSpec = (data: GetChartConfigProps['data'], dataProps: GetChartConfigProps['dataProps']) => {
   try {
+    // 优先确认 x 轴,如果没有枚举类型字段,取第一个字段为 x 轴
+    const field4Nominal = findNominalField(dataProps) ?? findOrdinalField(dataProps) ?? dataProps[0];
     // @ts-ignore
-    const field4Y = dataProps?.filter((field) => hasSubset(field.levelOfMeasurements, ['Interval']));
-    const field4Nominal = findNominalField(dataProps) ?? findOrdinalField(dataProps);
+    const field4Y = dataProps?.filter((field) => field.name !== field4Nominal?.name && hasSubset(field.levelOfMeasurements, ['Interval']));
     if (!field4Nominal || !field4Y) return null;
 
     const spec: Specification = {
diff --git a/web/components/chart/autoChart/charts/util.ts b/web/components/chart/autoChart/charts/util.ts
index bf4b121b3..850222333 100644
--- a/web/components/chart/autoChart/charts/util.ts
+++ b/web/components/chart/autoChart/charts/util.ts
@@ -61,6 +61,11 @@ export const sortData = ({ data, chartType, xField }: {
       sortedData.sort((datum1, datum2) => new Date(datum1[xField.name as string]).getTime() - new Date(datum2[xField.name as string]).getTime())
       return sortedData
     }
+    // 如果折线图横轴是数值类型,则按照数值大小排序
+    if (chartType.includes('line') && xField?.name && ['float', 'integer'].includes(xField.recommendation)) {
+      sortedData.sort((datum1, datum2) => (datum1[xField.name as string] as number) - (datum2[xField.name as string] as number))
+      return sortedData
+    }
   } catch (err) {
     console.error(err)
   }
diff --git a/web/components/chart/autoChart/index.tsx b/web/components/chart/autoChart/index.tsx
index 021dc6e44..cfab3df7c 100644
--- a/web/components/chart/autoChart/index.tsx
+++ b/web/components/chart/autoChart/index.tsx
@@ -102,6 +102,10 @@ export const AutoChart = (props: AutoChartProps) => {
             spec.data = sortData({ data: spec.data, xField: dataAnalyzerOutput.dataProps?.find(field => field.recommendation === 'date'), chartType: chartTypeInput });
           }
         }
+        if (chartTypeInput === 'pie_chart' && spec?.encode?.color) {
+          // 补充饼图的 tooltip title 展示
+          spec.tooltip = { title: { field: spec.encode.color } }
+        }
         return (
           <Chart
             key={chartTypeInput}