nimdok
nimdok

Reputation: 41

How do you make a progressive line chart with time as the X axis?

I'm having a bit of trouble making a smooth animation for a progressive line chart with time as the x axis. Does anyone know how to make the animation smooth like in the example with numbers as both axes?

I tried with the code below (in jsfiddle here).


<head>
  <script src="https://cdn.jsdelivr.net/npm/chart.js/dist/chart.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
</head>

<body>
  <canvas id="myChart"></canvas>
</body>

</html>

const totalDuration = 2000;
const delayBetweenPoints = totalDuration / data.length;
const previousY = (ctx) => ctx.index === 0 ? ctx.chart.scales.y.getPixelForValue(100) : ctx.chart.getDatasetMeta(ctx.datasetIndex).data[ctx.index - 1].getProps(['y'], true).y;

var data = [
  {
    x: '01.12.2019',
    y: 29
  },
  {
    x: '19.03.2020',
    y: 29
  },
  {
    x: '01.08.2021',
    y: 29
  },
  {
    x: '11.01.2022',
    y: 29
  }
];

var animation = {
  x: {
    type: 'number',
    easing: 'linear',
    duration: delayBetweenPoints,
    from: NaN,
    delay(ctx) {
      if (ctx.type !== 'data' || ctx.xStarted) {
        return 0;
      }
      ctx.xStarted = true;
      return ctx.index * delayBetweenPoints;
    }
  },
  y: {
    type: 'number',
    easing: 'linear',
    duration: delayBetweenPoints,
    from: previousY,
    delay(ctx) {
      if (ctx.type !== 'data' || ctx.yStarted) {
        return 0;
      }
      ctx.yStarted = true;
      return ctx.index * delayBetweenPoints;
    }
  }
}

config = {
  type: 'line',
  data: {
    labels: labels,
    datasets: [
      {
        label: 'Price History',
        data: data,
        fill: false,
        borderColor: lineColor,
        cubicInterpolationMode: 'monotone',
        tension: 0.5,
      },
    ],
  },
  options: {
    animation: animation,
    interaction: {
      mode: 'nearest',
      axis: 'x',
      intersect: false
    },
    plugins: {
      legend: false
    },
    scales: {
      x: {
        type: 'time',
        time: {
          unit: 'day',
          parser: 'dd.mm.yyyy'
        },
      },
    }
  },
};

I've added the time adapter but it didn't seem to smooth things out.

Upvotes: 1

Views: 2082

Answers (1)

LeeLenalee
LeeLenalee

Reputation: 31361

The reason yours doesnt look smooth and the one on the chart.js docs site does is that they use 1000 datapoints for their chart. So the transition from one point to next is not smooth but is perceived as smooth since the jump is verry small.

Since you only have 4 datapoints the jumps are verry noticable and thus does not look smooth.

So if you want it to looks smooth you will need to add a lot more datapoints in between your current datapoints

Upvotes: 1

Related Questions