问题描述:

I have a Chart.js bar chart that gets instantiated on page load. I then wish to add data to the chart as it becomes available (no data is available at the time of its creation). However, passing in new data always seems to have the chart fail to render the first set of data passed in:

var bar_chart_data = {

labels: [],

datasets: [

{

label: "My First dataset",

fillColor: "rgba(220,220,220,0.5)",

strokeColor: "rgba(220,220,220,0.8)",

highlightFill: "rgba(220,220,220,0.75)",

highlightStroke: "rgba(220,220,220,1)",

data: []

}

]

};

var ctx = $("#bar-chart").get(0).getContext("2d");

var bar_chart = new Chart(ctx).Bar(bar_chart_data);

bar_chart.addData([2], "test")

bar_chart.addData([2], "test2")

I have tried a variety of things, including:

  • passing in empty label and data arrays (above)
  • passing in empty label array, with no data field set
  • passing in valid label and data arrays with one element, subsequently remove it with bar_chart.removeData(), then try adding the valid data again
  • calling bar_chart.update() after adding new data

jsfiddle

网友答案:

The issue was inside the scale class when the chart was trying to calculateX with no data in the graph. It would result in infinity when no data was in there and this was messing up the graph. so you can override Chart.Scale.calculateX like this: ( http://jsfiddle.net/leighking2/3nrhtyz4/ ) Edit - @Matt Humphrey pointed out the fix did not work for Line graphs so here is an update based on his github comment (github.com/nnnick/Chart.js/issues/573#issuecomment-56102121)

   Chart.Scale = Chart.Scale.extend({
    calculateX: function (index) {
        //check to ensure data is in chart otherwise we will get inifinity
        if (!(this.valuesCount - (this.offsetGridLines ? 0 : 1))) {
            return 0;
        }
        var isRotated = (this.xLabelRotation > 0),
            // innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding,
            innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),
            valueWidth = this.valuesCount === 0 ? 0 : innerWidth / (this.valuesCount - ((this.offsetGridLines) ? 0 : 1)),
            valueOffset = (valueWidth * index) + this.xScalePaddingLeft;

        if (this.offsetGridLines) {
            valueOffset += (valueWidth / 2);
        }

        return Math.round(valueOffset);
    },
});

You can now just use chart js normally as before.

var bar_chart_data = {
    labels: [],
    datasets: [{
        label: "My First dataset",
        fillColor: "rgba(220,220,220,0.5)",
        strokeColor: "rgba(220,220,220,0.8)",
        highlightFill: "rgba(220,220,220,0.75)",
        highlightStroke: "rgba(220,220,220,1)",
        data: []
    }, {
        label: "My Second dataset",
        fillColor: "rgba(151,187,205,0.5)",
        strokeColor: "rgba(151,187,205,0.8)",
        highlightFill: "rgba(151,187,205,0.75)",
        highlightStroke: "rgba(151,187,205,1)",
        data: []
    }]
};

var bar_chart_options = {
    responsive: false
};

var ctx = $("#bar-chart").get(0).getContext("2d");
var bar_chart = new Chart(ctx).Bar(bar_chart_data, bar_chart_options);

bar_chart.addData([1, 1], "test")
bar_chart.addData([2, 2], "test2")
相关阅读:
Top