如何在ECharts折线图中对特定Y轴区间进行非线性缩放(偏斜显示)
如何在ECharts折线图中对特定Y轴区间进行非线性缩放(偏斜显示)
我完全理解你想让Y轴某段区间占更大绘图空间的需求,这种非线性缩放的效果在ECharts里其实可以通过自定义Y值的视觉映射函数来实现,不用太复杂的操作,我结合你提供的代码给你一步步说明~
核心思路
我们的核心思路是:把原始的Y轴数值,按照我们想要的比例映射到一个新的“视觉数值”上——让需要压缩的区间(比如你的0-40)对应到更小的视觉范围,需要拉伸的区间(40-50)对应到更大的视觉范围。然后让ECharts用这个视觉数值来绘图,同时把Y轴的刻度标签显示回原始数值,这样用户看到的就是“区间被拉伸/压缩”的效果,但刻度还是原始的真实值。
具体实现步骤
首先我们先写好原始值↔视觉值的双向转换函数,这是实现的核心:
// 原始Y值转视觉值:0-40对应视觉0-33(占1/3高度),40-50对应33-100(占2/3高度) function yToVisual(y) { if (y <= 40) { return (y / 40) * 33; } else { return 33 + ((y - 40) / 10) * 67; } } // 视觉值转原始Y值,用于Y轴刻度显示 function visualToY(v) { if (v <= 33) { return Math.round((v / 33) * 40); } else { return 40 + Math.round(((v - 33) / 67) * 10); } }
接下来,我们修改你的ECharts配置,把这个映射逻辑加进去:
1. 处理数据:把原始Y值转换成视觉值
原来的eChartsDataValues是直接用原始Y值,现在我们换成转换后的视觉值:
const eChartsDataValues = dataValues.map((dv) => [dv.date, yToVisual(dv.value)]);
2. 配置Y轴:让刻度显示回原始值
修改yAxis的配置,让ECharts用视觉值绘图,但刻度标签显示原始值,同时设置关键的刻度点保证准确性:
yAxis: { min: 0, max: 100, // 视觉值的范围设为0-100,对应整个图表高度 axisLabel: { // 把视觉值转回原始值作为刻度标签 formatter: function(v) { return visualToY(v); } }, axisTick: { alignWithLabel: true }, // 自定义刻度点,对应原始数据的关键节点,让刻度更直观 data: [ yToVisual(0), yToVisual(10), yToVisual(20), yToVisual(30), yToVisual(40), yToVisual(45), yToVisual(50) ] },
3. 适配MarkArea:用视觉值设置区间
因为现在Y轴用的是视觉值,所以MarkArea的Y轴区间也要用转换后的数值:
markArea: { silent: true, emphasis: { disabled: true, }, label: { fontSize: 12, textBorderColor: "transparent", position: "insideBottomLeft", }, data: [ [ { name: "This is mathematically a shorter range (40-50), but it should take up the majority of space on the graph", yAxis: yToVisual(40), itemStyle: { color: "red", }, }, { yAxis: yToVisual(50), }, ], [ { name: "This is mathematically a bigger range (0-40) but should take up a smaller section of the graph", yAxis: yToVisual(0), itemStyle: { color: "green", }, }, { yAxis: yToVisual(40), }, ], ], },
完整修改后的代码
把所有修改整合后,你的代码会变成这样:
import { format } from "date-fns"; import { createFakeValues } from "../utils"; // 原始Y值转视觉值:0-40对应视觉0-33(占1/3高度),40-50对应33-100(占2/3高度) function yToVisual(y) { if (y <= 40) { return (y / 40) * 33; } else { return 33 + ((y - 40) / 10) * 67; } } // 视觉值转原始Y值,用于Y轴刻度显示 function visualToY(v) { if (v <= 33) { return Math.round((v / 33) * 40); } else { return 40 + Math.round(((v - 33) / 67) * 10); } } const dataValues = createFakeValues({ yValues: [29, 32, 35, 40, 47, 49, 50, 49, 48, 45, 43, 39, 35, 30, 27, 25, 24], startDate: new Date("2024-12-01T18:27:08.199Z"), dateDeltaMs: 1800000, }); const eChartsDataValues = dataValues.map((dv) => [dv.date, yToVisual(dv.value)]); export const eChartsOptions = { dataset: [ { source: eChartsDataValues, dimensions: ["timestamp", "value"], }, ], xAxis: { type: "time", }, yAxis: { min: 0, max: 100, axisLabel: { formatter: function(v) { return visualToY(v); } }, axisTick: { alignWithLabel: true }, data: [ yToVisual(0), yToVisual(10), yToVisual(20), yToVisual(30), yToVisual(40), yToVisual(45), yToVisual(50) ] }, series: [ { name: "Y Level", type: "line", smooth: true, datasetIndex: 0, showSymbol: false, encode: { x: "timestamp", y: "value", }, markArea: { silent: true, emphasis: { disabled: true, }, label: { fontSize: 12, textBorderColor: "transparent", position: "insideBottomLeft", }, data: [ [ { name: "This is mathematically a shorter range (40-50), but it should take up the majority of space on the graph", yAxis: yToVisual(40), itemStyle: { color: "red", }, }, { yAxis: yToVisual(50), }, ], [ { name: "This is mathematically a bigger range (0-40) but should take up a smaller section of the graph", yAxis: yToVisual(0), itemStyle: { color: "green", }, }, { yAxis: yToVisual(40), }, ], ], }, }, ], };
适配其他区间比例
如果你之后需要调整区间比例(比如你提到的0-70占1/3,70-100占2/3),只需要修改转换函数的逻辑即可:
function yToVisual(y) { if (y <= 70) { return (y / 70) * 33.33; // 0-70对应0-33.33(1/3高度) } else { return 33.33 + ((y - 70) / 30) * 66.67; //70-100对应33.33-100(2/3高度) } } function visualToY(v) { if (v <= 33.33) { return Math.round((v / 33.33) * 70); } else { return 70 + Math.round(((v - 33.33) / 66.67) * 30); } }
这样就能轻松实现任意区间的拉伸/压缩需求啦~
备注:内容来源于stack exchange,提问作者dwat
相关产品推荐
相关产品推荐

