Echarts绘制不均匀数据轴(y)

本文以Echarts柱状图为例,介绍不均匀数据轴图表的构造方法。因Echarts Y轴数值均匀分布,数值差距大时小值难以显示。打破规则的思想是将大数值按规则变为小数据展示。方法包括设置数据间隔、按间隔处理数据、渲染数据,转换数据后可显示小数值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

应用场景(以Echarts柱状图为例):

现有一组数据:最小的数是 50000(5万) ,最大的数是 3000000000(30亿)

如果按照Echarts正常的画法,我们只需提取出来这些数据然后交给Echarts显示即可。

  • 但是这样做面临的问题就很明显——由于数值差距过大,且Echarts本身Y轴的数值是均匀分布的,所以在图里造成的结果是这样的:
    在这里插入图片描述

在图中,y 轴的数值均匀分布,最高的柱子在x轴 第五值为30亿,但是x轴 第一值为5万的柱子,根本看不见,因为差距太大了,包括x轴 第二值为500万的轴,我们也是只能看到一点点红色。

为了要显示出来小一点的值,我们期望的 y 轴排列应该是这样的:

0    10万    100万     1千万    1亿     10亿       20亿      30亿

这样的数值分布规则就完美符合我们的要求。
所以,我们要做的就是打破 y 轴均匀显示的规则(本质上并没有)。

打破规则

思想

针对这种数值大的数据,我们不免会怀念小数值的好处:

  • 比如把上面的数据都更换成小于等于100的数,那么显示起来就毫无问题了,即便数值只有10,但是在最大值是100的图里,也能正常显示。

所以,打破规则用到的思想就是缩小数据体量

  • 上图中,Echarts本身处理的数据间隔是 5亿,这样分跟我们 x轴的设置也有关系,x 轴一共 5 个分部,给的数值里最大30亿,所以分布在 y 轴上以 5亿 为间隔刚刚好。
  • 如果最大值是 100,那么就会以20为间隔。

那么,我们能不能把上面数据里上亿的数值按照一定的规则让其变成 很小的数据来在图里展示呢?

答案是可以的。

方法

这里可以算是对我在Echarts Gallery 上发布的一个不均匀数据轴图表代码的讲解了。

直达连接:投资计划——不均匀数据轴(y)

首先我们看一组数据:

// 数据源
const sourceData = [{
        date: '2020-01-01',
        amount: 1000000
    },
    {
        date: '2020-02-01',
        amount: 100000
    },
    {
        date: '2020-03-01',
        amount: 200000
    },
    {
        date: '2020-04-01',
        amount: 50000 // 很小的数值
    },
    {
        date: '2020-05-01',
        amount: 20000000
    },
    {
        date: '2020-06-01',
        amount: 300000000
    },
    {
        date: '2020-07-01',
        amount: 400000
    },
    {
        date: '2020-08-01',
        amount: 3000000000 // 很大的数值
    },
    {
        date: '2020-09-01',
        amount: 550000
    },
];

