Creating Bell Curve using React-Chartjs-2
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";
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 :
- 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]);
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)", ];
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:

