效果截图
前些天有读者问,ECharts 的提示框(tooltip)内,能不能添加一个饼图?
我之前倒是看到过用饼图作为散点图数据点的例子,感觉应该有办法……但是提示框和那个不太一样,估计需要研究一下——所以先回复说,这个之前没有尝试过,我有空试一下。
实现思路(一段曲折的过程)
当天晚上有事,没来及看,转天上班途中,先看了眼配置项手册,在确认没有现成功能可用的同时,注意到了一个关键点:提示框是一个 DOM 节点,也就是有办法作为 ECharts 的容器。
浮层的渲染模式,默认以 'html 即额外的 DOM 节点展示 tooltip;此外还可以设置为 'richText' 表示以富文本的形式渲染,渲染的结果在图表对应的 Canvas 中(目前 SVG 尚未支持富文本),这对于一些没有 DOM 的环境(如微信小程序)有更好的支持。 ECharts 配置项手册https://echarts.apache.org/zh/option.html#tooltip.renderMode
另外,其实从「tooltip.formatter」默认的换行符是「<br />」而不是「\n」这一个特点上,也可以推测得到的。
有了这个关键点,大体的思路就有了:
通过回调函数返回一个带 id 属性的 div,比如
以这个 div 为容器,初始化 ECharts 实例;
根据触发提示框的 params 属性,准备相应的饼图配置项,渲染对应的饼图
大体思路图示
但是还存在一个问题需要解决,这个问题有 2 个难点:
问题 1
为了解决这个问题,我想到了 2 种尝试的思路:
然后我就开始尝试有可能最简单的第 1 种,结果发现提示框中的饼图时有时无……然后经过各种分析,打点、测试、翻源码(其实没咋看懂),明白了大致原因:
提示框(tooltip)的移动,不触发「events.finished」事件,也就是当提示框指示的数据项/数据轴没发生改变时,提示框发生了「move」,而不是先「hide」再「show」:
第 1 种思路尝试失败
然后开始试图尝试第 2 种,但作为一个先接触 ECharts 后接触 JavaScript 的 JS 小白,我毫无悬念地、稀里糊涂地失败了
各位前端大神们,有兴趣的话,可以亲自尝试一下,我就不班门弄斧了……
被 callback 虐了半天的自己,郁闷了 10 多分钟……然后终于,自暴自弃地,想到了简单暴力的第 3 种方法:
// 准备一个饼图的 option
let pieOption = {
series: {
type: "pie",
labelLine: {
show: false
},
label: {
show: false
}
},
animation: false
};
option = {
title: {
text: '读者提问,提示框能否显示饼图'
},
xAxis: {
data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
},
yAxis: {},
tooltip: {
trigger: 'axis',
formatter: params => {
// 根据触发提示框的数据,准备饼图数据
let pieData = [];
for (let i in params) {
pieData.push({
name: params[i].seriesName,
value: params[i].value,
color: params[i].color
});
}
// 将饼图数据存入饼图 option.series.data
pieOption.series.data = pieData;
return `${params[0].axisValue}<br/><div id="tooltipPie" style="width: 100px;height:100px;"></div>`;
}
},
series: [{
type: 'bar',
stack: 'stack1',
data: [220, 182, 191, 234, 290, 330, 310]
}, {
type: 'bar',
stack: 'stack1',
data: [120, 122, 91, 324, 113, 130, 410]
}, {
type: 'bar',
stack: 'stack1',
data: [42, 32, 29, 72, 31, 63, 101]
}]
};
/**
* 因为每次弹出/移动提示框,都会覆盖提示框 DOM,所以只能每次都重新渲染饼图
* (暂且使用了个笨办法 setInterval,10 毫秒判断处理一次 = =b,有时间再想想更好的方式)
*/
setInterval(function(){
if (document.getElementById('tooltipPie') !== null && document.getElementById('tooltipPie').innerHTML === '') {
if (typeof tooltipChart !== 'undefined') {
return tooltipChart.setOption(pieOption);
}
var tooltipChart = echarts.init(document.getElementById("tooltipPie"));
tooltipChart.setOption(pieOption);
}
},10);
就是这段,每隔 10 毫秒,检测一次提示框饼图容器的内部是否为空,如果是,就重新渲染一遍饼图,这次算是非常不优雅的成功了
本文分享自 ZXand618的ECharts之旅 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!