Skip to content

LineChart 折线图 ​

用于展示指标随时间的变化趋势:支持多系列对比、面积填充、堆叠面积、平滑与缺测断点。

完整日期与窄容器 ​

调整宽度或切换长类目名称。首末文字保持在绘图区内,收边后再次检查间距;超长文字以省略号显示,悬停可读完整内容。

vue
<script setup lang="ts">
import { ref } from 'vue';
import { LineChart } from 'x-next';

const width = ref(320);
const categories = Array.from({ length: 30 }, (_, index) =>
  new Date(Date.UTC(2026, 8, 6 + index)).toISOString().slice(0, 10),
);
const series = [{ name: '浏览量', data: Array.from({ length: 30 }, (_, index) => 8 + index % 19) }];
</script>

<template>
  <label>宽度 <input v-model.number="width" type="range" min="240" max="966" /></label>
  <div :style="{ width: `${width}px`, maxWidth: '100%' }">
    <LineChart :categories="categories" :series="series" />
  </div>
</template>

何时使用 ​

  • 时间轴上比较多个指标的走势(各模型的 Token 消耗、不同环境的请求量)。
  • 关注变化速率与拐点,而不是单个时间点的精确读数。
  • 需要在线性趋势里叠加一条对照线(如实际值 vs 目标值)。

与其它图表的分工 ​

场景选择
随时间看变化趋势LineChart(本页)
按类目比较大小BarChart 柱状趋势图
看占比构成PieChart 饼图
卡片角落的迷你走势TrendChart 趋势图

基础用法 ​

categories 与每个系列 data 按下标一一对应;类目轴标签会按当前宽度自动抽稀,末位总是保留。

vue
<template>
  <x-line-chart
    :categories="categories"
    :series="[{ name: '请求量', data: values }]"
    aria-label="近 30 天请求量"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const categories = ref(['09-28', '09-29', '09-30', '10-01', '10-02']);
const values = ref([820, 932, 901, 934, 1290]);
</script>

多系列与平滑 ​

多系列默认叠放(不堆叠),颜色取自内置分类色板;smooth 默认为 true,关闭后是折线段。

vue
<template>
  <x-line-chart :categories="categories" :series="series" legend />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const categories = ref(['09-28', '09-29', '09-30', '10-01', '10-02']);
const series = ref([
  { name: '输入 Token', data: [820, 932, 901, 934, 1290] },
  { name: '输出 Token', data: [420, 512, 401, 634, 890] },
]);
</script>

面积图与堆叠面积 ​

area 打开填充;配合 stack 变为堆叠面积。堆叠面积适合看「总量 + 构成」——每层填充在下界与上界之间。

vue
<template>
  <x-line-chart
    :categories="categories"
    :series="series"
    area
    stack
    :value-formatter="formatMoney"
    legend
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const categories = ref(['09-28', '09-29', '09-30', '10-01', '10-02']);
const series = ref([
  { name: 'deepseek-flash', data: [43.38, 52.4, 38.05, 61.2, 55.8] },
  { name: 'gpt-4o-mini', data: [18.29, 26.1, 12.6, 30.4, 22.1] },
]);
const formatMoney = (value: number) => `¥${value.toFixed(2)}`;
</script>

缺测处理 ​

null 表示该时间点没有数据。默认断开折线(避免把「没有调用」画成跌到 0);connectNulls 打开后跨过缺测连到下一点。两者都不会在缺测处产生数据点。

vue
<template>
  <x-line-chart
    :categories="categories"
    :series="[{ name: '工作日请求量', data: values }]"
    :connect-nulls="connectNulls"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const connectNulls = ref(false);
const categories = ref(['09-28', '09-29', '09-30', '10-01', '10-02']);
// 周末为 null:默认在该处断开折线
const values = ref([820, null, null, 934, 1290]);
</script>

数值轴与负值 ​

正数数据保持 0 基线(不会用非零基线夸大波动);出现负值时才向下扩展出负向刻度,零线会被强调。min / max 可锁定区间。

vue
<template>
  <x-line-chart
    :categories="categories"
    :series="series"
    :max="1200"
    :grid="{ horizontalLinesNumber: 5 }"
    legend
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const categories = ref(['9/1', '9/5', '9/10', '9/15', '9/20', '9/25', '9/30']);
const series = ref([
  { name: 'p50', data: [180, 210, 195, 230, 205, 240, 220] },
  { name: 'p95', data: [420, 680, 510, 940, 720, 1180, 860] },
]);
</script>

自定义提示与点击事件 ​

tooltip 插槽可完全接管浮层内容;点击触发 line-click,命中具体数据点时带 seriesIndex 与 value。

尚未点击数据点

vue
<template>
  <x-line-chart
    :categories="categories"
    :series="series"
    legend
    @line-click="onLineClick"
  >
    <template #tooltip="{ label, items, formatValue }">
      <div style="font-weight: 500">{{ label }}</div>
      <div v-for="item in items" :key="item.seriesIndex">
        <span>{{ item.name }}</span>
        <span>{{ item.value === null ? '-' : formatValue(item.value) }}</span>
      </div>
    </template>
  </x-line-chart>
  <p>{{ clickLog }}</p>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const categories = ref(['09-28', '09-29', '09-30']);
