- 前端
- 数据可视化
- UI组件
【免费下载链接】v-charts
基于 Vue2.0 和 ECharts 封装的图表组件📈📊
导读
树图(Tree)是 ECharts 中用于表达层级关系的经典图表,v-charts 将其封装为<ve-tree>组件,只需按统一的columns/rows数据格式传入树节点对象,即可快速渲染。本文围绕 docs/tree.md 展开,完整覆盖基础树图、多树图、径向树图、纵向树图与自定义提示框五大实战场景,并结合 树图处理源码 深入讲解settings中dimension、metrics、seriesMap的真实解析逻辑,读完即可在自己的 Vue2 项目中直接落地使用。
一、环境准备与组件引入
1.1 安装依赖
v-charts 基于 Vue2.x 与 ECharts 封装,需要同时安装两个依赖包:
npm i v-charts echarts -S1.2 完整引入
在 docs/start.md 中说明了完整引入方式,注册后即可全局使用ve-tree:
// main.js import Vue from 'vue' import VCharts from 'v-charts' import App from './App.vue' Vue.use(VCharts) new Vue({ el: '#app', render: h => h(App) })1.3 按需引入
v-charts 的每种图表都已单独打包到lib目录下,树图对应tree.common.js。按需引入可以有效减小打包体积:
import Vue from 'vue' import VeTree from 'v-charts/lib/tree.common' import App from './App.vue' Vue.component(VeTree.name, VeTree) new Vue({ el: '#app', render: h => h(App) })从源码看,树图组件入口 通过import 'echarts/lib/chart/tree'只引入 ECharts 的 tree 图表模块,再与 核心渲染逻辑 混合导出VeTree,这也是它能够独立按需打包的原因。该组件同样被注册进 全量组件清单 与 统一安装入口,因此两种引入方式都受支持。
二、树图的数据格式:columns / rows 与树节点结构
v-charts 全系列使用统一的“指标 + 维度”数据模型,详细约定见 docs/data.md。树图数据同样由columns与rows组成:
{ columns: ['name', 'value'], rows: [ { name: 'tree1', value: [treeData] } ] }columns定义列名:第一项为维度,第二项为指标;rows是数据集合,每一行代表一棵独立的树;- 每行的
name字段是该棵树的标识(series 名称),value字段则存放树节点对象数组。
树节点对象是 ECharts tree series 的标准数据形态,核心字段如下:
const treeData = { name: 'f', // 节点名称(显示在节点上) value: 1, // 节点数值(影响节点大小) link: 'https://ele.me', // 节点关联链接(可用于提示框跳转) children: [ // 子节点数组,递归结构 { name: 'a', value: 1, link: 'https://ele.me', children: [ /* 更深层节点 */ ] } ] }仓库中 树数据定义 还提供了一份更大的flare数据集(BASIC_DATA),包含数十层、数百个节点的层级结构,适合用来验证多树图、径向树图等场景。
三、基础示例:简单树图
只传入data属性即可渲染出一棵完整的树,这是最简用法:
<template> <ve-tree :data="chartData"></ve-tree> </template> <script> const treeData = { name: 'f', value: 1, link: 'https://ele.me', children: [ { name: 'a', value: 1, link: 'https://ele.me', children: [ { name: 'a-a', link: 'https://ele.me', value: 2 }, { name: 'a-b', link: 'https://ele.me', value: 2 } ] }, { name: 'b', value: 1, link: 'https://ele.me', children: [ { name: 'b-a', link: 'https://ele.me', value: 2 }, { name: 'b-b', link: 'https://ele.me', value: 2 } ] }, { name: 'c', value: 3, link: 'https://ele.me', children: [ { name: 'c-a', link: 'https://ele.me', value: 4 }, { name: 'c-b', link: 'https://ele.me', value: 2 } ] }, { name: 'd', value: 3, link: 'https://ele.me', children: [ { name: 'd-a', link: 'https://ele.me', value: 4 }, { name: 'd-b', link: 'https://ele.me', value: 2 } ] } ] } export default { data () { return { chartData: { columns: ['name', 'value'], rows: [ { name: 'tree1', value: [treeData] } ] } } } } </script>渲染效果为一棵标准的横向树:根节点f下挂a、b、c、d四个分支,每个分支再展开叶子节点,节点大小随value变化。
四、settings 配置项详解
树图的settings支持三个配置项,下表完整继承自 docs/tree.md:
| 配置项 | 简介 | 类型 | 备注 |
|---|---|---|---|
| dimension | 维度 | string | 默认columns第一项为维度 |
| metrics | 指标 | string | 默认columns第二项为指标 |
| seriesMap | 附加到 series 中的设置 | object | 可为每一棵树单独设置样式 |
备注:通过
seriesMap,可以为每一个树设置样式,具体样式的配置可参考 ECharts 官方文档中 series-tree 一节(诸如布局方式layout、方向orient以及top/left/bottom/right等布局定位配置,均可在此处设置)。
4.1 dimension 与 metrics 的默认值行为
在 树图处理源码 中,这两个配置项的默认值被直接解构出来:
const { dimension = columns[0], metrics = columns[1], seriesMap = {} } = settings也就是说,只要你的数据columns第一项是树的维度名(如name)、第二项是指标名(如value),即使完全不写settings,组件也会自动正确读取每行name字段作为系列名、value字段作为树数据数组。当你的数据结构列名不同(例如使用['title', 'data'])时,才需要显式指定:
chartSettings: { dimension: 'title', metrics: 'data' }五、多树图:用 seriesMap 控制每棵树的布局
当rows中包含多行数据时,组件会把每一行渲染为一棵独立的树。此时默认所有树会叠在同一位置,必须通过seriesMap为每棵树指定布局区域。
<template> <ve-tree :data="chartData" :settings="chartSettings"></ve-tree> </template> <script> // treeData 与上一示例中的 treeData 完全相同,可直接复用 export default { data () { this.chartSettings = { seriesMap: { tree1: { top: '5%', left: '7%', bottom: '2%', right: '60%' }, tree2: { top: '20%', left: '60%', bottom: '22%', right: '18%' } } } return { chartData: { columns: ['name', 'value'], rows: [ { name: 'tree1', value: [treeData] }, { name: 'tree2', value: [treeData] } ] } } } } </script>seriesMap的键名对应rows中每行的name(即系列名),值是与 ECharts tree series 一致的配置对象:
tree1占据画布左侧(left: '7%'、right: '60%');tree2占据画布右侧(left: '60%'、right: '18%'),且纵向位置略低(top: '20%'、bottom: '22%')。
仓库 示例数据定义 中“多树图”示例与此处的seriesMap配置完全一致,可以直接对照运行。
5.1 seriesMap 的底层合并机制
为什么seriesMap能精确控制每一棵树?关键在于 getTreeSeries 的合并逻辑:
rows.forEach(row => { const label = row[dimension] const seriesItem = seriesMap[label] const result = { type: 'tree', name: row[dimension], data: row[metrics] } if (seriesMap[row[dimension]]) { Object.keys(seriesItem).forEach(key => { if (isObject(result[key])) { Object.assign(result[key], seriesItem[key]) } else { result[key] = seriesItem[key] } }) } series.push(result) })可以看到:每一行都会生成一个type: 'tree'的 series 项,name取自行的维度值,data取自行的指标值;随后以seriesMap[name]为准,把配置项逐 key 合并进 series。若目标 key 已是对象(如label、lineStyle),则做深一层合并;否则直接覆盖。这正是seriesMap中layout、orient、top、left等配置能直接透传给 ECharts 的原因。
六、径向树图与纵向树图
树图默认采用“横向展开”的布局,通过seriesMap中设置layout或orient即可切换形态,无需改动任何数据。
6.1 径向树图(layout: 'radial')
设置layout: 'radial'后,树以根节点为圆心向外辐射展开:
<template> <ve-tree :data="chartData" :settings="chartSettings"></ve-tree> </template> <script> // treeData 与基础示例中的 treeData 相同 export default { data () { this.chartSettings = { seriesMap: { tree1: { layout: 'radial' } } } return { chartData: { columns: ['name', 'value'], rows: [ { name: 'tree1', value: [treeData] } ] } } } } </script>径向布局适合展示根节点突出、层级较深的树形结构,视觉效果更接近思维导图。
6.2 纵向树图(orient: 'vertical')
设置orient: 'vertical'则让树沿纵向自上而下展开:
<template> <ve-tree :data="chartData" :settings="chartSettings"></ve-tree> </template> <script> // treeData 与基础示例中的 treeData 相同 export default { data () { this.chartSettings = { seriesMap: { tree1: { orient: 'vertical' } } } return { chartData: { columns: ['name', 'value'], rows: [ { name: 'tree1', value: [treeData] } ] } } } } </script>注意:默认的横向布局对应orient: 'horizontal',纵向布局则显式指定orient: 'vertical'即可。
七、自定义提示框内容
树节点默认的提示框只展示节点名与数值。v-charts 为所有图表提供了tooltip-formatter属性(配合tooltipFormatter方法)来定制提示框内容,同时可用extend属性直接扩展 ECharts 的 tooltip 配置。下面这个示例让提示框常驻显示(alwaysShowContent: true),并在内容中渲染出节点link的可点击链接:
<template> <ve-tree :data="chartData" :extend="chartExtend" :tooltip-formatter="tooltipFormatter" :settings="chartSettings"></ve-tree> </template> <script> // treeData 与基础示例中的 treeData 相同 export default { data () { this.chartSettings = {} this.chartExtend = { tooltip: { alwaysShowContent: true } } return { chartData: { columns: ['name', 'value'], rows: [ { name: 'tree1', value: [treeData] } ] } } }, methods: { tooltipFormatter (v) { return [ `${v.seriesName}: ${v.data.value}`, `<a target="_blank" href="${v.data.link}">${v.data.link}</a>` ].join('<br>') } } } </script>7.1 tooltipFormatter 的入参
tooltipFormatter接收的v是 ECharts 触发提示框时传入的参数对象,在树图场景中常用字段有:
v.seriesName:当前树的系列名(即行的name,如tree1);v.data:当前悬停节点的数据对象,可访问v.data.name、v.data.value、v.data.link等自定义字段。
示例中把v.data.link渲染成<a>链接并设置target="_blank",实现“悬停树节点 → 提示框展示可点击链接”的交互。
7.2 树图默认 tooltip 行为
即使不做任何配置,v-charts 也会为树图生成默认 tooltip。在 getTreeTooltip 中可以看到:
return { trigger: 'item', triggerOn: 'mousemove', formatter: tooltipFormatter }默认trigger: 'item'(悬停节点触发)、triggerOn: 'mousemove'(鼠标移动即触发),formatter默认取extra中传入的tooltipFormatter(即组件属性tooltip-formatter),不传时由 ECharts 渲染默认内容。
八、源码原理:ve-tree 的配置生成链路
理解整条数据到配置的链路,有助于排查问题与做深度定制。全流程由 核心渲染逻辑 驱动:
- 组件挂载与监听:
core.js在mounted时调用init()(core.js),通过echarts.init创建实例;data、settings等属性通过深度 watch 触发重绘(core.js)。 - 数据加工:
dataHandler(core.js)取出columns、rows,组装extra对象(包含tooltipVisible、legendVisible、tooltipFormatter、color等),然后调用各图表注册的chartHandler——树图的 handler 就是 tree 函数。 - 配置生成:
tree函数依次生成series、legend、tooltip三部分并返回。 - 配置后处理:
optionsHandler(core.js)负责把extend、colors、mark*、animation等合并进最终 options,再调用echarts.setOption渲染。
8.1 树图的 legend 生成规则
与普通折线图、柱状图不同,树图的图例不是默认必显的。在 getTreeLegend 及主函数中可以看到:
const legend = legendVisible && rows.length > 1 && getTreeLegend({ dimension, rows })- 只有
legendVisible(组件属性legend-visible,默认true)且rows.length > 1(即存在多棵树)时才会生成图例; - 图例数据是每行的维度值(树名列表),用于点击切换各棵树的显示/隐藏。
这解释了为什么单树图默认不显示图例——避免无意义的图例干扰画面。
8.2 extend 属性的合并规则
自定义提示框示例中的extend由 modules/extend.js 处理,其合并规则是:
- 值为函数时,以函数的返回值作为对应配置;
- 值为对象时,若 options 中对应属性也是对象(如
tooltip),则做Object.assign合并;若是对象数组(如series),则逐项合并;否则直接覆盖。
因此chartExtend = { tooltip: { alwaysShowContent: true } }会与树图生成的tooltip对象合并,最终得到{ trigger: 'item', triggerOn: 'mousemove', formatter, alwaysShowContent: true }。
8.3 组件支持的其他常用属性
除data、settings、extend、tooltip-formatter外,ve-tree继承了 docs/props.md 中列出的全部公有属性,树图场景中比较常用的有:
| 属性 | 说明 | 默认值 |
|---|---|---|
| width / height | 画布尺寸 | auto / 400px |
| tooltip-visible | 是否显示提示框 | true |
| legend-visible | 是否显示图例 | true |
| colors | 自定义配色数组 | 内置 13 色 |
loading />chartEvents: { click: (params) => { if (params.data && params.data.link) { window.open(params.data.link) } } }9.2 多树图务必配置布局区域当 9.3 修改树形数据会触发自动重绘
9.4 通过 ve-chart 切换图表类型如果你希望同一份数据在不同图表间切换,可以使用 总结本文完整覆盖了 v-charts 树图从引入、数据组织到五大渲染场景的全部用法: 赞
【免费下载链接】v-charts基于 Vue2.0 和 ECharts 封装的图表组件📈📊 项目地址:https://gitcode.com/gh_mirrors/vc/v-charts 相关推荐
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考 |