这一组数据里,最大值是 30亿 最小值是 5万。我们怎么处理数据呢?

  1. 第一步:设置数据间隔。

    // 间隔(0——30亿)
    // 0    10万    100万     1千万    1亿     10亿       20亿      30亿
    const dataInterval = [0, 100000, 1000000, 10000000, 100000000, 1000000000, 2000000000, 3000000000];
    

    可以理解为我们以自己的想法对 0 到 30亿 的数据 划分了显示的间隔。

  2. 第二步:按照间隔处理数据。

    const investAmount = sourceData.map(item => {
        const amount = item.amount;
    
        // 寻找在数据间隔里小于amount的最大值
        const min_v = Math.max(...dataInterval.filter(v => v <= amount));
        // 寻找在数据间隔里大于amount的最小值
        const max_v = Math.min(...dataInterval.filter(v => v > amount));
    
        // 寻找 min_v 所在的下标
        const index = dataInterval.findIndex(v => v === min_v);
    
        // 计算该amount在y轴上应该展示的位置
        const y_value = (((amount - min_v) / (max_v - min_v)) * 10) + index * 10;
    
        return {
            value: y_value,
            realValue: amount,
            date: item.date
        };
    }).filter(x => x);
    

    代码解释:

    • 首先遍历数据源,取出 amount (数据)。

    • 然后去定义的数据间隔里找 amount 处在间隔的哪两个数据之间。

      min_v:在定义的间隔里找到 所有小于 amount 数值 中的 最大值。

      max_v:在定义的间隔里找到 所有大于 amount 数值中的 最小值。

      如果上面说的不是很明白,我换一种说法:

      把 amount 放到定义的 数据间隔 里进行排序,然后 min_v 和 max_v 就数据间隔里是 amount 左右两侧的值。

      当然代码里是没有真的排序找,而是用了其他的方法而已。

    • 接着需要寻找 min_v 所在的值的下标 i ,然后让其 乘以10 得到一个 index。

    • 最后利用 amount 和 min_v 的差 除以 max_v 和 min_v 的差 乘以 10 加上index 即可。

    • 这是我们就得到了一个按照一定规则缩小的数值。

    • 图例:
      在这里插入图片描述

    • 上图中得到的结果是:31.111... ,看了这个图应该就明白了,按照上面我讲的,如果把每一个数据都按照这个公式带入算一遍,那么我们就可以把上亿的数转换成几十,而此时得到的Echarts图,将会是一个介于 0 — 70 之间的图,这样就可以把很小的数值也显示出来。

  3. 第三步:渲染数据

    这一步最主要的地方是当用户鼠标放到图上时我们肯定不能显示我们处理过后的数,所以要 formatter 一下:

    tooltip: {
        show: true,
        trigger: 'axis',
        axisPointer: {
            type: 'shadow'
        },
        formatter: (v) => {
            const date = v[0].data.date;
            // 前面处理数据时,构造的数组里包含了未处理过的原始值,所以这里直接用即可
            const value = v[0].data.realValue;
            return `<div>
                <span>日期:${date}</span><br>
                <span>金额:${value / 10000}(万)</span>
            </div>`
        }
    }
    

现在你可能就明白了,为什么我前面说 本质上并没有打破均匀显示规则 表面上看确实改变了,但实际y轴依然是均匀分布的数值,不过我们改变了表象,转换了数据而已。

OK, 关于怎么构造一个不均匀数据轴图表我已经介绍完了。大家可以直接去看发布的图表。前面已经提供了链接。

完结·撒花

### ECharts 中坐标刻度绘制方法自定义配置 在 ECharts 中,可以通过多种方式来实现坐标刻度的自定义绘制。对于数值型坐标 (`xAxis.type: 'value'`) 的情况,虽然默认情况下会均匀分布刻度,但是通过一些特定配置项可以达到等间距的效果。 #### 使用 `markLine` 实现等间距坐标效果 为了模拟等间距的坐标刻度,可以在保持 `xAxis.type` 为 `'value'` 的基础上利用 `markLine` 或者 `markPoint` 来标注特殊位置上的数据点[^1]: ```javascript option = { xAxis: { type: 'value', splitLine: { show: false }, // 显示分割线 axisLabel: { formatter: '{value}' } // 可选:格式化标签文本 }, yAxis: { type: 'value' }, series: [{ name: 'Series Name', type: 'line', data: [/* 数据序列 */], markLine: { symbol: ['none', 'none'], // 设置标记线条两端无箭头 lineStyle: { color: '#000', width: 1, type: 'solid' }, label: {show: true, position: 'middle'}, data: [ {name: '', xAxis: 特殊X值}, /* 更多特殊点 */ ] } }] }; ``` 此代码片段展示了如何使用 `markLine` 添加额外的垂直辅助线到图表上,这些线的位置可以根据实际需求设定同的 X 值,从而形成视觉上的非等距分隔效果。 #### Y 坐标的自定义处理 当涉及到Y时,除了上述提到的方法外,还可以考虑采用 GeoGebra 类似的方式来自定义简易坐标系[^2]。这种方式主要适用于需要精确控制图形展示场景的应用场合。具体做法是在初始化阶段就指定好整个绘图区域内的范围以及步长,并且能够灵活调整颜色样式等属性以满足个性化的需求。 例如,在构建工具之前先将所有涉及的颜色设为黑色,则后续生成的内容也会继承这一特性;另外也可以给定具体的区间界限作为参数传递进去以便更好地适应同类型的可视化任务。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值