Dygraphs 中调整 x 轴 label 展示

2022-09-26 16:49:22 浏览数 (2)

在前不久发表的文章 Dygraphs 中 x 轴等间距实现 中,我们介绍了如何在 x 轴等间距地实现图表划线。

嗯,当间距太小的时候,在 x 轴上展示的 label 文案(我这里是时间)就会交替重叠,如下:

上图中,我选择的时间间隔是 20s ,每个灰色的竖线代表一秒

上图会产生密集恐惧症有没有~那么,我们怎么去处理这种密集的数据呢?

一开始,我还以为 Dygraphs 官网上有相关的 api 或者 options 属性去控制,帮我们优化,自己还特意在 stackoverflow 上发问 Dygraphs set x label width But too tide to see the x label text,然而并什么用...

那么,我们还可以怎么做呢?摆烂?积极需求答案?

曲线救国

既然没有文档支持,那么我们可以使用 CSS 对相关的 DOM 进行隐藏,来个曲线救国。具体思路如下:

  1. 查看 x 轴上 labelDOM 节点,记下其公共有的类名 A
  2. 通过 JavaScript 获取图标下的全部的类名 A 文档节点
  3. 假设我们每个 label 的宽度是 B px,图表的宽度是 C px,那么我们可以得到想要的数据:每间隔 Math.floor(C / B) - 1 个点来展示 label 的文案(也就是其他 labelDOM 元素设置为 display: none

具体实现

上面我们已经分析了思路,我们先获取到公共有的类名:

相关的代码如下,我们将在代码中详解注解说明:

代码语言:javascript复制
public beautifyXAxis(): void {
  let widthLabel = 100; // 预设的宽度,能够容纳展示 label 的文案 
  // this.chartWidth 是图表的宽度,应该动态计算,因为浏览器可以伸缩
  // this.resolution.getValue() 是获取到整个图表展示区间的时间,这里是我上面提到的 20s
  let _pixelsPerLabel = (this.chartWidth / this.resolution.getValue() / 2) * 1000; // 计算实际的 label,其 _pixelsPerLabel 值和 this.dygraphs.options.axes.x.pixelsPerLabel 相同
  if(_pixelsPerLabel >= 100) { // 大于预设值,不用做什么处理
      return
  }
  
  // Math.floor 向下取整,这里不用减 1,见下 for 循环讲解
  let tooTidePointNumber = Math.floor(widthLabel / _pixelsPerLabel);
  // 获取到全部的 x 轴的 label 的 `DOM` 相关类集合
  let classXAxis: any = document.getElementById('theChartContainer')?.getElementsByClassName('dygraph-axis-label-x') || []; 

  for(let i = 0; i < classXAxis.length; i  ) {
    // 间隔 tooTidePointNumber - 1 个点展示 x 轴 label 的文案
    if(i % tooTidePointNumber == 0) {
      classXAxis[i].style.display = 'block';
    }  else {
      classXAxis[i].style.display = 'none';
    }
  }
}

实现的效果如下:

我们经过计算,在间隔相应的距离,才展示 x 轴的 label 文案。这样看起来,图表的 x 轴就清晰多了,妥妥地一枚小清新

0 人点赞