多个图表示例

本示例展示了如何在同一个图表中结合多种图表类型(折线图、面积图、参考线图),并根据用户交互动态展示注解内容,打造具有交互性的可视化图表。

示例代码

1const data = [
2  { sales: 1200, year: '2020', growth: 0.14, },
3  { sales: 1400, year: '2021', growth: 0.16, },
4  { sales: 2000, year: '2022', growth: 0.42, },
5  { sales: 2500, year: '2023', growth: 0.25, },
6  { sales: 3600, year: '2024', growth: 0.44, },
7]
8
9function Example() {
10  const [chartSelection, setChartSelection] = useState<string | null>()
11  const selectedItem = useMemo(() => {
12    if (chartSelection == null) {
13      return null
14    }
15    return data.find(item => item.year === chartSelection)
16  }, [chartSelection])
17
18  return <NavigationStack>
19    <VStack
20      navigationTitle={"Multiple Charts"}
21      navigationBarTitleDisplayMode={"inline"}
22    >
23      <Text>
24        Press and move on the chart to view the details.
25      </Text>
26      <Chart
27        frame={{
28          height: 300,
29        }}
30        chartXSelection={{
31          value: chartSelection,
32          onChanged: setChartSelection,
33          valueType: "string"
34        }}
35      >
36        <LineChart
37          marks={data.map(item => ({
38            label: item.year,
39            value: item.sales,
40            interpolationMethod: "catmullRom",
41            symbol: "circle",
42          }))}
43        />
44        <AreaChart
45          marks={data.map(item => ({
46            label: item.year,
47            value: item.sales,
48            interpolationMethod: "catmullRom",
49            foregroundStyle: ["rgba(255,100,0,1)", "rgba(255,100,0,0.2)"]
50          }))}
51        />
52        {selectedItem != null
53          ? <RuleLineForLabelChart
54            marks={[{
55              label: selectedItem.year,
56              foregroundStyle: { color: "gray", opacity: 0.5 },
57              annotation: {
58                position: "top",
59                overflowResolution: {
60                  x: "fit",
61                  y: "disabled"
62                },
63                content: <ZStack
64                  padding
65                  background={
66                    <RoundedRectangle
67                      cornerRadius={4}
68                      fill={"regularMaterial"}
69                    />
70                  }
71                >
72                  <Text
73                    foregroundStyle={"white"}
74                  >Sales: {selectedItem.sales}</Text>
75                </ZStack>
76              }
77            }]}
78          />
79          : null}
80      </Chart>
81    </VStack>
82  </NavigationStack>
83}

总览

本示例中使用了以下组件:

  • LineChart:绘制离散点并以平滑曲线连接。
  • AreaChart:在曲线下方填充区域,增强视觉效果。
  • RuleLineForLabelChart:在选中的标签位置绘制参考线并添加注解。
  • chartXSelection:启用用户在图表上的交互选择。

数据格式

本示例使用的数据结构如下:

1const data = [
2  { sales: 1200, year: '2020', growth: 0.14 },
3  { sales: 1400, year: '2021', growth: 0.16 },
4  { sales: 2000, year: '2022', growth: 0.42 },
5  { sales: 2500, year: '2023', growth: 0.25 },
6  { sales: 3600, year: '2024', growth: 0.44 },
7]

每条数据包含:

  • sales:销售额,作为主要数值
  • year:年份,用作 X 轴标签
  • growth:增长率(本例未用于图表展示)

主要功能

图表选择功能

1chartXSelection={{
2  value: chartSelection,
3  onChanged: setChartSelection,
4  valueType: "string"
5}}
  • 允许用户在图表上点击或拖动,选中某个横轴标签(year)。
  • 使用 setChartSelection 设置当前选择项。

折线图(LineChart)

1<LineChart
2  marks={data.map(item => ({
3    label: item.year,
4    value: item.sales,
5    interpolationMethod: "catmullRom",
6    symbol: "circle",
7  }))}
8/>
  • 以圆形符号表示每个数据点,并用平滑曲线连接。
  • 使用 "catmullRom" 插值方法使曲线更自然平滑。

面积图(AreaChart)

1<AreaChart
2  marks={data.map(item => ({
3    label: item.year,
4    value: item.sales,
5    interpolationMethod: "catmullRom",
6    foregroundStyle: ["rgba(255,100,0,1)", "rgba(255,100,0,0.2)"]
7  }))}
8/>
  • 覆盖在折线图之下的区域,增强趋势的视觉表达。
  • 应用了从橙色不透明到透明的渐变填充。

标签参考线图(RuleLineForLabelChart)

1<RuleLineForLabelChart
2  marks={[{
3    label: selectedItem.year,
4    foregroundStyle: { color: "gray", opacity: 0.5 },
5    annotation: {
6      position: "top",
7      overflowResolution: { x: "fit", y: "disabled" },
8      content: <ZStack
9        padding
10        background={<RoundedRectangle cornerRadius={4} fill={"regularMaterial"} />}
11      >
12        <Text foregroundStyle={"white"}>Sales: {selectedItem.sales}</Text>
13      </ZStack>
14    }
15  }]}
16/>
  • 在用户选中的年份上绘制一条灰色参考线。
  • 上方浮动注解展示销售额数据。
  • 使用 ZStackRoundedRectangle 构建注解背景样式。

交互流程

  1. 用户触摸图表。
  2. 系统根据触摸位置更新 chartSelection
  3. 使用 useMemo 查找对应的数据项。
  4. 在相应位置绘制参考线。
  5. 展示注解气泡显示详细数据(如 Sales: 2500)。

总结

通过本示例你可以学习如何:

  • 在同一图表中组合多个图表(如折线图、面积图、参考线图)。
  • 通过 chartXSelection 响应用户交互。
  • 使用 annotation 显示动态注解内容。
  • 利用渐变、透明度、圆角背景等样式增强展示效果。

该模式非常适合用于数据仪表盘、年度报告等需要交互性和可视化解释的数据展示场景。