echarts解决数据差异过大的问题

问题描述

使用echarts折线图和柱状图展示数据时,如果数据差异值较大,会导致显示图形差异过大,图表不美观。

如这一组数据2000000, 200, 0.1, 20, 0, -10, -3000,渲染出来的效果如下图:

可以看到由于最大值和最小值差异过大,导致过小的值柱子显示不出来,数据的波动趋势不明显。

当前需要解决的问题是如何体现数据差异性,让小数值柱子也能显示出来。
解决方案:

使用对数轴(yAxis. type="log"),适用于对数数据,可以解决数据差异过大的问题。但对数轴只适用于data>=0的情况。

如数据:barDatas = 2000000, 200, 0.1, 20, 3,3, 3000

如果对数轴中的数组数据出现0或者负数情况,就会造成错误渲染。

试了很多办法都无法解决这个问题,最后采取了多个grid多轴的办法。

可以通过grid来划分多个网格区域,然后让正数和负数柱状图分别在在不同的区域展现。

如:const barDatas = 2000000, 200, 0.1, 20, 0, -10, -3000

流程展示:

  • 将barDatas数组拆分为正数数组,负数数组

  • 设置三个grid,分别为用于展示正数,负数数据,以及底部X轴

  • 正负数数据网格区域y轴为yAxis. type="log",X轴网格区数数据区域yAxis. type="value"

  • 正数柱状图series.data只展示大于0的数据,其余为null(barDatas.map(item => item > 0 ? item : null);

    负数柱状图series.data只展示小于0的数据,并展示为绝对值,其余为null(barDatas.map(item => item < 0 ? Math.abs(item): null)

  • 设置负数的y轴yAxis.inverse=true,让Y轴绕X轴上下翻转,并配置y轴标签显示yAxis.axisLabel.formatter=(val) => val === 1 ? 0 : -${val}

其中要解决的问题是:

1)解决起始0对齐的问题

因为对数轴的数据不能为0,所以需要设置上下yAxis的min为1,再通过yAxis.axisLabel.formatter将y轴的1改为0。

2)小于1的数据柱子无高度。

需要设置barMinHeight最小高度,同时改造小于1的数为1.01

这种方式能很好的解决数据差异过大的问题。

效果图附上:

代码附上:

javascript 复制代码
<!DOCTYPE html>
<html lang="en" style="height: 100%">

<head>
    <meta charset="utf-8">
</head>
<script type="text/javascript" src="https://registry.npmmirror.com/echarts/5.5.0/files/dist/echarts.min.js"></script>

<body style="height: 100%; margin: 0">
    <div id="container" style="width: 50%;height: 50%;border: 1px solid red;margin: 30px;"></div>
    <script type="text/javascript">
        var dom = document.getElementById('container');
        var myChart = echarts.init(dom, null, {
            renderer: 'canvas',
            useDirtyRect: false
        });
        var app = {};
        var option;
        // const barDatas = [1000000, 20000000, 0.1, 20, 0, -10, -3000];
        // const barDatas = [200000, -100];
        const barDatas = [2000000, 200, 0.1, 20, 0, -10, -3000]
        option = {
            color: ['#3398DB'],
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                },
                formatter: (params) => {
                    const { dataIndex } = params[0]
                    return `${`城市${dataIndex + 1}`}:${barDatas[dataIndex]}`
                }
            },
            grid: [{
                right: 20,
                left: 80,
                top: 30,
                bottom: '50%',
                containLabel: false,
            }, {
                right: 20,
                left: 80,
                top: '50%',
                bottom: 30,
                containLabel: false,
                show: false
            }, {
                right: 20,
                left: 80,
                top: '50%',
                bottom: 30,
                containLabel: false,
                show: false
            }],
            xAxis: [
                {
                    type: 'category',
                    gridIndex: 0,
                    show: false,
                },
                {
                    type: 'category',
                    show: false,
                    gridIndex: 1,
                },
                {
                    type: 'category',
                    interval: 0,
                    gridIndex: 2,
                    data: barDatas.map((item, index) => `城市${index + 1}`)
                },
            ],
            yAxis: [
                {
                    type: 'log',
                    gridIndex: 0,
                    min: 1, // 设置y轴最小值
                    axisLabel: {
                        formatter: (val) => val === 1 ? 0 : val
                    }
                },
                {
                    type: 'log',
                    gridIndex: 1,
                    inverse: true, //设置反向坐标,让Y轴绕X轴上下翻转
                    min: 1, // 设置y轴最小值
                    axisLabel: {
                        formatter: (val) => val === 1 ? 0 : `-${val}`
                    }
                },
                {
                    type: 'value',
                    gridIndex: 2,
                    show: false,
                },
            ],
            series: [
                {
                    name: '正数',
                    xAxisIndex: 0,
                    yAxisIndex: 0,
                    type: 'bar',
                    data: barDatas.map(item => item > 0 ? item > 1 ? item : 1.01 : null), // 正数柱状图series.data只展示大于0的数据
                    barMinHeight: 1.5,// 最小高度
                },
                {
                    name: '负数',
                    type: 'bar',
                    xAxisIndex: 1,
                    yAxisIndex: 1,
                    data: barDatas.map(item => item < 0 ? Math.abs(item) > 1 ? Math.abs(item) : 1.01 : null), // 负数柱状图eries.data只展示小于0的数据
                    barMinHeight: 1.5, // 最小高度
                },
                {
                    name: 'x轴',
                    xAxisIndex: 2,
                    yAxisIndex: 2,
                    type: 'bar',
                    show: false,
                    data: barDatas.map(item => null),
                },
            ],
        };
        if (option && typeof option === 'object') {
            myChart.setOption(option);
        }
        window.addEventListener('resize', myChart.resize);
    </script>
</body>

</html>
相关推荐
默_笙12 小时前
🚦 请三个 AI 考官给 RAG 打分:量化评估实战(下)
前端·javascript
阿坨12 小时前
灵感闪存卡:一款 Tampermonkey用户脚本
javascript·tampermonkey
朝朝辞暮i14 小时前
C++ 第 25 课:getter / setter + this
java·javascript·c++
蜗牛互联网14 小时前
Python接入Gemini 3.8 Flash实现票据视觉抽取与规则校验
java·javascript·网络·人工智能·python
xieter15 小时前
【技术精选】深入浅出现代前端渲染与性能优化实践指南 (2026-10-04)
前端·javascript
xieter15 小时前
【硬核实战】TypeScript Compiler API: Preserving Child Node Narrowing in Reusable Type Guards 🔧 (2026-10-03)
前端·javascript
xieter16 小时前
【硬核实战】React 19 useFormStatus Returning False? I Built a SubmitButton That Fixes It (2026-10-03)
前端·javascript
paopaokaka_luck17 小时前
非遗文物数字化小程序(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
javascript·spring boot·mysql·数据分析·echarts·mybatis
Highcharts.js17 小时前
图表开发实战总结| 7 条“黄金法则”与“性能铁律”
前端·javascript·vue.js·编辑器·时序数据库·highcharts
Helix25017 小时前
Electron、WebView 框架与 HTA 对比:桌面应用选型、安全性与现代替代方案
前端·javascript·electron·webview·vbscript·hta·本地html应用