echarts饼图位置调整(echarts怎么设置饼图与引导线间距)

本文目录
- echarts怎么设置饼图与引导线间距
- ECharts 自定义系列 profile 坐标转置
- 饼图标签布局方案
- ECharts饼图文本标签间距问题Hack
- 我用的echarts做的饼图,一个页面中写了2个 ,页面没法往下拉,怎么解决
echarts怎么设置饼图与引导线间距
list2=
%》
var myChart = echarts.init(document.getElementById(’chart1’));
var option = {
title : {
text: ’项目结构分析’,
x:’center’
},
tooltip : {
show: true
},
legend: {
orient: ’vertical’,
x: "left",
ECharts 自定义系列 profile 坐标转置
ECharts 自定义系列 profile - ECharts
希望将 ECharts 自定义系列官方提供的 profile 图表,横纵坐标进行转换。
encode 的作用是 映射 。
简单的说,就是从一个二维数组中,选择需要映射那几列数据到图表中。本例中,encode 从 data.value 中映射数据。
数据映射,有两层意思。
画布的尺寸是有限的,也是是随界面布局的变化,时时相对发生变化。
图形(柱状图,折线图,饼图等等)在画布上的比例(相对尺寸)是一定的,那么一个具体的数值,在展现在图形上时,就需要按照一定的比例进行映射。
以本例为例,
画布大概只有 400*600 px
x 轴,只有3个数据 (0,1,2)
y 轴,上的数据很多,是基于时间戳用随机数计算出来的(例如:1510975537362),科学计数法基本上都在 10e12 这个范围。
显然,不可能直接把数值 转化为像素,因此就需要知道 x 和 y 轴的 最大值 和
最小值 然后把每一个具体的值映射为屏幕中的像素值。
上面 encode 中,x 只选择 data.value 中的第一列,也就是范围 0-2;y 轴选择 data.value 中的第二、三列(即开始时间和结束时间范围)
在数值到画布坐标映射时,调用 api.coord() 这个方法实现。本例中详见 series-custom.renderItem 的说明
本例中,data 是由 echarts.util.each(categories, function (category, index) 生成的。data 的完整结构如下:
xAxis 和 yAxis 的作用是绘制坐标轴。
在转置的时候,坐标轴需要配套转置。
renderItem 是数据映射过程中的关键,其作用好比 excel 中的数据透视表。不同的是,renderItem 需要把图形是什么样子的,定义清楚。
在本例中,我们需要对坐标轴进行转置,因此,在一开始的时候,修改了 series-custom.encode 中的映射行为。坐标轴对应的数据发生了修改,因此,在映射具体图形坐标的时候,需要配套修改。
这个方法用来获取一组坐标在画布中的坐标轴上对应的长度。这就好比获取地图比例尺的长度。返回值为一个数组,第一个元素对应x轴,第二个元素对应y轴
本例中,我们想知道转置以后,x轴一个单位的长度。
饼图标签布局方案
本文作者 字节跳动-数据平台-melon
引言
在做数据可视化相关的工作中,开发人员总是必不可免的需要与标签打打交道。在画布空间充裕,数据量不大,标签内容简洁的理想国中,一切自然不成问题。但是现实场景中,芜杂的需求,庞大的数据,向我们提出了要求:如何合理的组织标签的布局,从而尽可能多且美观的展示标签。
不同图表都有着其各自空间以及美学考量的特性,本文主要着眼于饼图的标签布局。
首先抛出一个普适的前提:画布空间是有限的,因此在其中能够有效展示的标签数量是有限制的。基于这一前提,我们有几个需要关注的问题:
相关产品饼图标签布局
在讨论饼图布局方案之前,首先让我们来看看其他产品的饼图布局:
G2
G2 饼图标签会按照饼图外圆进行排布,并用短连接线从扇区指向标签左端或者右端中点。
但是令人费解的是,在顶部以及底部的标签,其连接线却转为了弧线,并指向了标签上部或者下部,令人很难理解其处理逻辑为何,甚至于当标签较密时无法将标签与连接线相对应。
此外,也能看到其顶部和底部标签出现了重叠,导致失去了可读性。
ECharts
ECharts 对标签布局提供了几种方案,自左至右分别是 none,labelLine,edge,其分别意味着按照饼图外圆排布、标签水平方向对齐、标签按画布边缘对齐。三种方案,其标签位置的 Y 值均相同。究其本质,后两种方案其实就是 第一种方案的基础上改变了标签的 X 值 而已。
ECharts 饼图标签与扇区的连接线为两段线,第一段由扇区指出,第二段保证水平。
ECharts 相比较于 G2 而言,提供了标签相互躲避的算法,当标签数量非常大时,仍然保证了一定程度的可读性(后两种方案),但是在某些区域标签依旧出现了重叠,例如画布顶部。
第一种方案在标签数量较大时表现非常怪异,其标签布局明显划分为了四个区域,上下的标签布局出现了割裂,同时左右标签互相影响出现了遮挡,甚至超出了画布。
其他
Tableau 不支持引导线的设置,也就意味着其没有布局能力。虽然 Tableau 会对遮挡的标签进行隐藏,但是其仍然无法支持大量标签的显示。
网易有数也支持标签的遮挡隐藏。其同样采用饼图外圆的布局,做了标签的躲避,并且使用了一个较为诡异的贝塞尔连接线来防止连接线穿过饼图区域。
其他产品相类似,这里不再赘述。
简单总结一下,为了提升标签的可读性,许多产品都使用了饼图外圆弧的布局方式。当标签数量较大时,或者隐藏被遮挡标签仅显示少量标签,或者提供标签的位置调整并使用引导线连接对应扇区。
基于我们之前给出的关注问题,调整方案能够容纳更多标签,展示更多信息,比起遮挡而言相对更好。事实上,之前在我们自己的产品中也采取了类似 ECharts 的布局方案,但是由于 ECharts 的布局策略中本身存在诸多不足,因此需要做一次全面的改进。
布局方案
基于诸多考量,我们提出了自己的标签布局方案。首先来看看我们的布局效果吧:
最简单的标签布局情况自然没有问题。
当标签数量开始增多的时候同样能够合理的组织标签位置展示。
在数据量极其巨大的极端情况下,同样能够保证充分利用画布空间展示有效信息。
看起来似乎不错,那么我们做了哪些工作呢?
整体布局策略
一如之前所说,基于饼图外圆的标签排布是许多布局方案的基础,由于饼图本身的几何特性,这一布局同样也是最为直观的选择。
但是基于外圆的布局存在一个重要的缺陷:圆图形本身是 **封闭 **的,也就意味着其所能容纳的标签数量有限。这一缺陷导致标签布局无法有效的利用画布剩余空间。这一缺陷当然可以采用扩大外圆半径的方式来解决,但这也意味着布局同时侵占了画布横向与纵向的空间,同时外圆与扇区中间的间隔过大也影响了布局的美观。
ECharts 采用了一种并不优雅的方式来解决这一问题,即在外圆布局的基础上引入了第二种布局逻辑。第二种布局逻辑会在标签数量较大时生效,其不遵循外圆的约束,而将标签推移一个固定值,这也就是导致极端情况下 ECharts none 布局下半区域左右标签过度延伸的原因。
引入额外的逻辑作为补充导致了两个恶果:
虽然 ECharts none 布局在标签数量巨大时表现糟糕,但是后两种布局表现就好上许多。究其原因,是源于后两种标签在 X 值的计算上有一个统一且可靠的逻辑,即 标签的 X 值由其 Y 值确定 ,而不像第一种布局在局部上受到不同计算逻辑影响。这也给予了我们布局的基础思路:执行遮挡规避对标签 Y 值进行调整,之后通过全局规范确定其 X 值。
为此,我们放宽了外圆布局所暗含的同心圆假设,使用两个圆心不同的圆弧替代外圆布局标签。在保证标签 X 值计算具有统一规范的同时,支持对标签数量进行扩展,如下图所示:
由于目前标签布局仅考虑横排文字,因此将外圆拆分为了左右两个圆弧,两者圆心均与饼图在同一水平线上。两个圆弧与水平线的交点与饼图圆心的距离相等,即 |A O0| = |B O0|,该距离由连接线的配置所决定并为一固定值。
确定 |A O0| 以及 O1 在水平线上之后,O1 的位置也就由其半径所确定。当展示标签较少时,外圆能够容纳所有标签,此时 O1 落在 O0,与外圆布局相同。当标签数量变大时,标签在 Y 方向上会执行调整,圆弧半径也随之扩大,从而在 Y 方向上占据更多空间。
介绍了整体的布局策略,该来谈一谈一些具体的做法。
遮挡规避
在计算每个标签对应扇区数据以及获取到标签本身宽高之后,需要对标签计算其初始的位置。初始状况下,所有标签在默认情况排布在饼图外圆的对应位置。
理想状况下,自然是无需做后续操作,每个标签呆在其应处的位置。但是当标签出现遮挡时,就需要采取一些算法对这一遮挡进行规避。
遮挡规避算法多是大同小异,无非是处理相互遮挡的标签如何偏移遮挡的距离(我们所采用的规避算法与 ECharts 相类似)。此时我们的指导思想也为我们提供了许多的便利:遮挡规避仅仅需要考虑标签的 Y 值,而 X 值是在后续过程中被确定的。下图展示了碰撞规避的简单流程:
在执行布局的过程中,我们会依次向画布放置标签。假设我们当前所处理的标签为 A,检测到其与后一个标签 B 发生了遮挡,此时需要执行规避。规避分为两个阶段:
简单来讲,ShiftDown 与 ShiftUp 两个阶段的含义就是当标签发生遮挡时,将两者以及其临近的标签各自推移一半的遮挡距离。
优先级
上图中占有较大扇区的标签由于被挤压超出了画布无法展示。为了解决这一问题,有必要将所有的标签进行优先级排序。
标签按照其对应扇区面积排序自不消说,标签按照其优先级依次放入画布执行遮挡规避也很自然。值得关注的问题在于:当上一个标签执行完毕碰撞规避后,当前标签应当落在何处?
如果仅仅是简单的将标签放在默认的位置,就可能导致扇区的先后顺序与标签的先后顺序不对应,其引导线自然也会出现交叉。为此,应当同时保留标签的优先级顺序以及对应扇区的顺序。在标签放入画布时,寻找其扇区顺序上的前后标签:
为了保证高优先级标签不会被低优先级标签挤出画布,还需要设置一个合理的布局 终止条件 。当标签放入并执行了碰撞规避后,程序会检测画布最顶端和最低端的标签,并且尝试将超出画布的标签向内推移。如果一次推移之后仍旧存在超出画布的标签,则可以认为此时画布已经过度拥挤,当前标签不应当被显示。此时便可以将所有标签 Y 值恢复到上一轮标签布局结束时,并终止新标签的放入。
除了保证高优先级的标签有更高概览展示之外,优先级也提供了布局 **性能优化 **的可能。比起 ECharts 所采用的所有标签一块进行遮挡规避的方案,按照优先级依次布局的方案不用在每一轮处理所有的标签。同时,终止条件保证了在标签数量极大的情况下,最多也仅需要处理画布所能容纳的最大标签数量。除去优先级排序的过程,最坏情况下,ECharts 布局的复杂度为 O(2N^2),而我们的方案则为 O(4K^2),其中 K 为画布最大容纳标签数量。
切线限制
前头谈的都是标签文字的布局,但是别忘了我们还有引导线的绘制。虽然引导线仅仅是由连接标签和扇区的辅助,但是其本身也有一定的美学要求,例如引导线不应当穿过饼图的区域:
上图给出了一个引导线影响饼图绘制的极端示例。当然,这是一个旧算法下的执行结果,在新的优先级布局策略生效的情况下,结果可能不会变得如此糟糕,但是引导线遮盖扇区的情况仍是难以避免的。
为了防止这一现象的发生,在每个标签执行遮挡规避之后,布局策略额外增加了切线的检查。也即是以当前标签对应扇区的中点为切点绘制切线,并计算该切线到该侧布局圆弧的交点,从而获取到该标签 Y 值的调整范围。
在实现过程中,这一策略会面临一个问题:布局圆弧的半径计算依赖于优先级布局的结果,而在优先级布局的过程中又需要布局圆弧半径来做切线的检查。这样一来似乎陷入了“:chicken:生:egg:生:chicken:”的困境。
这时候就需要我们给出一个额外的假设条件: 当引导线穿越扇区的情况发生时,必然是由于标签触及到了画布顶端或者底端并向画布中间挤压所导致 。
基于这一条件,用于切线检查的圆弧半径只需要设置为最大的圆弧半径即可。这样一来,问题迎刃而解,剩下的便仅是重新捡起中学数学的课本,解几个方程罢了。
不足之处
虽然目前的策略能够合理的利用画布空间展示标签信息,但是也仍然存在某些可以改进的地方。
不支持自动换行
目前的布局策略支持多行文字的展示,但是并不支持文字的 自动换行 。
由于我们的策略将标签布局在圆弧上,因此标签可绘制文字的剩余空间依赖于标签 Y 值调整算法输出的结果。自动换行生效时,其会导致标签高度的改变,又会重新触发 Y 值调整算法;而再一次调整结束后,标签可能得到了足够的空间,又变为单行显示,最终坠入了无限循环的地狱。
切线限制影响优先级展示
在布局的过程中,我们同时应用了优先级的布局以及切线的限制。在某些特殊情况下,切线策略会导致标签并不完全按照优先级进行展示,如下图所示:
可以看到,相对而言具有较大扇区的济宁由于切线策略的限制,无法显示标签;但是底部扇区极小的上海却能够显示。当然,这一点也很难说是一个 Bug,因为图中的示例虽然打破了标签显示的优先级,但是更好的利用了画布空间。
标签换边
如果说前两个问题是由于策略基本思想导致的难以解决的痼疾,或者仅仅是美学考量上的取舍,那么标签换边则是一个后续切实可以改进的方面。如下如所示:
可以看到饼图底部两个扇区标签并未显示。这两个标签处在饼图的右半边,在这一半边其优先级不足,因此被舍弃。但是如果将其换到左半边,则拥有较高的优先级,可以为其安排展示的空间。但是哪些标签需要换边,标签换边之后是否会破坏原先的布局逻辑,仍然是一个需要好好讨论的问题。
数据平台前端职位热招中,扫码进入我的 内推渠道:
ECharts饼图文本标签间距问题Hack
在用 ECharts 作饼图的过程中遇到文字标签过于拥挤,需要增加标签间距离的问题,比如下图:
这个图大小为200*200(大小过大没有效果),ECharts 配置项如下:
ECharts 配置项中有 lineHeight 一项,修改以后发现并没有什么效果,但其实它修改的是整个标签块的行高,我们加上边框以后就可以发现端倪:
上图 ECharts 配置项变更处如下:
我发现 avoidLabelOverlap 只是根据 fontSize 来计算得到文本所占的大小来避免标签重叠,与整个标签块的大小没有关系(不知道以后会不会改正),所以要增加标签间距只能加换行:
效果图如下:
最简单的修改到这里就可以了。这里有两个不够完美的小问题:1) 标签和横线不对齐,2) 只能增加整数倍间距,0.5 行这样的间距无法实现,要解决这两个问题请往下看。
ECharts 文本标签支持富文本样式 rich ,所以可以不同行用不同字体大小,记住富文本样式中的 fontSize 也只是影响显示的文字大小,不影响 avoidLabelOverlap 计算。然后标签和横线不对齐的问题就靠上下都多加一行解决。最后就是如何计算基础行高,即外部的 fontSize 了:
字体大小 myFontSize 12,文字 lines 1行,标签间距 space 0.5行,求基础行高 myLineHeight。
其中2表示上下多加的两行。
最终版本:
效果图:
我用的echarts做的饼图,一个页面中写了2个 ,页面没法往下拉,怎么解决
《div id="main" style="width: 600px;height:400px;"》《/div》绘图的时候会初始化两个div区域会指定大小,你看一下你2个div指定的height高度和页面的高度有没有冲突,可能是2个div的高度超过了你页面其他地方设置的height,导致只能显示出一半

更多文章:
plot函数作用(MATLAB中plot函数和line函数作用有区别吗)
2026年7月25日 23:00
变形金刚ksi公司(变形金刚4中有哪些中国广告 变形金刚4植入的中国广告汇总)
2026年8月1日 18:45
vocabulary英语(vocabulary怎么读 英语vocabulary怎么读)
2026年5月9日 17:30
java简单图书管理系统(求一个java图书管理系统代码,不需要图形化,命令行就可以,只要求实现导入图书,查询,删除)
2025年9月21日 13:00
oracle执行脚本文件(如何利用脚本文件来管理Oracle数据库)
2025年10月19日 19:30
directx出现了致命错误 最终幻想14(玩最终幻想14老是提示没有安装DirectX,可是已经安装过了)
2026年8月18日 13:45
8086汇编语言程序设计速成课(8086的编程题(使用汇编语言))
2025年10月10日 03:15
delphi定义(DELPHI基础教程:Delphi自定义部件开发(二)[4])
2026年2月28日 09:15
matlab定义含参变量函数(matlab中如何以函数为参数定义函数文件)
2026年9月11日 12:30
subplot指令(excel怎么画高斯分布_excel正态分布函数)
2025年10月23日 09:45
正则表达式1000到3999(用正则表达式提取这个式子中的数字)
2026年5月14日 09:30













