在Chart.js条形图中指定每个条的不同厚度

时间:2018-10-19 22:35:35

标签: javascript charts chart.js chart.js2

处理一个自定义图表,该图表可以根据数据提供的值来确定条形图或水平条形图中的条形厚度,而不是barThickness或{{3 }}。

目标:我可以创建一个水平条形图,其数据包含一个x值和一个thickness,其中厚度变为该条相对于其他条的相对厚度。

例如,此代码:

const data = {
  labels: ['Northeast', 'Midwest', 'South', 'West'],
  datasets: [
    {
      data: [
        { x: 10, thickness: 18 },
        { x: 20, thickness: 8 },
        { x: 13, thickness: 5 },
        { x: 4, thickness: 12 }
      ],
    },
  ],
}

const context = document.querySelector('#myChart').getContext('2d')

const barChart = new Chart(context, {
    type: 'horizontalBar',
    data: data,
})

...将使图表看起来像这样:

barPercentage / categoryPercentage

...代替这个:

desired result

(此处不包括不相关的样式选项)。

主要功能:

  • 刻度线标签位于栏的中央
  • 刻度线间隔由条形厚度确定
  • 条形图均匀分布

这怎么办?

我知道我可以修改条形图控制器的图形以为绘制的矩形指定显式宽度,但这无法产生均匀间隔的条形。相反,它们在其固定宽度类别中具有可变宽度,这不是我想要的外观:

current view

我的直觉是我需要扩展bad widths,但这似乎很复杂。

希望获得有关最佳方法的任何建议!谢谢!

类似于new axis。在我的搜索中遇到了这些有希望的答案,但最终并不是正确的答案:

1 个答案:

答案 0 :(得分:1)

要支持此功能,需要做三件事:

  1. 使用类别比例来计算与轴尺寸(垂直宽度,水平高度)成比例的钢筋厚度
  2. 覆盖类别比例尺中的#getPixelForValue()方法,以使类别宽度反映变量的厚度,而不是均匀的
  3. 使用比例尺计算出的值更改控制器绘制的矩形的尺寸

在此程序包中将它们作为自定义图表实现:https://github.com/swayable/chartjs-chart-superbar使用Chart.js的new chartnew axes自定义功能。

通过将以下行为添加到类别比例来解决(1):

getBarThickness(thicknessPercentage) {
  let thickness = thicknessPercentage * this._axisSize(),
    spacing = this.options.spacing * 2

  return thickness - spacing
}

_axisSize() {
  return this.isHorizontal() ? this.width : this.height
}

(2)有点复杂,因为类别标度中每个值的像素在计算与以下项之间的距离时需要考虑数据集中每个先前项目的各种厚度的 all 边缘(left代表水平,top代表垂直)。否则,轴上类别的厚度将与条的厚度不匹配,类别轴标签将不会在条上居中。

(1)和(2)的相关文件:https://github.com/swayable/chartjs-chart-superbar/blob/master/src/scale.thickCategory.js

(3)通过使用上面的_view方法更改元素的_modelScale#getBarThickness()属性中的相关尺寸来解决。

(3)的相关文件:https://github.com/swayable/chartjs-chart-superbar/blob/master/src/mixin.barThickness.js


通过阅读Chart.js的源代码(尤其是scale.category.jscore.datasetController.js)可以了解其中的大部分内容。还从Chart.smith.js的源代码中获得了一些启发。