Chart: 计算X轴标签个数

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

纵轴的数值标签表示,是需要算法支持的,参见【图表轴刻度的思路,算法: 转载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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您要使用 C# 中的 Chart 控件来绘制图形,并让横轴标签沿着曲线循环移动,可以通过修改 Chart 控件的 AxisLabel 属性来实现。具体来说,您可以在每次循环中计算出横坐标的值,并将对应的标签赋值给 AxisLabel 属性。示例代码如下: ``` double amplitude = 50; // 曲线振幅 double period = 100; // 曲线周期 double time = 0; // 当前时间 chart1.Series.Clear(); chart1.Series.Add("Series1"); chart1.Series["Series1"].ChartType = SeriesChartType.Line; while (true) { // 计算横坐标值和标签 double x = amplitude * Math.Sin(2 * Math.PI * time / period); string label = "Label " + (int)(time / period * 10); // 在 (x, y) 处添加数据点,并设置对应标签 chart1.Series["Series1"].Points.AddXY(x, y); chart1.ChartAreas[0].AxisX.LabelStyle.Interval = 1; chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -45; chart1.ChartAreas[0].AxisX.LabelStyle.Font = new Font("Arial", 8); chart1.ChartAreas[0].AxisX.LabelStyle.ForeColor = Color.Black; chart1.ChartAreas[0].AxisX.CustomLabels.Add(x - 0.5, x + 0.5, label); // 更新时间 time += 0.1; // 可以根据需要调整时间步长 if (time >= period) { time -= period; // 时间循环 } } ``` 在上面的示例中,我们首先清空了 Chart 控件中的所有系列,并添加了一个名称为 "Series1" 的线性系列。然后,在每次循环中,我们计算出横坐标的值和对应的标签,并将它们添加到 Chart 控件中。具体来说,我们首先在 Series1 中添加一个数据点 (x, y),然后使用 AxisX.CustomLabels 属性添加一个自定义标签,将它与对应的横坐标值关联起来。这样,就可以实现横轴标签沿着曲线循环移动的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值