|
|
1 月之前 | |
|---|---|---|
| .. | ||
| README.md | 1 月之前 | |
| line-chart.vue | 1 月之前 | |
一个轻量且功能全面的折线/柱状图组件(已测试兼容 uni-app 微信小程序、支付宝小程序、抖音小程序 以及 H5)。
chartType 切换)下文为完整的参数说明与若干示例,方便你直接拷贝并在项目中使用。
components/line-chart 目录复制到你的项目。最简示例:
<template>
<line-chart :chartData="chartData" />
</template>
<script>
import LineChart from '@/components/line-chart/line-chart.vue'
export default {
components: { LineChart },
data() {
return {
chartData: {
labels: ['1月', '2月', '3月', '4月', '5月', '6月'],
datasets: [
{
label: '销售额',
data: [850, 920, 880, 950, 1000, 980],
color: '#4A90E2',
gradientStart: '#4A90E2',
gradientEnd: '#357ABD'
}
]
}
}
}
}
</script>
组件默认会使用合理的样式和动画展示折线图。
必填属性 chartData:
{
labels: Array<string>, // X 轴标签,长度应与各 dataset.data 数组长度匹配
datasets: [
{
label: string, // 数据集名称
data: number[], // 数值数组
color?: string, // 线条或点颜色(十六进制或 css 颜色)
gradientStart?: string, // 渐变起始色(可选)
gradientEnd?: string, // 渐变结束色(可选)
// 以下为柱状图相关(仅当 chartType === 'bar' 时可用)
// barWidth?: number,
// barColor?: string
}
]
}
注意:每个 dataset.data 数组应与 labels 数组长度一致;组件会以数组索引对应的方式进行渲染。
| 名称 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| chartType | String | 'line' |
否 | 图表类型:'line' 或 'bar' |
| width | String | '100%' |
否 | 图表外层容器宽度(支持百分比或 px) |
| height | String | '400px' |
否 | 图表外层容器高度 |
| chartData | Object | - | ✅ | 图表数据(见上文) |
| padding | Object | {top:20,right:20,bottom:30,left:50} |
否 | 内边距,见下文 |
| zoomConfig | Object | {enabled:true,minScale:1,maxScale:10,showControls:true} |
否 | 缩放配置 |
| animationConfig | Object | {enabled:true,duration:30} |
否 | 动画配置(duration 为帧数) |
| yAxisConfig | Object | {steps:5,autoRange:true,min:null,max:null,allowNegative:true} |
否 | Y 轴配置 |
| xAxisConfig | Object | {labelDensity:'auto',showAllLabels:false,formatter:null,lineHeight:14} |
否 | X 轴配置 |
| tooltipConfig | Object | {enabled:true,threshold:60} |
否 | Tooltip 配置 |
| legendConfig | Object | {enabled:true,position:'bottom',clickable:true} |
否 | 图例配置 |
| barConfig | Object | 详见下文 | 否 | 柱状图相关配置(当 chartType==='bar' 时生效) |
padding(内边距)
{
top: 20,
right: 20,
bottom: 30,
left: 50
}
zoomConfig(缩放)
{
enabled: true, // 是否允许缩放/捏合
minScale: 1, // 最小缩放倍数
maxScale: 10, // 最大缩放倍数
showControls: true // 是否显示重置缩放按钮
}
animationConfig(动画)
{
enabled: true, // 是否启用动画
duration: 30 // 动画帧数(默认 30 帧,视设备与 dpr 约 400-600ms)
}
yAxisConfig(Y 轴)
{
steps: 5, // 刻度数量(大致)
autoRange: true, // 自动计算范围
min: null, // 手动最小值(可选)
max: null, // 手动最大值(可选)
allowNegative: true// 自动计算时是否允许负值
}
说明:当 autoRange: true 时,组件会根据可见数据自动计算最大/最小值;你也可以单独设置 min 或 max 覆盖相应端。
xAxisConfig(X 轴)
{
labelDensity: 'auto', // 'auto' | 'sparse' | 'dense'
showAllLabels: false, // true 时强制显示所有标签(可能重叠)
formatter: null, // (label, index) => string,用于格式化标签并可返回包含 '\n' 的多行字符串
lineHeight: 14 // 行高,单位 px,用于多行标签排版
}
tooltipConfig(Tooltip)
{
enabled: true, // 是否显示 tooltip
threshold: 60 // 触发阈值(像素)——触摸/点击附近多少范围内触发
}
legendConfig(图例)
{
enabled: true, // 是否显示图例
position: 'bottom', // 'top' | 'bottom'
clickable: true // 点击图例可以切换数据集显示/隐藏
}
barConfig(柱状图相关)
{
width: 8,
innerGap: 2,
bottomGap: 2,
leftGap: 2,
animateMode: 'stagger', // 'all' | 'stagger'
staggerDelayFraction: 0.02, // stagger 模式下列间延迟占比
borderRadius: { top: 4, bottom: 0 }
}
1) 多折线(带自定义 X 轴 formatter)
<template>
<line-chart
:chartData="chartData"
:xAxisConfig="{ formatter: formatLabel }"
width="100%"
height="320px"
/>
</template>
<script>
import LineChart from '@/components/line-chart/line-chart.vue'
export default {
components: { LineChart },
data() {
return {
chartData: {
labels: ['2025-01-01', '2025-01-02', '2025-01-03'],
datasets: [
{ label: 'A', data: [100, 120, 140], color: '#4A90E2' },
{ label: 'B', data: [80, 110, 130], color: '#E94B3C' }
]
}
}
},
methods: {
formatLabel(label) {
// 返回多行文本,中间用 '\n' 分割
const d = new Date(label)
const mm = String(d.getMonth() + 1).padStart(2, '0')
const dd = String(d.getDate()).padStart(2, '0')
return `${mm}-${dd}\n星期${['日','一','二','三','四','五','六'][d.getDay()]}`
}
}
}
</script>
2) 切换为柱状图(bar)示例
<template>
<line-chart
chartType="bar"
:chartData="barData"
:barConfig="{ width: 12, animateMode: 'all' }"
width="100%"
height="320px"
/>
</template>
<script>
import LineChart from '@/components/line-chart/line-chart.vue'
export default {
components: { LineChart },
data() {
return {
barData: {
labels: ['1月','2月','3月','4月'],
datasets: [
{ label: '收入', data: [200, 300, 250, 400], color: '#50C878' }
]
}
}
}
}
</script>
3) 图例在顶部并关闭 tooltip(示例)
<line-chart
:chartData="chartData"
:legendConfig="{ position: 'top' }"
:tooltipConfig="{ enabled: false }"
width="100%"
height="300px"
/>
zoomConfig.minScale 与 zoomConfig.maxScale 限制。tooltipConfig.threshold 判断触发范围。yAxisConfig.autoRange 为 true)。兼容性:该组件已在 uni-app 环境下针对不同小程序平台(微信/支付宝/抖音)以及 H5 做了条件编译。
性能建议:当数据点数非常多(>2000)时,建议在数据层做下采样或限制绘制帧率以保持流畅。
{
enabled: true, // 是否显示图例
position: 'bottom', // 图例位置:'top' | 'bottom'
clickable: true // 是否可点击切换显示/隐藏数据集
}
位置说明:
'bottom':图表下方,横排显示(默认)'top':图表上方,横排显示{
enabled: true, // 是否启用Tooltip
threshold: 60 // 触发距离阈值(像素)
}
<template>
<view class="page">
<line-chart
:chartData="chartData"
width="100%"
height="400px"
:padding="{
top: 20,
right: 20,
bottom: 40,
left: 50
}"
:zoomConfig="{
enabled: true,
minScale: 1,
maxScale: 10,
showControls: true
}"
:animationConfig="{
enabled: true,
duration: 60
}"
:yAxisConfig="{
steps: 5,
autoRange: true
}"
:xAxisConfig="{
labelDensity: 'auto'
}"
:tooltipConfig="{
enabled: true,
threshold: 60
}"
/>
<button @tap="updateData">更新数据</button>
</view>
</template>
<script>
import LineChart from '@/components/line-chart/line-chart.vue'
export default {
components: {
LineChart
},
data() {
return {
chartData: {
labels: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月'],
datasets: [
{
label: '产品A',
data: [30, 45, 60, 50, 70, 65, 80, 75],
color: '#FF6B9D',
gradientStart: '#FFB6C1',
gradientEnd: '#FF1493'
},
{
label: '产品B',
data: [50, 65, 80, 70, 90, 85, 95, 88],
color: '#4ECDC4',
gradientStart: '#A8E6CF',
gradientEnd: '#00CED1'
}
]
}
}
},
methods: {
updateData() {
// 更新数据会自动触发过渡动画
this.chartData = {
...this.chartData,
datasets: [
{
...this.chartData.datasets[0],
data: this.chartData.datasets[0].data.map(() =>
Math.floor(Math.random() * 50) + 30
)
},
{
...this.chartData.datasets[1],
data: this.chartData.datasets[1].data.map(() =>
Math.floor(Math.random() * 50) + 50
)
}
]
}
}
}
}
</script>
#FF6B9D)chartData 会自动触发平滑过渡动画data 数组长度应与 labels 数组长度一致uni.createCanvasContext)components/line-chart/
├── line-chart.vue # 主组件文件
└── README.md # 组件文档
直接修改 chartData 对象即可,组件会自动触发过渡动画:
this.chartData = {
...this.chartData,
datasets: [
{
...this.chartData.datasets[0],
data: [新数据...]
}
]
}
启用图例并设置 clickable: true,然后点击图例项即可:
:legendConfig="{
enabled: true,
position: 'bottom',
clickable: true
}"
使用 xAxisConfig.formatter 函数:
:xAxisConfig="{
formatter: (label, index) => {
// 自定义格式化逻辑
return `格式化后的${label}`
}
}"
在 formatter 函数中返回包含 \n 的字符串:
formatter: (label, index) => {
return `第一行\n第二行`
}
检查以下几点:
tooltipConfig.enabled 是否为 true设置 zoomConfig.enabled 为 false:
:zoomConfig="{
enabled: false
}"
修改 yAxisConfig.steps:
:yAxisConfig="{
steps: 10 // 显示 10 个刻度
}"
设置 yAxisConfig.autoRange 为 false 并指定 min 和 max:
:yAxisConfig="{
autoRange: false,
min: 0,
max: 1000
}"
动画速度是固定的(约 0.8 秒),暂不支持自定义。如需修改,可以调整组件内的 transitionProgress += 0.05 这一行。
目前已测试并支持:
其他平台理论上也支持,但未经测试。
组件使用白色背景,如需修改,可以在组件的 .chart-wrapper 样式中修改 background 属性。
直接在 chartData.datasets 数组中添加即可,支持任意数量:
datasets: [
{ label: '产品A', data: [...], color: '#4A90E2' },
{ label: '产品B', data: [...], color: '#E94B3C' },
{ label: '产品C', data: [...], color: '#50C878' },
{ label: '产品D', data: [...], color: '#9C27B0' },
// 继续添加...
]
这可能是因为数据过渡动画期间 Tooltip 显示的是过渡中的数据。这是正常的,动画完成后会显示准确数据。
使用 legendConfig.position:
:legendConfig="{
position: 'top' // 或 'bottom'
}"
设置 zoomConfig.showControls 为 false:
:zoomConfig="{
showControls: false
}"
LineChart 是一个功能完整、性能优秀、易于使用的折线图组件:
开始使用 LineChart,让数据可视化更简单!