首页 文章

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

提问于
浏览
2

处理自定义图表,该图表可以根据数据提供的值确定条形图或水平条形图中条形图的厚度,而不是使用barThicknessbarPercentage / categoryPercentage预设的宽度 .

目标:我可以使用包含 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,
})

...会呈现如下图所示的图表:

desired result

......而不是这个:

current view

(这里没有包含不相关的风格选项) .

主要特色:

  • 刻度标签位于条形图的中心

  • 蜱间隔由条形厚度决定

  • 条均匀分布

如何才能做到这一点?

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

bad widths

我的预感是我需要扩展new axis但这似乎很复杂 .

希望得到关于最佳方法的任何建议!谢谢!

this unanswered question相似 . 在我的搜索中遇到这些答案似乎很有希望但最终不是正确的答案:

1 回答

  • 0

    要支持此功能,需要执行以下三项操作:

    • 使用类别比例计算与轴尺寸成比例的条形厚度(垂直宽度,水平高度)

    • 覆盖类别比例中的 #getPixelForValue() 方法,以便类别宽度反映变体厚度,而不是均匀

    • 使用比例计算的值更改控制器绘制的矩形的尺寸

    在这个包中实现了这些作为自定义图表: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)稍微复杂一点,因为在计算距离边缘的距离时,类别比例中每个值的像素需要考虑数据集中每个先前项目的所有不同厚度( left 表示水平,或 top 表示垂直) . 否则,轴中类别的厚度将与条的厚度不匹配,并且类别轴标签将不会在条上居中 .

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

    (3)通过使用上面的 Scale#getBarThickness() 方法更改元素的 _view_model 属性中的相关维度来解决 .

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


    通过阅读Chart.js的源代码来解决大部分问题,尤其是scale.category.jscore.datasetController.js . 还从Chart.smith.js的源代码中获得了一些灵感 .

相关问题