更新记录
1.0.0(2026-04-29)
- feat: 首次公开发布
hans-charts,提供基于spec / theme / frame的uni-app x图表组件 API。 - feat: 支持
line、bar、combo、pie、rose、radar六类图表。 - feat: 支持
stack / percent stack、折线面积填充、axisKey / yAxes双轴表达,以及 loading / empty state。 - feat: 支持图例切换、tooltip、selection、
zoom / pan等基础交互,并统一输出@action事件。 - feat: 提供
appendData、updateData、setViewport、showTooltip、highlight、reset、exportImage等实例方法。 - feat: 内置
minimal、editorial、dashboard三套 preset,支持light / dark模式与主题定制。 - feat: 补齐
uni-app xApp Android / iOS 平台实现,并提供 playground 场景化回归页。 - test: Android 自动化回归用例
pages/index/index.test.js当前通过78/78。 - docs: 完善插件
readme.md、平台支持说明与发布变更记录。
平台兼容性
uni-app x(5.07)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | √ | √ | √ | - |
hans-charts 图表组件
hans-charts 是面向 uni-app x 的 UVUE Canvas 图表组件,使用 spec / theme / frame 三个入口描述图表语义、视觉主题和宿主尺寸。
平台支持
| 平台 | 支持情况 |
|---|---|
| uni-app x App Android | 支持 |
| uni-app x App iOS | 支持 |
| uni-app x Web | 未作为当前主验证目标 |
| uni-app x HarmonyOS | 支持(当前为首轮适配,建议继续真机验证) |
| uni-app Vue2/Vue3、小程序、快应用 | 不支持 |
要求 HBuilderX 4.0+,项目需要使用 uni-app x。
安装与引入
将插件放在项目的 uni_modules/hans-charts 目录下后,可在页面或组件中直接使用:
<template>
<hans-charts :spec="spec" :theme="theme" :frame="frame" />
</template>
如需使用类型,在 script setup lang="uts" 中引入:
import type {
HansChartSpec,
HansChartTheme,
HansChartFrame,
HansChartsExposed
} from '@/uni_modules/hans-charts'
快速示例
<script setup lang="uts">
import { ref } from 'vue'
import type { HansChartFrame, HansChartSpec, HansChartTheme } from '@/uni_modules/hans-charts'
const spec = ref<HansChartSpec>({
type: 'line',
title: 'Weekly Visits',
interaction: {
legend: {
show: true,
interactive: true
},
tooltip: {
show: true,
confine: true,
placement: 'auto'
},
gesture: {
zoomEnabled: true,
panEnabled: true,
minScale: 0.8,
maxScale: 3
}
},
axis: {
x: {
show: true,
labelMaxLength: 10,
labelStrategy: 'autoSkip'
},
y: {
show: true,
tickCount: 5
}
},
data: {
categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
series: [
{
key: 'visits',
name: 'Visits',
values: [120, 132, 101, 134, 90, 230, 210],
color: '#2563eb'
}
]
}
})
const theme = ref<HansChartTheme>({
preset: 'editorial',
mode: 'light',
palette: ['#2563eb', '#06b6d4', '#22c55e'],
line: {
smoothing: 'smooth',
width: 2.4,
pointRadius: 4,
areaOpacity: 0.14
},
layout: {
padding: {
top: 20,
right: 18,
bottom: 38,
left: 16
}
}
})
const frame = ref<HansChartFrame>({
width: 320,
height: 220
})
</script>
<template>
<hans-charts :spec="spec" :theme="theme" :frame="frame" />
</template>
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
spec |
HansChartSpec |
是 | 图表类型、数据、坐标轴、交互、加载态等语义配置。 |
theme |
HansChartTheme \| null |
否 | 视觉主题配置,包括色板、排版、网格、图例、tooltip、图形样式等。 |
frame |
HansChartFrame \| null |
否 | 图表宽高和像素比。缺省或宽高小于等于 0 时走自动测量。 |
debug |
boolean |
否 | 调试辅助开关,默认 false。生产环境建议保持关闭。 |
frame 的字段如下:
type HansChartFrame = {
width?: number
height?: number
pixelRatio?: number
}
未显式传入 frame.width / frame.height 时,组件会优先测量宿主宽度,并按自动高度策略重绘。业务页面如果有固定图表区域,建议直接传入明确的 width 和 height。
支持的图表类型
spec.type |
图表 | 数据入口 |
|---|---|---|
line |
折线图 | data.categories + data.series[].values 或 data.series[].data |
bar |
柱状图 | data.categories + data.series[].values 或 data.series[].data |
combo |
折线/柱状复合图 | data.categories + data.series[],每个系列用 type: 'line' \| 'bar' 区分 |
pie |
饼图 | data.series[] 切片数组 |
rose |
玫瑰图 | data.series[] 切片数组,可为切片设置 radius |
radar |
雷达图 | data.indicators + data.series[].values |
数据写法
折线图、柱状图、复合图
const spec: HansChartSpec = {
type: 'combo',
data: {
categories: ['Mon', 'Tue', 'Wed'],
series: [
{
type: 'bar',
key: 'orders',
name: 'Orders',
values: [42, 48, 52],
stack: 'traffic'
},
{
type: 'line',
key: 'rate',
name: 'Conversion',
values: [18, 21, 23],
axisKey: 'rate',
area: false
}
]
}
}
values 适合简单数值数组,data 适合需要稳定 key、原始业务对象或连续坐标的场景:
{
key: 'visits',
name: 'Visits',
values: [120, null, 156],
data: [
{ key: 'mon', value: 120, rawDatum: { id: 1, day: 'Mon' } },
{ key: 'tue', value: null, rawDatum: { id: 2, day: 'Tue' } },
{ key: 'wed', y: 156, rawDatum: { id: 3, day: 'Wed' } }
]
}
说明:
null表示空点。data.y优先于data.value。data.key会用于事件、tooltip、selection 和数据更新后的状态恢复;类目文案可能变化时建议显式传入。rawDatum会透传到点击事件、tooltip formatter 和 data labels formatter。
饼图与玫瑰图
const pieSpec: HansChartSpec = {
type: 'pie',
data: {
series: [
{ key: 'search', name: 'Search', value: 46, color: '#2563eb' },
{ key: 'ads', name: 'Ads', value: 28, color: '#f97316' },
{ key: 'direct', name: 'Direct', value: 26, color: '#22c55e' }
]
}
}
玫瑰图支持额外的 radius 字段:
const roseSpec: HansChartSpec = {
type: 'rose',
data: {
series: [
{ key: 'a', name: 'A', value: 35, radius: 0.7 },
{ key: 'b', name: 'B', value: 48, radius: 0.92 }
]
}
}
雷达图
const radarSpec: HansChartSpec = {
type: 'radar',
axis: {
show: true,
labelStrategy: 'truncate',
labelMaxLength: 8
},
thresholds: {
items: [
{ value: 60, color: '#f97316', label: 'Target' }
],
lineDash: [4, 5]
},
data: {
indicators: ['Quality', 'Speed', 'Cost', 'Risk', 'Growth'],
series: [
{
key: 'current',
name: 'Current',
values: [82, 70, 64, 76, 88]
}
]
}
}
坐标轴与业务表达
笛卡尔图表支持 axis、scale、dataZoom、brush、labels 和 annotations。
const comboSpec: HansChartSpec = {
type: 'combo',
axis: {
x: {
type: 'category',
labelStrategy: 'autoSkip',
labelMaxLength: 10
},
y: {
axisKey: 'volume',
type: 'value'
},
yAxes: [
{ axisKey: 'volume', position: 'left', type: 'value' },
{ axisKey: 'rate', position: 'right', type: 'value', min: 0, max: 40 }
]
},
scale: {
negative: 'allowNegative'
},
dataZoom: {
show: true,
type: 'inside',
start: 10,
end: 90
},
labels: {
show: true,
position: 'top'
},
annotations: {
show: true,
items: [
{ type: 'average', label: 'Avg' },
{ type: 'max', label: 'Max' }
]
},
data: {
categories: ['Mon', 'Tue', 'Wed'],
series: [
{ type: 'bar', key: 'organic', name: 'Organic', values: [42, 48, 52], stack: 'traffic' },
{ type: 'bar', key: 'paid', name: 'Paid', values: [28, 24, 32], stack: 'traffic' },
{ type: 'line', key: 'rate', name: 'Conversion', axisKey: 'rate', values: [18, 21, 23] }
]
}
}
常用字段:
| 配置 | 说明 |
|---|---|
axis.x / axis.y |
坐标轴显示、类型、刻度数、最大/最小值、反向、label 策略。 |
axis.yAxes |
多 y 轴配置,系列通过 axisKey 绑定。 |
scale.negative |
负值策略,clampZero 或 allowNegative。 |
series.stack |
柱状图堆叠分组。 |
series.stackMode |
normal 或 percent。 |
series.area |
折线面积填充,可传 boolean 或 { show, opacity, baseline }。 |
dataZoom |
类目轴窗口裁剪,当前建议使用 type: 'inside'。 |
brush |
已有配置结构,框选 UI 和正式框选事件不建议在业务中依赖。 |
交互配置
const interaction = {
legend: {
show: true,
interactive: true,
singleSelect: false
},
tooltip: {
show: true,
confine: true,
placement: 'auto',
offset: { x: 10, y: -56 },
formatter: (params) => {
return params.seriesName + ': ' + params.displayValue
}
},
gesture: {
zoomEnabled: true,
panEnabled: true,
minScale: 0.8,
maxScale: 3
}
}
tooltip.formatter 入参包含 chartType / legendIndex / seriesIndex / dataIndex / dataKey / seriesName / label / value / rawDatum / displayLabel / displayValue 等字段。
主题配置
const theme: HansChartTheme = {
preset: 'dashboard',
mode: 'dark',
palette: ['#60a5fa', '#34d399', '#f97316'],
surface: {
radius: 10,
shadow: 1
},
grid: {
strength: 'soft',
dash: [3, 7],
opacity: 0.72,
lineWidth: 0.9
},
typography: {
title: 15,
axis: 10,
legend: 13,
tooltipTitle: 12,
tooltipValue: 13
},
legend: {
position: 'bottom',
wrap: true,
dotSize: 8
},
tooltip: {
style: 'glass',
maxWidth: 240,
paddingX: 12,
paddingY: 10,
radius: 10
},
layout: {
touchTarget: 44,
emptyText: 'No data',
padding: {
top: 20,
right: 18,
bottom: 38,
left: 16
}
}
}
可用 preset:minimal、editorial、dashboard。可用模式:light、dark。
加载态与空态
const loadingSpec: HansChartSpec = {
type: 'line',
loading: {
show: true,
text: 'Loading...'
},
data: {
categories: [],
series: []
}
}
空态文案通过 theme.layout.emptyText 配置。数据为空或有效点为空时,组件会显示空态。
Events
<hans-charts
:spec="spec"
:theme="theme"
:frame="frame"
@ready="onReady"
@action="onAction"
@pointClick="onPointClick"
@legendClick="onLegendClick"
@selectionChange="ionChange"
@tooltipChange="onTooltipChange"
@viewportChange="onViewportChange"
@zoom="onZoom"
@pan="onPan"
/>
| 事件 | 说明 |
|---|---|
ready |
canvas 初始化完成后触发,返回 canvasId / width / height / pixelRatio / renderBounds。 |
action |
统一动作事件,覆盖点选、图例切换、selection、zoom、pan、dataZoom、brush。 |
pointClick |
点击图形元素时触发,返回系列、数据索引、key、label、value、percentage、rawDatum 等。 |
legendClick |
点击图例时触发,返回图例索引、当前激活状态、隐藏/激活索引列表。 |
selectionChange |
选中点变化时触发。 |
tooltipChange |
tooltip 或 cursor 状态变化时触发。 |
viewportChange |
缩放和平移状态变化时触发。 |
zoom |
缩放手势或命令触发时返回当前 viewport。 |
pan |
平移手势或命令触发时返回当前 viewport。 |
stateChange |
运行时状态变化事件,适合需要同步完整状态的场景。 |
inspect |
调试快照事件,业务侧通常不需要依赖。 |
事件类型可从插件导入:
import type {
HansChartActionEvent,
HansChartReadyEvent,
HansPointClickEvent,
HansLegendClickEvent,
HansChartSelectionChangeEvent,
HansChartTooltipChangeEvent,
HansChartViewportChangeEvent,
HansChartZoomEvent,
HansChartPanEvent,
HansChartStateChangeEvent
} from '@/uni_modules/hans-charts'
实例方法
需要由外部按钮、筛选器或多图联动驱动图表时,可以通过组件 ref 调用实例方法。
<script setup lang="uts">
import { ref } from 'vue'
import type { HansChartsExposed } from '@/uni_modules/hans-charts'
const chartRef = ref<HansChartsExposed | null>(null)
function zoomIn(): void {
chartRef.value?.setViewport({ scale: 1.5 })
}
function showThirdPoint(): void {
chartRef.value?.showTooltip({ legendIndex: 0, dataIndex: 2 })
}
function resetChart(): void {
chartRef.value?.reset()
}
</script>
<template>
<hans-charts ref="chartRef" :spec="spec" :theme="theme" :frame="frame" />
</template>
| 方法 | 说明 |
|---|---|
getRuntimeState() |
获取当前图例隐藏、selection、tooltip、viewport、cursor 等运行时状态。 |
setViewport(viewport) |
设置 scale / translateX / translateY,会按手势配置和画布边界自动约束。 |
clearInteraction() |
清空 selection、tooltip、cursor、activeLegend,不重置当前 viewport。 |
highlight(target) |
程序化高亮指定点位,不主动显示 tooltip。 |
showTooltip(target) |
程序化显示 tooltip,并同步 activeLegend 和 cursor。 |
hideTooltip() |
主动关闭 tooltip。 |
appendData(input) |
向 line / bar / combo 的类目和系列尾部追加数据。 |
updateData(input) |
替换 line / bar / combo 的类目或指定系列数据。 |
reset() |
重置 viewport、图例、selection、tooltip、cursor 等交互状态。 |
resize() |
重新计算尺寸并重绘,适合外部原地修改 frame 后主动触发。 |
exportImage() |
返回 PNG dataURL;当前宿主不支持 toDataURL 时返回空字符串。 |
dispatchCommand(command) |
低层命令入口,业务侧优先使用上面的高层方法。 |
target 支持以下字段,可按索引或 key 定位:
type HansChartTarget = {
legendIndex?: number
legendKey?: string
dataIndex?: number
dataKey?: string
}
appendData() 和 updateData() 的输入格式:
{
categories?: string[]
series: [
{
legendIndex?: number
legendKey?: string
values?: (number | null)[]
data?: Array<{
key?: string
x?: number | string | null
y?: number | null
value?: number | null
rawDatum?: any | null
}>
}
]
}
使用限制
- 当前主要支持
uni-app x的 App Android 和 App iOS。 dataZoom建议使用inside窗口裁剪;sliderUI 不是当前稳定能力。brush已提供配置结构,但框选 UI 和正式框选事件不建议在业务中依赖。exportImage()依赖宿主 canvas 的toDataURL能力,App 端不可用时会返回空字符串。- 如果外部通过
appendData()或updateData()修改运行时数据,之后再传入新的props.spec时,以新的外部spec为准。
隐私与权限
插件不包含广告,不采集数据,不声明额外系统权限,也不依赖额外第三方 SDK。

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 344
赞赏 0
下载 11743781
赞赏 1911
赞赏
京公网安备:11010802035340号