19

I'm using Chart.js to draw a chart.. My dataset have some null values, Actually chart.js plot a line between points that are previous and successor of the null values in this way :

enter image description here

The red arrow indicate where are the null values

I want to find how can I not plot these null values enter image description here

The configuration I use is as simple as that :

var lineChartData = {
            "datasets": [{
                "label": "defi score",
                "data": data,
                "pointStrokeColor": "#fff",
                "fillColor": "rgba(220,220,220,0.5)",
                "pointColor": "rgba(220,220,220,1)",
                "strokeColor": "rgba(220,220,220,1)",
            }],
            "labels": labels
        };


        var ctx = document.getElementById("chart_per_week").getContext("2d");
        var myLine = new Chart(ctx).Line(lineChartData, {
            responsive: true,
            scaleFontColor: "#FF5972",
            bezierCurve: false
        });

Thank you for your help

4 Answers 4

38

In case you still reach this page, New version supports skipping missing data. . If you want the lines to be connected by skipping missing data, you can set spanGaps: true in the options.

Then if you have null or NaN for missing data, it will skip it and connect to the next point.

.....
 showTooltips: true,
        options: {
             spanGaps: true,
  ......

Documentation here

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks Selay, that was exactly what I was looking for.
nullvalue doesn't seem to work. doc states to set empty points to NaN
@CédricFrançoys can you please share the link
best answer. most simple and the document clearly says to use spanGaps if you have null values
|
14

I know this is pretty old, but I think there is a better solution now. Replace all your null values with Number.NaN

http://www.chartjs.org/docs/#line-chart-chart-options

Below is a data point I replaced with NaN on the red line

Broken Line

1 Comment

Best answer so far.
8

Breaking (Broken) Lines using Chart.js

You can extend the line chart type to do this


Preview

enter image description here

Script

Chart.types.Line.extend({
  name: "LineAlt",
  initialize: function (data) {
    var fillColors = [];
    var strokeColors = [];
    data.datasets.forEach(function (dataset, i) {
      if (dataset.data.indexOf(null) !== -1) {
        fillColors.push(dataset.fillColor);
        strokeColors.push(dataset.strokeColor);
        dataset.fillColor = "rgba(0,0,0,0)"
        dataset.strokeColor = "rgba(0,0,0,0)"
      }
    })

    Chart.types.Line.prototype.initialize.apply(this, arguments);

    var self = this;
    data.datasets.forEach(function (dataset, i) {
      if (dataset.data.indexOf(null) !== -1) {
        self.datasets[i]._saved = {
          fillColor: fillColors.shift(),
          strokeColor: strokeColors.shift()
        }
      }
    })
  },
  draw: function () {
    Chart.types.Line.prototype.draw.apply(this, arguments);

    // from Chart.js library code
    var hasValue = function (point) {
      return point.value !== null;
    },
    nextPoint = function (point, collection, index) {
      return Chart.helpers.findNextWhere(collection, hasValue, index) || point;
    },
    previousPoint = function (point, collection, index) {
      return Chart.helpers.findPreviousWhere(collection, hasValue, index) || point;
    };

    var ctx = this.chart.ctx;
    var self = this;
    ctx.save();
    this.datasets.forEach(function (dataset) {
      if (dataset._saved) {
        ctx.lineWidth = self.options.datasetStrokeWidth;
        ctx.strokeStyle = dataset._saved.strokeColor;
        ctx.fillStyle = dataset._saved.fillColor;

        // adapted from Chart.js library code
        var pointsWithValues = Chart.helpers.where(dataset.points, hasValue);
        dataset.points.forEach(function (point, index) {
          if (index === 0 || (hasValue(point) && !hasValue(dataset.points[index - 1])))
            point.start = true;
        });
        var currentStartPoint = undefined;
        Chart.helpers.each(pointsWithValues, function (point, index) {
          if (point.start) {
            if (currentStartPoint) {
              ctx.lineTo(pointsWithValues[index - 1].x, self.scale.endPoint);
              ctx.lineTo(currentStartPoint.x, self.scale.endPoint);
              ctx.closePath();
              ctx.fill();
            }

            currentStartPoint = point;
            ctx.beginPath();
            ctx.moveTo(point.x, point.y);
          }
          else {
            if (self.options.bezierCurve) {
              var previous = previousPoint(point, pointsWithValues, index);
              ctx.bezierCurveTo(
                previous.controlPoints.outer.x,
                previous.controlPoints.outer.y,
                point.controlPoints.inner.x,
                point.controlPoints.inner.y,
                point.x,
                point.y
              );
            }
            else {
              ctx.lineTo(point.x, point.y);
            }
          }

          ctx.stroke();
        }, this);

        ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, self.scale.endPoint);
        ctx.lineTo(currentStartPoint.x, self.scale.endPoint);
        ctx.closePath();
        ctx.fill();
      }
    })

    ctx.restore();
  }
});

and then

var data = {
    ...
    datasets: [
        {
            ...
            data: [65, 59, null, 81, 52, 62, null, 56, 40],
        }
    ],
};

...
new Chart(ctx).LineAlt(data);

Fiddle - https://jsfiddle.net/hbrhz2q4/

2 Comments

Thank you very much, that's works very fine for me, I took it as the correct answer ....
This was the correct answer when it was written, but there is a better way now as in Selay's answer below
1

I'm not sure if ChartJS itself can natively do this.

However one way I did something similar was to make the line graph out of multiple datasets. One dataset would end when a null value is reached, and the next dataset would start. This would of course requires parsing all this data before passing it into var linechartdata

You can make all the datasets have the same colors and highlights and the graph should render with spaces where null data would have been found.

2 Comments

Hi, Do you suggest another librairie to draw charts ? thank you
Actually, to parse data, I asked a question for that : stackoverflow.com/questions/34516775/… so I got my datasets with the null values ;) ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.