8月echarts记录-雷达图tooltip实现单轴显示、解决柱状/折线图点击非图表图形元素不会触发事件、柱形图点击选中改变背景颜色等
雷达图tooltip实现单轴显示
问题描述
雷达图官方默认tooltip显示如图,在鼠标移动到某一条轴数据时显示所有指标的值。
需求却要求如图二展示,在鼠标移动到某个label上时用弹框显示所有轴该指标的值。
解决方案
设置两组radar,第一组正常显示,第二组设置为透明色
设置两组seriestooptip,使用第二组的数据和格式化展示
radar: [
{
// 第一组的样式,自己定义
center: ["50%", "50%"], // 外圆的位置
radius: "65%",
name: {
textStyle: {
color: "rgba(0,0,0,0.65)",
fontSize: 12,
fontWeight: 400,
},
},
// TODO:
indicator: [
{ text: "第一条轴" },
{ text: "第二条轴" },
{ text: "第三条轴" },
{ text: "第四条轴" },
{ text: "第五条轴" },
],
splitArea: {
// 坐标轴在 grid 区域中的分隔区域,默认不显示。
areaStyle: {
// 分隔区域的样式设置。
color: ["rgba(255,255,255,0)"], // 分隔区域颜色。分隔区域会按数组中颜色的顺序依次循环设置颜色。默认是一个深浅的间隔色。
},
},
axisLine: {
// 指向外圈文本的分隔线样式
lineStyle: {
type: "dashed",
color: "#DCDCDC", // 设置网格的颜色
},
},
splitLine: {
lineStyle: {
type: "dashed",
color: "#DCDCDC", // 设置网格的颜色
},
},
},
// 添加第二组 其样式全部隐藏
{
center: ["50%", "50%"], // 外圆的位置 设置一致
radius: "100%", //设置最长 这样可以在圆心到顶点的位置都可以触发tooptip
name: {
show: false,
},
// TODO:
indicator: [
{ text: "第一条轴" },
{ text: "第二条轴" },
{ text: "第三条轴" },
{ text: "第四条轴" },
{ text: "第五条轴" },
],
// 以下全透明
splitArea: {
show: false,
},
axisLine: {
show: false,
},
splitLine: {
show: false,
},
},
]
series: [
{
type: "radar",
radarIndex: 0,
tooltip: {
show: false,
},
data: [
{
value: [99.18, 0.59, 99.94, 100, 100],
name: "",
itemStyle: {
//此属性的颜色和下面areaStyle属性的颜色都设置成相同色即可实现
color: "#00E319",
borderColor: "#FFF",
borderWidth: 1,
},
areaStyle: {
color: "#00e3191c",
},
},
{
value: [99.18, 0.6, 99.89, 100, 100],
name: "",
itemStyle: {
//此属性的颜色和下面areaStyle属性的颜色都设置成相同色即可实现
color: "#155AD1",
borderColor: "#FFF",
borderWidth: 1,
},
areaStyle: {
color: "#155ad13d",
},
},
],
},
{
type: "radar",
radarIndex: 1, //雷达图所使用的 radar 组件的 index。
zlevel: 1, //必须设置 zlevel大的Canvas会放在zlevel小的Canvas的上面,这样鼠标移入这个维度的tooptip才能展示
tooltip: {
show: true,
formatter: (params) => {
const { data, color } = params.data;
const mark = `<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${color};"></span>`;
return `${params.name}<br/>${mark}昨日 ${data[0]}%<br/>${mark}前日 ${data[1]}%<br/> 环比 ${data[2]}%`;
},
},
data: [
// 按照单个维度画5次,每次只有对应维度有值,即value分别设置为[6200, null, null, null, null] ,[null, 6200, null, null, null],[null, null, 6200, null, null],[null, null, null, 6200, null],[null, null, null, null, 6200]这种
{
value: [6200, 0, 0, 0, 0],
data: [99.23, 99.19, 0.04],
name: "第一个指标",
// 同样的,隐藏样式
itemStyle: {
color: "transparent",
},
areaStyle: {
color: "transparent",
},
},
{
value: [0, 6200, 0, 0, 0],
data: [0.92, 1.09, -15.6],
name: "第二个指标",
itemStyle: {
color: "transparent",
},
areaStyle: {
color: "transparent",
},
},
{
value: [0, 0, 6200, 0, 0],
data: [99.7, 98.54, 1.18],
name: "第三个指标",
itemStyle: {
color: "transparent",
},
areaStyle: {
color: "transparent",
},
},
{
value: [0, 0, 0, 6200, 0],
data: [98.38, 99.96, -1.58],
name: "第四个指标",
itemStyle: {
color: "transparent",
},
areaStyle: {
color: "transparent",
},
},
{
value: [0, 0, 0, 0, 6200],
data: [100, 92.13, 8.54],
name: "第五个指标",
itemStyle: {
color: "transparent",
},
areaStyle: {
color: "transparent",
},
},
],
},
],
解决柱状/折线图点击非图表图形元素不会触发事件
问题描述
- 使用官方的点击click事件,点我们想要点击的时候,发现折线图只有移动到点上、柱状图只有移动到柱子上才生效,其余都无法点击。
- 在数据差别很大的图形中,想准确点击数据较小甚至为0的图形是非常困难的,这就使得一些交互体验不是很好。
解决方案
1. 使用API convertFromPixel和getZr实现
- 代码实现
this.areaChart.getZr().off("click"); // 阻止一次点击事件
this.areaChart.getZr().on("click", (params) => {
const pointInPixel = [params.offsetX, params.offsetY]; //获取到鼠标点击位置
if (this.areaChart.containPixel("grid", pointInPixel)) { //使用containPixel API判断点击位置是否在显示图形区域
let xIndex = this.areaChart.convertFromPixel({ seriesIndex: 0 }, [
params.offsetX,
params.offsetY,
])[0]; //使用API convertFromPixel获取点击位置对应的x轴数据的索引值
const currentObj = chartData[xIndex]; //chartData为数据源 取点击的该数据
//执行想要执行的方法
}
});
// 将可以响应点击事件的范围内,鼠标样式设为pointer
this.areaChart.getZr().on("mousemove", (params) => {
var pointInPixel = [params.offsetX, params.offsetY];
if (this.areaChart.containPixel("grid", pointInPixel)) {
//若鼠标滑过区域位置在当前图表范围内 鼠标设置为小手
this.areaChart.getZr().setCursorStyle("pointer");
}
});
API介绍
- getZr()用于获取Echarts实例中的zrender实例。zrender是一个轻量级的Canvas绘图库,Echarts使用zrender来进行图表的绘制
- containPixel用于判断一个点是否在指定的图形元素内部。
// 用于判断是否在某一个坐标上 使用containPixel 方法支持的类型有 grid, polar, geo, series-map, series-graph, series-pie。
// 判断 [23, 44] 点是否在 geoIndex 为 0 的 geo 坐标系上。
chart.containPixel('geo', [23, 44]); // 'geo' 等同于 {geoIndex: 0}
// 判断 [23, 44] 点是否在 gridId 为 'z' 的 grid 上。
chart.containPixel({gridId: 'z'}, [23, 44]);
// 判断 [23, 44] 点是否在 index 为 1,4,5 的系列上。
chart.containPixel({seriesIndex: [1, 4, 5]}, [23, 44]);
// 判断 [23, 44] 点是否在 index 为 1,4,5 的系列或者 gridName 为 'a' 的 grid 上。
chart.containPixel({seriesIndex: [1, 4, 5], gridName: 'a'}, [23, 44]);
- convertFromPixel是ECharts(百度开发的一个数据可视化库)中的一个方法,用于将像素坐标转换为数据坐标。
echartsInstance.convertFromPixel(coordinateSystem, pixelPoint);
//echartsInstance ECharts实例
//coordinateSystem 坐标系实例
//pixelPoint 像素坐标点,可以是一个数组或者一个对象
//该方法返回一个数组,表示转换后的数据坐标点。 如要将鼠标点击事件的像素坐标转换为数据坐标,可以使用以下代码:
myChart.on('click', function (params) {
var pointInPixel = [params.offsetX, params.offsetY]
}
- getZr().setCursorStyle(‘pointer’) 用于设置鼠标指针样式的,通过 Echarts 库中的
getZr()
方法获取画布对象,然后调用其setCursorStyle()
方法来设置鼠标指针的样式。例如:default, pointer
2.使用ref 或者 echarts 中 getDom() 获取 ECharts 实例容器的 dom 节点,通过addEventListener对click事件进行监听
由于getZr()属于私有API存在过多不稳定因素,也可以选择用这种方法
chart = echarts.init(refChart.value!)
// chart.getZr().on('click', clickHover)
this.$refs.areaChart?.addEventListener('click', (params) => {
// 获取鼠标位移
const pointInPixel = [params.offsetX, params.offsetY]
// 判断坐标是否在grid上
if (chart.containPixel('grid', pointInPixel)) {
//....逻辑同第一种方法
}
多柱形图点击选中改变背景颜色
问题描述
点击多柱状图的柱子时,改变柱子的背景颜色,柱子颜色不改变
解决方案
设置yAxis的splitArea-areaStyle属性,点击时改变该项的color,再赋值
this.areaChart.on("click", (param) => {
//xData 数据的长度 项的长度
let colors = Array.from(Array(xData.length).keys()).map((v) => {
return "rgba(51, 154, 240, 0)";
});
colors[param.data.index - 1] = "rgba(51, 154, 240, 0.4)";
barChartOption.yAxis.splitArea = {
show: true,
areaStyle: {
//多类目时,可以使用数组设置颜色
color: colors,
},
};
this.areaChart.setOption(barChartOption);
});
解决echarts图表点击模块多次触发点击事件
问题描述
点击柱状图的柱子或饼图中的模块时弹出详情,但接口调了两次。
解决方案
在点击事件前阻止一次点击事件
this.areaChart.off("click"); // 阻止一次点击事件
this.areaChart.on("click", (params) => {}); // 模块点击事件