【问题标题】:Highcharts - how can I center labels on a datetime x-axis?Highcharts - 如何在日期时间 x 轴上居中标签?
【发布时间】:2013-08-29 16:29:36
【问题描述】:

我很难弄清楚如何在不使用类别和 tickPlacement 的情况下在 Highcharts 中的日期时间 x 轴上居中标签(因为 tickPlacement 仅适用于类别)。

我的轴是动态创建的,所以我不能简单地设置 x 偏移或填充,因为这会导致不同间隔的轴看起来很奇怪。

在弄乱了配置选项之后,我想我可能已经找到了使用 x 轴格式化程序和一些在 Highcharts 回调中的 css / jquery noodling 的解决方案。请参阅下面的答案。

【问题讨论】:

    标签: javascript jquery highcharts


    【解决方案1】:

    诀窍是像这样使用 x 轴标签对象:

    xAxis: {
      type: 'datetime',
      labels: {
        useHTML: true,
        align: 'center',
        formatter: function () {
          //using a specific class for the labels helps to ensure no other labels are moved 
          return '<span class="timeline_label">' + Highcharts.dateFormat(this.dateTimeLabelFormat, this.value) + '</span>';
        }
    }
    

    您可以看到格式化程序将保留用户设置或默认设置的任何 dateTimeLabelFormat。

    然后有一个回调,做这样的事情:

    function (chart) {
      var $container = $(chart.container);
      var $labels = $container.find('.highcharts-axis-labels .timeline_label');
      var $thisLabel, $nextLabel, thisXPos, nextXPos, delta, newXPos;
    
      $labels.each(function () {
        $thisLabel = $(this).parent('span');
        thisXPos = parseInt($thisLabel.css('left'));
    
        $nextLabel = $thisLabel.next();
        nextXPos = $nextLabel.length ? parseInt($nextLabel.css('left')) : chart.axes[0].left + chart.axes[0].width;
        delta = (nextXPos - thisXPos) / 2.0;
        newXPos = thisXPos + delta;
    
        if ($nextLabel.length || $(this).width() + newXPos < nextXPos) {
          $thisLabel.css('left', newXPos + 'px');
        } else {
          $thisLabel.remove();
        }
      });
    });
    

    简而言之,这将遍历每个标签并通过计算其自身与下一个标签之间的距离来确定它应该被移动多少(使用 css)。当它到达最后一个标签时,它要么使用轴的末端移动它以进行计算,要么如果它不适合则将其移除。这最后一部分只是我决定做的决定,你可能会选择做一些其他的事情,比如自动换行等等。

    你可以看到jsfiddle here

    希望这对某些人有所帮助。另外,如果有任何改进,很高兴在这里看到它们。

    【讨论】:

    • 两年过去了,这真的非常有帮助 - 谢谢。我发现这个解决方案的主要问题是它在重绘时没有正确更新(即在调整视口大小时)。我玩过并利用events 选项在加载和重绘时回调函数。我还对其进行了自定义,以在其中为标签容器提供宽度和居中对齐,而不是在标签选项中使用所有绝对定位和居中对齐。我使用不规则的时间间隔,但按月而不是按天对它们进行分类。小提琴:jsfiddle.net/mzh5gcmu
    【解决方案2】:

    基于现有答案,有一个更简单的解决方案,即使在滴答计数发生变化时,也可以在调整浏览器窗口大小(或以其他方式强制重绘图表)时使用:http://jsfiddle.net/McNetic/eyyom2qg/3/

    它通过将相同的事件处理程序附加到 loadredraw 事件来工作:

    $('#container').highcharts({
      chart: {
        events: {
          load: fixLabels,
          redraw: fixLabels
        }
      },
    [...]
    

    处理程序本身如下所示:

      var fixLabels = function() {
      var labels = $('div.highcharts-xaxis-labels span', this.container).sort(function(a, b) {
        return +parseInt($(a).css('left')) - +parseInt($(b).css('left'));
      });
      labels.css('margin-left', 
        (parseInt($(labels.get(1)).css('left')) - parseInt($(labels.get(0)).css('left'))) / 2
      );
      $(labels.get(this.xAxis[0].tickPositions.length - 1)).remove();
    };
    

    如您所见,标签的额外包装是不必要的(至少如果您没有多个 xAxis)。基本上,它是这样工作的:

    1. 获取所有现有标签(重绘时,包括新添加的标签)。 2. 按css属性'left'排序(重绘后不会这样排序)
    2. 计算前两个标签之间的偏移量(所有标签的偏移量相同)
    3. 将偏移量的一半设置为所有标签的左侧边距,有效地将它们的偏移量的一半向右移动。
    4. 删除最右边的标签(移到图表之外,有时部分可见)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-29
      • 2017-04-09
      • 1970-01-01
      相关资源
      最近更新 更多