Chart: 计算X轴标签个数

来源:互联网 发布:linux修改系统时间命令 编辑:程序博客网 时间:2024/05/30 04:40

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

纵轴的数值标签表示,是需要算法支持的,参见【图表轴刻度的思路,算法: 转载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的上面的代码抛砖引玉,提供了思路。

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

0 0