[Chartjs]-Chartjs average line over bars

2๐Ÿ‘

I would calculate the average and spread it over the whole graph like this:

const getLineData = (initialData, lengthOfDataChunks) => {
  const numOfChunks = Math.ceil(initialData.length / lengthOfDataChunks);
  const dataChunks = [];

  for (var i = 0; i < numOfChunks; i++) dataChunks[i] = [];

  initialData.forEach((entry, index) => {
    const chunkNumber = Math.floor(index / lengthOfDataChunks);
    dataChunks[chunkNumber]
    dataChunks[chunkNumber].push(entry);
  });

  const averagedChunks = dataChunks.map(chunkEntry => {
    const chunkAverage = chunkEntry.reduce(sumArray) / lengthOfDataChunks;
    return chunkEntry.map(chunkEntryValue => chunkAverage);
  });

  return averagedChunks.flat();
}

const ctx = document.getElementById('canvas').getContext('2d');
const barData = [1, 2, 3, 1, 3, 4, 7, 2, 4, 3, 1, 6, 5, 2];
const sumArray = (accumulator, currentValue) => accumulator + currentValue;
const averageBarValue = barData.reduce(sumArray) / barData.length;
const lineData = getLineData(barData, 7);

var mixedChart = new Chart(ctx, {
  type: 'bar',
  data: {
    datasets: [{
      label: 'Bar Dataset',
      data: barData,
      backgroundColor: "#FF9881",
      order: 2
    }, {
      label: 'Line Dataset',
      data: lineData,
      type: 'line',
      borderColor: "#FF312D",
      fill: false,
      borderWidth: 1,
      order: 1
    }],
    labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
  },
  options: {
    "scales": {
      "yAxes": [{
        "ticks": {
          "beginAtZero": true
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>


<canvas id="canvas"></canvas>

I hope I got your question right. If not, please let me know!

1๐Ÿ‘

If your requirements are to draw just a flat, average line, I would go for
their official annotation plugin [chartjs-plugin-annotation].

I will insert a really basic, self-consistent example here, adapted from their documentation.

index.html:

<html>
    <head>
        <script src="index.js"></script>
    </head>

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

anyname.js [which you then need to browserify into the index.js source file]:

/* the following is just a shortcut to register all the needed elements, for any chart.
   more info here:
   https://www.chartjs.org/docs/3.3.0/getting-started/integration.html#bundlers-webpack-rollup-etc */
const Chart = require("chart.js/auto");

const annotationPlugin = require("chartjs-plugin-annotation");

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

const data = {
    labels: ["1", "2", "3", "4", "5", "6", "7"],
    datasets: [
        {
            label: "Sample Series",
            data: [40, 100, 54, 34, 13, 78, 41]
        }
    ]
};

const annotation = {
    type: 'line',
    borderColor: 'black',
    borderDash: [6, 6],
    borderDashOffset: 0,
    borderWidth: 3,
    label: {
        enabled: true,
        content: (ctx) => "Average: " + average(ctx).toFixed(2),
        position: 'end'
    },
    scaleID: 'y',
    value: (ctx) => average(ctx)
};

const config = {
    type: 'bar',
    data,
    options: {
        plugins: {
            title: {
                display: true,
                text: "Sample Chart",
                font: {
                    size: 14
                }
            },
            annotation: {
                annotations: {
                    annotation
                }
            }
        }
    }
};

// the annotation plugin needs to be registered, too
Chart.register(annotationPlugin);

document.addEventListener('DOMContentLoaded', () => {
    const myChart = new Chart(document.getElementById('canvas'), config);
}, false);

Node required libraries [which you need to install for browserify to work]:

  • chart.js โ€” v. 3.7.1
  • chartjs-plugin-annotation โ€” v. 1.3.1

References:

https://www.chartjs.org/chartjs-plugin-annotation/1.2.0/samples/line/average.html

Leave a comment