Echarts坐标轴显示优化

3,367 阅读2分钟

Ecahrts版本:5.2.0

问题

Echarts默认的行为,当x坐标轴标签内容过长的时候,会出现部分标签隐藏不显示的问题

源码

<html>
<title>ECharts 示例</title>
<body>
    <div id="main" style="width: 600px;height:400px;margin:100px"></div>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.2.0/dist/echarts.js"></script>
    <script>
        var myChart = echarts.init(document.getElementById('main'));
        myChart.setOption({
            tooltip: {},
            xAxis: {
                data: [
                    '这是一段特别特别长的话_这是一段特别特别长的话',
                    '羊毛衫',
                    '雪纺衫',
                    '裤子',
                    '高跟鞋',
                    '袜子'
                ],
            },
            yAxis: {},
            series: [{
                name: '销量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
            }]
        });
    </script>
</body>
</html>

正常情况

image.png

异常情况

image.png

可以看到,当第一个柱子的x轴标签过长时,第2、3、4、5根柱子的x标签被隐藏了,希望将x坐标轴的所有标签都显示出来,以便让用户不错过重要信息

优化方案

限制标签宽度

源码

初步方案是限制标签的宽度,超出时用省略号显示,该方案需要配置axisLabel

<html>
<title>ECharts 示例</title>

<body>
    <div id="main" style="width: 600px;height:400px;margin:100px"></div>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.2.0/dist/echarts.js"></script>
    <script>
        var myChart = echarts.init(document.getElementById('main'));
        myChart.setOption({
            tooltip: {},
            xAxis: {
+                axisLabel: {
+                    interval: 0,
+                    width: 50,
+                    overflow: 'truncate'
+                },
                data: [
                    '这是一段特别特别长的话_这是一段特别特别长的话',
                    '羊毛衫',
                    '雪纺衫',
                    '裤子',
                    '高跟鞋',
                    '袜子'
                ],
            },
            yAxis: {},
            series: [{
                name: '销量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
            }]
        });
    </script>
</body>

</html>

interval确保每个标签都显示出来width设置了标签的宽度,overflow表示标签内容超出宽度后如何处理

效果

image.png

这里还存在一个问题,上面的width是固定死的,但柱子之间的间距会随着个数的增加而变小,此时按照上述方式设置会出现内容重叠的情况:

image.png

此时我们希望可以调整柱子之间的最小间距,以便可以设置固定的标签宽度。但Echarts的布局逻辑是,如果不设置dataZoom的话,Echarts会保证把每个柱子都显示出来,所以柱子越多,柱子之间的间距越小,此时固定死标签宽度就不能避免标签的重叠了。

增加区域缩放(dataZoom)

源码

<html>
<title>ECharts 示例</title>
<style>
    #main {
        width: 50%;
        height: 400px;
        margin: 100px;
    }
</style>
<body>
    <div id="main"></div>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.2.0/dist/echarts.js"></script>
    <script>
+        var myChart = echarts.init(document.getElementById('main'));
        const viewBarCount = 5;
        const data = [
            '这是一段特别特别长的话_这是一段特别特别长的话', '羊毛衫',
            '雪纺衫', '裤子', '高跟鞋', '袜子', '汗衫', 'T恤', '运动鞋',
            '皮鞋', '雪地靴', '手套', '领带', '皮夹克', '墨镜', '围巾',
            '羊绒衫', '草帽', '耳环', '项链'
        ];
        myChart.setOption({
            xAxis: {
                axisLabel: {
                    interval: 0,
                    width: 50,
                    overflow: 'truncate'
                },
                data,
            },
            yAxis: {},
            series: [{
                name: '销量',
                type: 'bar',
+               barMaxWidth: 50,
                data: [
                    5, 20, 36, 10, 10, 20, 10, 20, 30, 40,
                    30, 13, 32, 15, 30, 32, 12, 14, 14, 14
                ]
            }],
+           dataZoom: [{
+               brushSelect: false,
+               zoomLock: true,
+               start: 0,
+               end: Math.floor((viewBarCount - 1) / data.length * 100),
+               filterMode: 'none'
+           }]
        });
    </script>
</body>

</html>

需要注意的是,这里我们设置了视图区域内固定显示的柱子个数是5,所以无论有多少条数据,我们都只能一次性看到5个,这就保证了柱子之间的间隔不会太少(自适应页面除外)。同时我们设置了barMaxWidth,亦会保证当柱子个数比较少的时候,不会柱子太粗而标签太短出现不协调

效果

image.png

总结

综上所述,我们通过以下三个措施来进行优化:

  1. 设置xAxis.axisLabel来确保每个标签都得到显示,以及固定每个标签宽度和文字溢出的处理方式。
  2. 设置dataZoom确保柱子的间距,防止标签重叠。
  3. 设置series.barMaxWidth规定每个柱子的最大宽度,保持和标签宽度的和谐

由于我们所处理的不是自适应模式,所以视图内的柱子个数是固定死的,如果考虑到自适应,那么计算dataZoom.end时可以把容器的宽度纳入算法里,在不同宽度的情况下分别在视图内显示不同数量的柱子。