const series = ref([
  { name: '请求量', data: [820, 932, 901] },
  { name: '错误数', data: [120, 132, 101] },
]);
const clickLog = ref('尚未点击数据点');
const onLineClick = (data: { label: string; value: number | null }) => {
  clickLog.value = `${data.label}:${data.value ?? '缺测'}`;
};
</script>

数据点与轴格式化 ​

showPoints 控制数据点:true 常显、false 不显示、'auto'(默认)在点数较少时常显。labels.yFormatter 只影响数值轴,valueFormatter 同时影响提示与图例。

vue
<template>
  <x-line-chart
    :categories="categories"
    :series="series"
    :show-points="true"
    :smooth="smooth"
    :value-formatter="formatCompact"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const smooth = ref(true);
const categories = ref(['09-28', '09-29', '09-30']);
const series = ref([{ name: '请求量', data: [820, 932, 901] }]);
const formatCompact = (value: number) => (value >= 1000 ? `${value / 1000}k` : `${value}`);
</script>

加载与空数据 ​

loading 覆盖加载遮罩;全部为 null 或没有系列时显示空态,可用 empty 插槽替换。

vue
<template>
  <x-line-chart :categories="categories" :series="series" :loading="loading">
    <template #empty>该时段没有调用记录</template>
  </x-line-chart>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const loading = ref(true);
const categories = ref(['09-28', '09-29', '09-30']);
const series = ref([{ name: '请求量', data: [820, 932, 901] }]);
</script>

按需导入 ​

ts
import { LineChart } from 'x-next';
ts
import { createApp } from 'vue';
import { LineChart } from 'x-next';
import 'x-next/style/base.css';
import 'x-next/style/line-chart.css';

createApp(App).use(LineChart);

样式按需引入(base.css 为共享基础层,多个组件只需引入一次):

ts
import 'x-next/style/base.css';
import 'x-next/style/line-chart.css';

Props ​

属性说明类型默认值
categories类目轴标签,与各系列 data 下标对应Array<string | number>[]
series数据系列,必填LineChartSeries[][]
stack是否堆叠;面积时变为堆叠面积booleanfalse
area是否绘制面积填充booleanfalse
smooth平滑曲线booleantrue
connectNulls缺测是否跨过连接booleanfalse
showPoints数据点显示策略boolean | 'auto''auto'
height图表高度,数字按 pxnumber | string280
width图表宽度,数字按 pxnumber | string'100%'
max数值轴上界;传入后锁定刻度number-
min数值轴下界;负值数据自动扩展number-
padding绘制边距,1-4 个非负数字字符串或单个数字string | number'8'
grid网格线配置LineChartGridOptions-
labels轴标签配置LineChartLabelsOptions-
tooltip悬浮提示booleantrue
legend图例,点击可隐藏/显示系列booleanfalse
valueFormatter数值格式化,用于提示、图例与数值轴(value: number) => string千分位,最多 4 位小数
loading加载中boolean | objectfalse
ariaLabel无障碍名称;设置后画布带 role="img"string-

LineChartSeries ​

字段说明类型
name系列名,用于提示与图例string
data按 categories 顺序排列的值;null 表示缺测Array<number | null>
color系列颜色;默认取内置分类色板string

LineChartGridOptions ​

字段说明类型默认值
horizontalLines是否显示横向网格线booleantrue
horizontalLinesNumber横向网格线数量(含基线)number4

LineChartLabelsOptions ​

字段说明类型默认值
xVisible是否显示类目标签booleantrue
yVisible是否显示数值轴标签booleantrue
xFormatter类目标签格式化(label: string, index: number) => string-
yFormatter数值轴刻度格式化(只影响轴)(value: number) => string跟随 valueFormatter
fontSize轴标签字号number12
color轴标签颜色string跟随主题

Events ​

事件名说明参数
lineClick点击数据点或绘图区时触发(data: LineChartClickData)
legendChange图例切换后触发(visibleIndexes: number[])

LineChartClickData 包含 index / label / items / total,以及命中数据点的 seriesIndex 与 value(未命中时为 null)。

Slots ​

插槽名说明参数
tooltip自定义悬浮提示内容LineChartTooltipSlotProps(含 formatValue)
legend自定义图例{ series: LineChartSeries[]; hiddenIndexes: number[] }
point自定义数据点渲染{ seriesIndex, index, value, x, y, color }
empty自定义空态内容-

交互说明 ​

  • 数值轴:默认按 1 / 2 / 5 步长取整(刻度始终是 0.5、80 这类可读值),因此实际刻度行数可能少于 horizontalLinesNumber;传 min / max 后按锁定值均分。
  • 零基线:纯正数数据不会用非零基线;出现负值时才扩展负向刻度。
  • 缺测:默认断线,connectNulls 改为跨过;两种模式都不会在缺测处产生数据点,避免鼠标命中不存在的点。
  • 堆叠:按可见系列的顺序自下而上累加;缺测按 0 处理,保证堆叠层不出现空洞。命中的系列高亮显示,其余系列由样式淡化。
  • x 轴标签:按当前宽度和文字宽度自动抽稀,优先保留末位;收边后再次检查间距。空间不足时省略其他标签,单个超长标签以省略号显示并提供完整文字提示。
  • 键盘导航:绘图区可聚焦,左右方向键移动读数、Home / End 跳到首尾、Esc 关闭提示;键盘导航时通过 aria-live 播报。
  • 性能:整块画布只挂一个 mousemove 与一个提示节点,不为每个数据点创建浮层或监听器;数据点默认在点数较少时常显,长序列自动隐藏。