skip to Main Content

What’s the correct configuration to add a line annotation to a chart.js chart where the x-axis is of the ‘timeseries’ type?

Without the timeseries the following code works as expected.

function average(ctx) {
  const values = ctx.chart.data.datasets[0].data;
  return values.reduce((a, b) => a + b, 0) / values.length;
}

const ctx = document.getElementById('chart');

const mean = {
  type: 'line',
  drawTime: 'afterDraw',
  label: {
    display: true,
    content: (ctx) => average(ctx).toFixed(2),
   },
   scaleID: 'y',
   value: (ctx) => average(ctx)
 };

const chart = new Chart(ctx, {
  type: 'line',
  data: {
     labels:   ['', '', '', '', '', '', '', '', '', '', '', '', '', ''],
     datasets: [
       { data: [42, 129, 53, 55, 52, 62, 68, 55, 61, 58, 66, 63, 53, 69] }
     ]
  },
  options: {
    plugins: {,
       annotation: {
         annotations: {
          mean
         }
      }
    }
  }
});

working chart

However, when I introduce the timeseries

function average(ctx) {
  const values = ctx.chart.data.datasets[0].data;
  return values.reduce((a, b) => a + b, 0) / values.length;
}

const ctx = document.getElementById('chart');

const mean = {
  type: 'line',
  drawTime: 'afterDraw',
  label: {
    display: true,
    content: (ctx) => average(ctx).toFixed(2),
   },
   scaleID: 'y',
   value: (ctx) => average(ctx)
 };

const chart = new Chart(ctx, {
  type: 'line',
  data: {
    datasets: [
      {
        data: [ 
        { x: '2023-04-03 10:32:09', y: 42 },
        { x: '2023-04-03 10:32:16', y: 129 },
        { x: '2023-04-03 10:32:29', y: 53 },
        { x: '2023-04-03 10:32:37', y: 55 },
        { x: '2023-04-03 10:32:44', y: 52 },
        { x: '2023-04-03 10:32:51', y: 62 },
        { x: '2023-04-03 10:33:04', y: 68 },
        { x: '2023-04-03 10:33:12', y: 55 },
        { x: '2023-04-03 10:33:26', y: 61 },
        { x: '2023-04-03 10:34:11', y: 58 },
        { x: '2023-04-03 10:34:27', y: 66 },
        { x: '2023-04-03 10:34:34', y: 63 },
        { x: '2023-04-03 10:34:48', y: 53 },
        { x: '2023-04-03 10:34:55', y: 69 } ]
      },
    ]
  },
  options: {
    scales: {
      x: { 
        type: 'timeseries',
        time: { unit: 'hour' },
        ticks: { beginAtZero: true } 
      }
    },
    plugins: {
       annotation: {
         annotations: {
          mean
        }
      }
    }
  }
});

enter image description here

The annotation is not rendered.

Am I missing anything here?

2

Answers


  1. You should import the date adapter library as mentioned in the [documentation]

    The time scale requires both a date library and a corresponding adapter to be present. Please choose from the available adapters.

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

    While in the annotation which you are drawing a line indicating the average,

    b is an object, instead, I believe that you should get the value with b.y.

    function average(ctx) {
      const values = ctx.chart.data.datasets[0].data;
      return values.reduce((a, b) => a + b.y, 0) / values.length;
    }
    

    Demo @ StackBlitz

    Login or Signup to reply.
  2. The issue is the average function. When you are using "data points" (objects as data), you have to use the property of the object which is representing the Y data.

    function average(ctx) {
      const values = ctx.chart.data.datasets[0].data;
      // you have to use b.y to get the y value and not simply b which is an object
      return values.reduce((a, b) => a + b.y, 0) / values.length;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search