Creating Bell Curve using React-Chartjs-2

28 / Feb / 2024 by Aastha Tyagi 0 comments

Introduction

React-Chartjs-2 or Chartjs-2 is a powerful charting library. We can easily create lines, bars, and pie charts, but it doesn’t provide any direct feature to create a bell curve. In this post, we will learn to create a bell curve using React-Chartjs-2 by using the “Line” component for it.

Before we start writing, we need to install and import chartjs and react-chartjs-2  :

import {  Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Filler, Tooltip, Legend } from "chart.js";

import { Line } from "react-chartjs-2";
Next, we’d need to register our chart:
ChartJS.register(

    CategoryScale,

    LinearScale,

    PointElement,

    LineElement,

    Title,

    Tooltip,

    Legend,

    Filler,

    annotationPlugin // should be imported from "chartjs-plugin-annotation" only if we want to show values on graph (in our case here, percentage of data falling in each section)

);

Creating Export function :

  1. Add data values: In our export function, create a state to save the data that needs to be shown on the map. If our bell curve needs to be divided into “n” sections, then the state will have “n+1” values, where the first value will always be 0.

For 5 sections :

    const [ratingsData, setRatingsData] = useState([0,10,25,59,20,10]);
     2. Add options for graph :
const options = {

        responsive: true,

        plugins: {

            tooltip: { enabled: false },

            hover: { mode: null },

            legend: {

                position: "top"

            },

            title: {

                display: true,

                text: "",

            },

            annotation: {

                clip: false,

                annotations: {

                    label1: {

                        type: 'label',

                        display: true,

                        xValue: 1,

                        yValue: ratingsData[1] + 20,

                        backgroundColor: 'rgba(255,255,255)',

                        content: [ratingsData[1] ? `${ratingsData[1]}%` : ''],

                        font: {

                            size: 9

                        },

                    },

                    label2: {

                        type: 'label',

                        display: true,

                        xValue: 3,

                        yValue: ratingsData[2] + 20,

                        backgroundColor: 'rgba(255,255,255)',

                        content: [ratingsData[2] ? `${ratingsData[2]}%` : ''],

                        font: {

                            size: 9

                        }

                    },

                    label3: {

                        type: 'label',

                        display: true,

                        xValue: 5,

                        yValue: ratingsData[3] + 20,

                        backgroundColor: 'rgba(255,255,255)',

                        content: [ratingsData[3] ? `${ratingsData[3]}%` : ''],

                        font: {

                            size: 9

                        }

                    },

                    label4: {

                        type: 'label',

                        display: true,

                        xValue: 7,

                        yValue: ratingsData[4] + 20,

                        backgroundColor: 'rgba(255,255,255)',

                        content: [ratingsData[4] ? `${ratingsData[4]}%` : ''],

                        font: {

                            size: 9

                        }

                    },

                    label5: {

                        type: 'label',

                        display: true,

                        xValue: 9,

                        yValue: ratingsData[5] + 20,

                        backgroundColor: 'rgba(255,255,255)',

                        content: [ratingsData[5] ? `${ratingsData[5]}%` : ''],

                        font: {

                            size: 9

                        }

                    }

                },

            },

            datalabels: {

                display: false,

            },

        tension: 0.4,

        scales: {

            x: {

                grid: {

                    display: false

                },

                title: {

                    padding: { top: 35, left: 0, right: 0, bottom: 0 },

                    display: true,

                    text: 'Normal Company Wide Ratings',

                    font: {

                        weight: 'bold',

                        size: 12

                    },

                },

                ticks: {

                    font: {

                        weight: 'bold',

                        size: 9

                    },

                }

            },

            y: {

                grid: {

                    display: false

                },

                title: {

                    display: true,

                    text: 'Number of Newers',

                    font: {

                        weight: 'bold',

                        size: 12

                    },

                },

                ticks: {

                    display: false

                },

            }

        },

    };

3. Add Labels: To add labels on x-axis, create an array of “n” elements (with a nested array if a new line is required )

const labels =

        ["",

            [[1], ['Needs'], [' Improvement']],

            "",

            [[2], ['Below'], [' Expectations']],

            "",

            [[3], ['Met'], [' Expectations']],

            "",

            [[4], ['Exceeded'], [' Expectations']],

            "",

            [[5], ['Outstanding']],

            ""];

4. Create average points to be plotted on a graph: To create a curve, we need at least n*2 points on the graph, which can be done by creating average values.

const getAverageValue = (arr, index) => {

        let w = 0, x, y, z = 0;

        x = arr[index]

        y = arr[index + 1]

        return x > y ? (y + ((x - y) / 2)) : (x + ((y - x) / 2))

    }
const labels1 =

    {

        "0": getAverageValue(ratingsData, 0),

        "0.5": ratingsData[1],

        "1": getAverageValue(ratingsData, 1),

        "1.5": ratingsData[2],

        "2": getAverageValue(ratingsData, 2),

        "2.5": ratingsData[3],

        "3": getAverageValue(ratingsData, 3),

        "3.5": ratingsData[4],

        "4": getAverageValue(ratingsData, 4),

        "4.5": ratingsData[5],

        "5": 0

    }

5. Fill graph with colors: Create an array to add colors that must be filled in all graph sections.

var colors = [

        "rgba(241,91,105,1)",

        "rgba(254,226,130,1)",

        "rgba(31,158,107,1)",

        "rgba(79,162,255,1)",

        "rgba(64,56,255,1)",

    ];
      6. Create a dataset for the graph
let DataSet = [

        {

            label: ``,

            data: [

                labels1['0'],

                labels1['0.5'],

                labels1['1'],

            ],

            fill: {

                target: "origin",

                above: colors[0],

            },

            backgroundColor: 'rgb(255,255,255,0)',

            borderColor: 'rgb(255,255,255,0)',

        },

        {

            label: ``,

            data: [

                labels1['0'],

                labels1['0.5'],

                labels1['1'],

                labels1['1.5'],

                labels1['2'],

            ],

            fill: {

                target: "origin",

                above: colors[1],

            },

            backgroundColor: 'rgb(255,255,255,0)',

            borderColor: 'rgb(255,255,255,0)',

        },

        {

            label: ``,

            data: [

                labels1['0'],

                labels1['0.5'],

                labels1['1'],

                labels1['1.5'],

                labels1['2'],

                labels1['2.5'],

                labels1['3'],

            ],

            fill: {

                target: "origin",

                above: colors[2],

            },

            backgroundColor: 'rgb(255,255,255,0)',

            borderColor: 'rgb(255,255,255,0)',

        },

        {

            label: ``,

            data: [

                labels1['0'],

                labels1['0.5'],

                labels1['1'],

                labels1['1.5'],

                labels1['2'],

                labels1['2.5'],

                labels1['3'],

                labels1['3.5'],

                labels1['4']

            ],

            fill: {

                target: "origin",

                above: colors[3],

            },

            backgroundColor: 'rgb(255,255,255,0)',

            borderColor: 'rgb(255,255,255,0)',

        },

        {

            label: ``,

            data: [

                labels1['0'],

                labels1['0.5'],

                labels1['1'],

                labels1['1.5'],

                labels1['2'],

                labels1['2.5'],

                labels1['3'],

                labels1['3.5'],

                labels1['4'],

                labels1['4.5'],

                labels1['5'],

            ],

            fill: {

                target: "origin",

                above: colors[4],

            },

            backgroundColor: 'rgb(255,255,255,0)',

            borderColor: 'rgb(255,255,255,0)',

        },

    ];

7. Combining labels and datasets:  Create an object for labels and datasets. Then pass options and this data object to our Line Chart

const data = {

        labels: labels,

        datasets: DataSet,

    };

8. Return below from our export function :

<Line options={options} data={data} ref={chartRef}

Conclusion

After the final step, our graph will look like below:

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *