ChartJS:使用多轴在图表上对齐零

时间:2017-07-28 12:00:56

标签: chart.js

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

我希望零在同一条线上。

我不喜欢这个: Graph image

link to 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',

      }]
    }
  }
});

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

2 个答案:

答案 0 :(得分:2)

如果您事先知道范围并且可以提前为每个刻度对象指定最小值和最大值,则上面的答案很好。如果像我一样,你试图用生成的数据产生效果,那么你需要为你计算这些值的东西。以下是不使用硬编码值的情况。它确实产生了丑陋的最大/最小值 - 但还有另一个解决方法:Hide min and max values from y Axis in Chart.js。它也可能产生不太理想的间距,在这种情况下,可以使用应用于最小值和最大值的简单软糖因子。

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
  })
}

答案 1 :(得分:1)

您可以通过在轴上设置ticks选项来控制max,min和stepSize。要使零对齐,您需要使轴对称。如果您希望网格线也对齐,则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 
    }
  }]

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