ChartJS:将图表上的零与多轴对齐

Mer*_*din 4 chart.js

如果数据集中有正值和负值,如何将图表上的零与多轴对齐?

我希望零在同一行上。

我不喜欢这个: 图形图像

链接到 jsfiddle

new Chart(canvas, {
  type: 'line',
  data: {
    labels: ['1', '2', '3', '4', '5'],
    datasets: [{
      label: 'A',
      yAxisID: 'A',
      data: [-10, 96, 84, 76, 69]
    }, {
      label: 'B',
      yAxisID: 'B',
      data: [-2, 3, 5, 2, 3]
    }]
  },
  options: {
    scales: {
      yAxes: [{
        id: 'A',
        type: 'linear',
        position: 'left',
      }, {
        id: 'B',
        type: 'linear',
        position: 'right',

      }]
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

实际上,官方网页上的示例也有同样的问题。看起来好乱

Ric*_*don 5

如果您事先知道范围并且可以提前为每个刻度对象指定最小值和最大值,那么上面的答案很好。如果像我一样,你试图用生成的数据产生效果,你将需要一些为你计算这些值的东西。以下不依赖于硬编码值来执行此操作。它确实会生成丑陋的最大值/最小值 - 但还有另一个解决方法:在 Chart.js 中隐藏 y 轴的最小值和最大值。它也可能产生小于理想的间距,在这种情况下,可以使用应用于最小值和最大值的简单模糊因子。

function scaleDataAxesToUnifyZeroes (datasets, options) {
  let axes = options.scales.yAxes
  // Determine overall max/min values for each dataset
  datasets.forEach(function (line) {
    let axis = line.yAxisID ? axes.filter(ax => ax.id === line.yAxisID)[0] : axes[0]
    axis.min_value = Math.min(...line.data, axis.min_value || 0)
    axis.max_value = Math.max(...line.data, axis.max_value || 0)
  })
  // Which gives the overall range of each axis
  axes.forEach(axis => {
    axis.range = axis.max_value - axis.min_value
    // Express the min / max values as a fraction of the overall range
    axis.min_ratio = axis.min_value / axis.range
    axis.max_ratio = axis.max_value / axis.range
  })
  // Find the largest of these ratios
  let largest = axes.reduce((a, b) => ({
    min_ratio: Math.min(a.min_ratio, b.min_ratio),
    max_ratio: Math.max(a.max_ratio, b.max_ratio)
  }))
  // Then scale each axis accordingly
  axes.forEach(axis => {
    axis.ticks = axis.ticks || { }
    axis.ticks.min = largest.min_ratio * axis.range
    axis.ticks.max = largest.max_ratio * axis.range
  })
}
Run Code Online (Sandbox Code Playgroud)


Jef*_*ff 2

您可以通过ticks在轴上设置选项来控制最大、最小和步长来实现此目的。为了使零点对齐,您需要使轴对称。 stepSize如果您也希望网格线对齐,则该选项是可选的。

在你的例子中:

yAxes: [{
    id: 'A',
    type: 'linear',
    position: 'left',
    ticks : {
        max: 100,
        min: -50,
        stepSize: 50
    }
  }, {
    id: 'B',
    type: 'linear',
    position: 'right',
    ticks : {
        max: 6,
        min: -3,
        stepSize: 3 
    }
  }]
Run Code Online (Sandbox Code Playgroud)

请参阅更新的小提琴: https://jsfiddle.net/x885kpe1/1/