Chart: 计算X轴标签个数

本文深入分析了百度echarts K线图中X轴标签显示间隔的计算逻辑,通过遍历蜡烛线、计算标签长度、设定间隔并自适应调整,实现高效且美观的图表展示效果。重点探讨了自适应计算过程中的关键步骤和经验参数,为开发者提供了一种简单而有效的优化策略。

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

在图表中,横轴通常表示分类,纵轴表示数值。

纵轴的数值标签表示,是需要算法支持的,参见【图表轴刻度的思路,算法: 转载X】,略过。

这里说说横轴(X轴)的标签。

 

用K线图做例子,在一个图中表示的蜡烛线非常多,每根线对应一个时间,这些时间就是X轴上要表示的标签。

如果每根线的时间都在X轴表示出来,由于数量太多,就会相互重叠,根本分不清彼此,上面的文字让看不出来。

因此就要减少其数量。如何减少数量?

 

百度的echarts(http://echarts.baidu.com/)中有K线图,分析其源码(\src\component\categoryAxis.js 中【_getInterval】函数),了解到起设计思路。

        /**
         * 计算标签显示挑选间隔
         */
        _getInterval : function () {
            var interval   = this.option.axisLabel.interval;
            if (interval == 'auto') {
                // 麻烦的自适应计算
                var fontSize = this.option.axisLabel.textStyle.fontSize;
                var data = this.option.data;
                var dataLength = this.option.data.length;

                if (this.isHorizontal()) {
                    // 横向
                    if (dataLength > 3) {
                        var gap = this.getGap();
                        var isEnough = false;
                        var labelSpace;
                        var labelSize;
                        var step = Math.floor(0.5 / gap);
                        step = step < 1 ? 1 : step;
                        interval = Math.floor(15 / gap);
                        while (!isEnough && interval < dataLength) {
                            interval += step;
                            isEnough = true;
                            labelSpace = Math.floor(gap * interval); // 标签左右至少间隔为3px
                            for (var i = Math.floor((dataLength - 1)/ interval) * interval; 
                                 i >= 0; i -= interval
                             ) {
                                if (this.option.axisLabel.rotate !== 0) {
                                    // 有旋转
                                    labelSize = fontSize;
                                }
                                else if (data[i].textStyle) {
                                    labelSize = zrArea.getTextWidth(
                                        this._getReformedLabel(i),
                                        this.getFont(
                                            zrUtil.merge(
                                                data[i].textStyle,
                                                this.option.axisLabel.textStyle
                                           )
                                        )
                                    );
                                }
                                else {
                                    /*
                                    labelSize = zrArea.getTextWidth(
                                        this._getReformedLabel(i),
                                        font
                                    );
                                    */
                                    // 不定义data级特殊文本样式,用fontSize优化getTextWidth
                                    var label = this._getReformedLabel(i) + '';
                                    var wLen = (label.match(/\w/g) || '').length;
                                    var oLen = label.length - wLen;
                                    labelSize = wLen * fontSize * 2 / 3 + oLen * fontSize;
                                }

                                if (labelSpace < labelSize) {
                                    // 放不下,中断循环让interval++
                                    isEnough = false;
                                    break;
                                }
                            }
                        }
                    }
                    else {
                        // 少于3个则全部显示
                        interval = 1;
                    }

 

 

其设计思路主线是(如果分析错误,见谅!)

1. 遍历所有蜡烛线,找到其对应的标签文字最长的,计算其占用的空间长度(像素)

2. 设定标签之间的间隔(interval),计算其空间长度(像素)

3. 比较上面长度关系

4. 如果interval长度不足以容下最长文字,则增加interval,继续循环比较。直到找到合适的interval。

 

==================================

var step = Math.floor(0.5 / gap);

interval = Math.floor(15 / gap);

==================================

代码中的数字【0.5】【15】似乎是尝试出来的经验值,不具有普遍性。

代码逻辑看起来比较复杂,不容易懂。

 

echarts的上面的代码抛砖引玉,提供了思路。

应该有足够简单的设计能够替代。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值