How to make Chart.js with dynamic months on x-axis - javascript

I'm trying to make a Chart.js with a dynamic x-axis that will always use the next 7 months as the ticks for the x-axis.
But I'm having two problems:
The lines are not showing on my graph
The x-axis is only showing the first and last month, none of the months in-between.
Here is an example I made in paint to show what I'm trying to achieve:
And here is the code I have so far:
/* Build the charts */
var ctx = document.getElementById('ROIchart').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
datasets: [{
label: 'Paid Search and Leads',
backgroundColor: 'red',
borderColor: 'red',
data: [10, 10, 10, 10, 10, 10, 10],
}, {
label: 'SEO and Content',
backgroundColor: 'green',
borderColor: 'green',
data: [0, 2, 8, 21, 57, 77, 100],
fill: true,
}]
},
// Configuration options go here
options: {
responsive: true,
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'month'
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="ROIchart"></canvas>

With the moment.js library, you can look at the length of your array, and from a starting month generate the months, and then put them as labels
/* Build the charts */
var ctx = document.getElementById('ROIchart').getContext('2d');
var array1 = [10, 10, 10, 10, 10, 10, 10];
var months = []
for (let i = 0; i < array1.length; i++) {
months.push(moment().year(2020).month(i+1).date(0).startOf('month'))
}
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: months,
datasets: [{
label: 'Paid Search and Leads',
backgroundColor: 'red',
borderColor: 'red',
data: array1,
}, {
label: 'SEO and Content',
backgroundColor: 'green',
borderColor: 'green',
data: [0, 2, 8, 21, 57, 77, 100],
fill: true,
}]
},
options: {
responsive: true,
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'month'
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>
<canvas id="ROIchart"></canvas>

Related

Chart.js does not scale with two yAxis

I struggle to let my second y-Axis scale to my second data array.
The green data should be scaled according to the right y-Axis (not working).
The red data is correctly scaled to the left y-Axis.
<div id="chartWrapper" class="card-content column is-two-thirds">
<canvas id="myChart" height="250px"></canvas>
<script>
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
datasets: [{
label: 'Temperatur in C°',
yAxisID: 'A',
borderColor: "red",
data: 0
},
{
label: 'Niederschlagsmenge in mm',
yAxisID: 'B',
borderColor: "blue",
data: 0
}]
},
options: {
scales: {
A: {
type: 'linear',
beginAtZero: false,
position: 'left',
display: true
},
B: {
type: 'linear',
beginAtZero: false,
position: 'right',
display: true
}
}
}
});
</script>
</div>
Don't be confused with the data being 0, I add the data dynamically.
Thank you very much for any help.
This is because you are using V2 of chart.js in which the scales need to be configured as arrays like so:
new Chart(ctx, {
type: 'line',
data: {},
options: {
scales: {
yAxes: [{
id: 'A'
}, {
id: 'B'
}]
}
}
})

Is it possible to draw a line chart in chart.js with multiple lines and **multiple lables**

