是否能够在混合图表的左边缘对齐折线图?

时间:2017-03-17 13:10:09

标签: chart.js

我想在混合图表的左边缘对齐折线图,如下所示。

enter image description here

但是当我在数据中添加折线图时,它会根据现有的条形图自动与中心对齐,如下所示。

https://jsfiddle.net/daehyung/cvekgadf/4/

var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
            type: 'bar',
        label: 'A',
        data: [12, 19, 3, 5, 2, 3],
        borderWidth: 1
    },
    {
            type: 'line',           
        label: 'B',
        data: [10, 8, 2, 3, 1, 2],
        borderWidth: 1,
        steppedLine: true
            }]
},
options: {
    scales: {
        yAxes: [{
            ticks: {
                beginAtZero:true
            }
        }]
    }
}
});

2 个答案:

答案 0 :(得分:3)

根据@jordanwillis的回答,我想出了一个更好的方法,它与chart.js 2.7.*兼容,并且应该更安全地用于未来的版本,因为它重用了更多的现有代码:

Chart.controllers.LineNoOffset = Chart.controllers.line.extend({
    updateElement: function(point, index, reset) {
        Chart.controllers.line.prototype.updateElement.call(this, point, index, reset);
        const meta = this.getMeta();
        const xScale = this.getScaleForId(meta.xAxisID);
        point._model.x = xScale.getPixelForValue(undefined, index-0.5);
    },
});

答案 1 :(得分:1)

无法通过chart.js中的配置完全执行此操作。浏览完源代码后,我看到线条图表在组合条形图上显示时会在内部设置offset = true属性。

因此,实现此行为的唯一方法是扩展折线图并实现您自己的函数来控制此offset变量的设置。事实证明,这并不难。以下是一个示例(请注意,offset变量仅在折线图的updateElement()函数中设置。)

var helpers = Chart.helpers;

Chart.controllers.LineNoOffset = Chart.controllers.line.extend({
  updateElement: function(point, index, reset) {
    var me = this;
    var meta = me.getMeta();
    var custom = point.custom || {};
    var dataset = me.getDataset();
    var datasetIndex = me.index;
    var value = dataset.data[index];
    var yScale = me.getScaleForId(meta.yAxisID);
    var xScale = me.getScaleForId(meta.xAxisID);
    var pointOptions = me.chart.options.elements.point;
    var x, y;
    var labels = me.chart.data.labels || [];
    var includeOffset = false;

    // Compatibility: If the properties are defined with only the old name, use those values
    if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
      dataset.pointRadius = dataset.radius;
    }
    if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
      dataset.pointHitRadius = dataset.hitRadius;
    }

    x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset);
    y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);

    // Utility
    point._xScale = xScale;
    point._yScale = yScale;
    point._datasetIndex = datasetIndex;
    point._index = index;

    // Desired view properties
    point._model = {
      x: x,
      y: y,
      skip: custom.skip || isNaN(x) || isNaN(y),
      // Appearance
      radius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),
      pointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),
      backgroundColor: me.getPointBackgroundColor(point, index),
      borderColor: me.getPointBorderColor(point, index),
      borderWidth: me.getPointBorderWidth(point, index),
      tension: meta.dataset._model ? meta.dataset._model.tension : 0,
      steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,
      // Tooltip
      hitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)
    };
  },
});

定义新的图表类型后,您必须更改配置以使用此新类型。

这是显示最终结果的codepen example(并演示如何执行此操作)。