☰
v-charts 树图(ve-tree)组件实战指南:数据格式、多树布局与提示框定制
2026/10/12 5:37:58 网站建设 项目流程
  • 前端
  • 数据可视化
  • UI组件

【免费下载链接】v-charts

基于 Vue2.0 和 ECharts 封装的图表组件📈📊

项目地址:https://gitcode.com/gh_mirrors/vc/v-charts
点击查看免费下载

导读

树图(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 -S

1.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 的配置生成链路

理解整条数据到配置的链路,有助于排查问题与做深度定制。全流程由 核心渲染逻辑 驱动:

  1. 组件挂载与监听:core.js在mounted时调用init()(core.js),通过echarts.init创建实例;data、settings等属性通过深度 watch 触发重绘(core.js)。
  2. 数据加工:dataHandler(core.js)取出columns、rows,组装extra对象(包含tooltipVisible、legendVisible、tooltipFormatter、color等),然后调用各图表注册的chartHandler——树图的 handler 就是 tree 函数。
  3. 配置生成:tree函数依次生成series、legend、tooltip三部分并返回。
  4. 配置后处理: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 多树图务必配置布局区域

当rows超过一行且未设置seriesMap时,多棵树会重叠在画布中央。建议在seriesMap中为每棵树规划top/left/bottom/right,同时注意各区域不要相互交叉。

9.3 修改树形数据会触发自动重绘

core.js对data使用深度监听(deep: true),因此直接修改treeData中任意节点的value、增删children,都会触发组件重新生成配置并调用setOption,无需手动刷新。对于高频变化的场景,可通过change-delay属性调整重绘的防抖延迟。

9.4 通过 ve-chart 切换图表类型

如果你希望同一份数据在不同图表间切换,可以使用<ve-chart>组件并仅改变settings.type,参照 docs/toggle.md。将type设为'tree'即可渲染树图,同时示例页面 chart.vue 展示了如何在页面中按类型动态渲染ve-tree的完整集成方式。

总结

本文完整覆盖了 v-charts 树图从引入、数据组织到五大渲染场景的全部用法:columns/rows统一数据格式、dimension/metrics默认值规则、seriesMap的多树布局与样式定制、layout: 'radial'径向布局、orient: 'vertical'纵向布局,以及基于tooltip-formatter与extend的提示框定制。结合 src/packages/tree/main.js 的源码可以看到,所有这些能力最终都收敛为“每一行 → 一个type: 'tree'的 series”,这正是 v-charts 树图简洁灵活的根本所在。需要深入排查渲染细节时,可打开组件的log属性,在控制台查看最终生成的 ECharts options。

  • 前端
  • 数据可视化
  • UI组件

【免费下载链接】v-charts

基于 Vue2.0 和 ECharts 封装的图表组件📈📊

项目地址:https://gitcode.com/gh_mirrors/vc/v-charts
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询