Suppose x1={1,4,7,9} | y1={10,20,35,40} and x2={2,3,6,9} | y2={15,23,30,35}. Now I want to draw a line chart in chart.js for it.
P.S. Scatter chart is not a solution because my website is generating data dynamically so I have to provide data in array only and scatter requires the data in very sophisticated manner.
My simple question is by any way, can we have different x axis points in line chart for different lines??
code for your reference:
<!DOCTYPE html>
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<body>
<canvas id="myChart" style="width:100%;max-width:600px"></canvas>
<script>
var xValues1 = [50,60,70,80,90,100,110,120,130,140,150];
var yValues1 = [7,8,8,9,9,9,10,11,14,14,15];
var xValues2 = [54,64,74,84,94,104,114,124,134,144,154];
var yValues2 = [8,9,9,10,10,10,11,12,15,15,16];
new Chart("myChart", {
type: "line",
data: {
labels: xValues1,
datasets: [{
fill: false,
backgroundColor: "rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
data: yValues1
},
{
fill: false,
backgroundColor: "rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
data: yValues2
}
]
},
options: {
legend: {display: false},
scales: {
yAxes: [{ticks: {min: 6, max:16}}],
}
}
});
</script>
</body>
</html>
(for yvalues2, I want xvalues2)
You can add a second X axis for your other labels:
const xValues1 = [50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150];
const yValues1 = [7, 8, 8, 9, 9, 9, 10, 11, 14, 14, 15];
const xValues2 = [54, 64, 74, 84, 94, 104, 114, 124, 134, 144, 154];
const yValues2 = [8, 9, 9, 10, 10, 10, 11, 12, 15, 15, 16];
const options = {
type: 'line',
data: {
datasets: [{
label: '# of Votes',
data: yValues1,
borderColor: 'pink'
},
{
label: '# of Points',
data: yValues2,
borderColor: 'orange',
xAxisID: 'x2' // Match dataset to other axis
}
]
},
options: {
scales: {
xAxes: [{
type: 'category',
labels: xValues1,
id: 'x',
display: true // Set to false to hide the axis
},
{
type: 'category',
labels: xValues2,
id: 'x2',
display: true // Set to false to hide the axis
}
]
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>

how change color of labels of legends of chart.js

i use of chart.js package for create a chart.
my problem:
how change the color of label of each legends?
for example:
color of "legend1" be: red.
color of "legend2" be: blue.
my codes:
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
data: {
labels: ['۱۴۰۰/۰۱/۰۱', '۱۴۰۰/۰۱/۰۲', '۱۴۰۰/۰۱/۰۳', '۱۴۰۰/۰۱/۰۴', '۱۴۰۰/۰۱/۰۵', '۱۴۰۰/۰۱/۰۶'],
datasets: [{
type: 'line',
label: 'legend1',
backgroundColor: 'rgb(14, 156, 255)',
data: [6, 5.5, 4, 7, 5.4, 5.8],
fill: false,
borderColor: 'rgb(14, 156, 255)',
tension: 0
},
{
type: 'line',
label: 'legend2',
backgroundColor: 'rgb(22, 185, 156)',
data: [6.2, 5.7, 3.8, 7.2, 5.2, 5.9],
fill: false,
borderColor: 'rgb(22, 185, 156)',
tension: 0
}
] //end : datasets
}, // end: data
options: {
plugins: {
legend: {
labels: {
font: {
size: 18
} // end: font
} // end: labels
,
position: 'bottom',
rtl: true,
align: "start"
} // end: legend
}, // end: plugins
scales: {
y: {
beginAtZero: true,
display: false
} // end: y
,
x: {
grid: {
borderDash: [6, 5],
lineWidth: 1,
color: '#CCCCCC'
} // end: grid
} //end:x
} // end: scales
} //end: options
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.7.1/dist/chart.min.js"></script>
<canvas id="myChart" width="778" height="433"></canvas>
my problem is just that: how change the color of each legend's text?
color of "legend1" text and color of "legend2" text.
my codes result:
To achieve what you want you will need to use a custom generateLabels function like so:
const legendColors = ['red', 'blue']
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'orange'
}
]
},
options: {
plugins: {
legend: {
labels: {
generateLabels: (chart) => {
const datasets = chart.data.datasets;
const {
labels: {
usePointStyle,
pointStyle,
textAlign,
color
}
} = chart.legend.options;
return chart._getSortedDatasetMetas().map((meta, i) => {
const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
const borderWidth = Chart.helpers.toPadding(style.borderWidth);
return {
text: datasets[meta.index].label,
fillStyle: style.backgroundColor,
fontColor: legendColors[i],
hidden: !meta.visible,
lineCap: style.borderCapStyle,
lineDash: style.borderDash,
lineDashOffset: style.borderDashOffset,
lineJoin: style.borderJoinStyle,
lineWidth: (borderWidth.width + borderWidth.height) / 4,
strokeStyle: style.borderColor,
pointStyle: pointStyle || style.pointStyle,
rotation: style.rotation,
textAlign: textAlign || style.textAlign,
borderRadius: 0, // TODO: v4, default to style.borderRadius
// Below is extra data used for toggling the datasets
datasetIndex: meta.index
};
}, this);
}
}
}
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>
Did you try the hex format ?
For example, you could try replacing "rgb(14, 156, 255)" by "#0e9cff"
More info here : https://devsheet.com/code-snippet/change-color-of-the-line-in-chartjs-line-chart/

Legend not displaying on Line or Bar chart - React-Chartjs-2

I am having some difficulties getting the legend to display on several of my graphs in my react dashboard.
I am using React-Chartjs-2 . The legends were working originally, then I tested turning legends off in the Chart.default properties and when I tried to turn it back on, they did not reappear.
My global Chart settings are as follows:
// React-Chartjs-2 Global Styling
defaults.global.elements.point.radius = 1;
defaults.global.elements.line.tension = 0.1;
defaults.global.elements.point.hoverRadius = 10;
defaults.global.elements.point.hitRadius = 12;
// Font
defaults.global.defaultFontSize = 12;
defaults.global.defaultFontColor = "#838383";
// Legend
defaults.global.legend.display = true;
defaults.global.legend.align = "start";
defaults.global.legend.position = "bottom";
defaults.global.legend.labels = {
padding: 30,
boxWidth: 15,
};
My local chart properties for my Line, Bar and Doughnut charts all follow a similar layout, being:
<Line
data={props.graph.data}
height={300}
options={{
maintainAspectRatio: false,
legend: {
display: true,
},
scales: {
xAxes: [{
gridLines: {
display: false
}
}],
yAxes: [{
gridLines: {
drawBorder: false,
},
ticks: {
beginAtZero:true,
// Include a kwh sign in the ticks
callback: function(value, index, values) {
return value + 'kWh';
}
},
}]
}
}}
/>
As you can see, Legends are turned on in both global and local settings.
Currently, only the doughnut chart is displaying it's legend. Toggling the display:true value only shifts the bottom of the Line/Bar chart up and down a small amount.
Anybody encountered a similar issue?
It looks like the defaults can't handle being passed an object, if you define the defaults for the legend label padding and boxWidth separately then it will render your legend.
Normal example but problem was the same as if you would use react wrapper:
const defaults = Chart.defaults;
defaults.global.elements.point.radius = 1;
defaults.global.elements.line.tension = 0.1;
defaults.global.elements.point.hoverRadius = 10;
defaults.global.elements.point.hitRadius = 12;
// Font
defaults.global.defaultFontSize = 12;
defaults.global.defaultFontColor = "#838383";
// Legend
defaults.global.legend.display = true;
defaults.global.legend.align = "start";
defaults.global.legend.position = "bottom";
defaults.global.legend.labels.padding = 30;
defaults.global.legend.labels.boxWidth = 15;
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
reverse: false
}
}]
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
canvas {
background-color : #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js" integrity="sha512-hZf9Qhp3rlDJBvAKvmiG+goaaKRZA6LKUO35oK6EsM0/kjPK32Yw7URqrq3Q+Nvbbt8Usss+IekL7CRn83dYmw==" crossorigin="anonymous"></script>
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
</body>
Already answer has been given even though, I would like to give alternative solution without defaults namespace options.
We can achieve it with plugins namespace in reactjs.
<Line
data={{
labels: ["1", "2", "3", "4", "5", "6"],
datasets: [
{
label: "Primary kVA",
data: [6, 17, 12, 19, 10, 55, 5, 22, 3, 100, 200, 350],
fill: false,
backgroundColor: "rgb(255, 99, 132)",
borderColor: "rgba(255, 99, 132, 0.2)",
},
{
label: "Redundant kVA",
data: [12, 23, 33, 55, 22, 300, 100, 200, 350],
fill: false,
backgroundColor: "rgb(77, 255, 156)",
borderColor: "rgb(77, 255, 156,0.73)",
},
],
}}
options={{
plugins: {
legend: {
display: true,
position: "right",
align: "start",
labels: {
usePointStyle: true,
},
},
},
}}
/>

How to add vertical interactive guide line to Chart.js

I am trying to build a fairly simple line chart with Chart.js but I need it to have a vertical guide line that shows up along with the tooltop when you hover over a point. I want something very similar to http://nvd3.org/examples/line.html but using Chart.js.
Here is an example of what I want that I cobbled together from various examples. Notice that the line disappears when you hover over a point.
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
datasets: [{
fill: true,
label: 'You',
backgroundColor: 'rgba(0,170,238, 0.5)',
data: [8, 16, 30, 15, 12, 4]
}, {
fill: true,
label: 'Others',
backgroundColor: 'rgba(153,170,238, 0.5)',
data: [5, 4, 3, 5, 2, 3]
}]
},
options: {
legend: {
display: false
},
tooltips: {
mode: 'x-axis',
backgroundColor: '#ffffe0',
bodyFontColor: '#000',
bodySpacing: 7,
multiKeyBackground: '#ffffe0',
titleFontColor: '#000',
titleMarginBottom: 5,
xPadding: 10,
yPadding: 10
},
scales: {
xAxes: [{
display: false
}],
yAxes: [{
display: false
}]
}
}
});
// Hook into main event handler
var parentEventHandler = Chart.Controller.prototype.eventHandler;
Chart.Controller.prototype.eventHandler = function(e) {
console.log(e);
var ret = parentEventHandler.apply(this, arguments);
this.clear();
this.draw();
// Draw the vertical line here
var eventPosition = Chart.helpers.getRelativePosition(arguments[0], this.chart);
this.chart.ctx.beginPath();
this.chart.ctx.moveTo(eventPosition.x, 0);
this.chart.ctx.strokeStyle = "#ff0000";
this.chart.ctx.lineTo(eventPosition.x, this.chart.height);
this.chart.ctx.stroke();
return ret;
};
<canvas id="myChart" height=200/>

Categories