I have to display a line chart with two different datasets in one single chart. After execution of query I got the plan_plan and actual_plan of the following form.
plan_plan = 0: {week: "46", planned_del: "20"}
1: {week: "53", planned_del: "94"}
actual_plan = 0: {week: "8", actual_del: "1"}
javascript part:
function show_Graph()
{
{
var plandata = <?php echo json_encode($plan_plan); ?>;
var actualdata = <?php echo json_encode($actual_plan); ?>;
console.log(plandata);
var labels = [];
var plandel = [];
var actualdel = [];
for (var i in plandata) {
labels.push(plandata[i].week);
plandel.push(plandata[i]);
}
for (var j in actualdata) {
labels.push(actualdata[j].week);
actualdel.push(actualdata[j]);
}
var chartdata = {
labels: labels,
datasets: [
{
label: "Planned Deliverables",
fill: false,
borderColor: "rgba(255, 0, 0, 1)",
pointHoverBackgroundColor: "rgba(255, 0, 0, 1)",
data: plandel
},
{
label: "Actual Deliverables",
fill: false,
backgroundColor: "rgba(0, 255, 0, 0.75)",
borderColor: "rgba(0, 255, 0, 1)",
pointHoverBackgroundColor: "rgba(0, 255, 0, 1)",
pointHoverBorderColor: "rgba(0, 255, 0, 1)",
data: actualdel
}
]
};
var graphTarget = $("#scurve_chart");
var barGraph = new Chart(graphTarget, {
type: 'line',
data: chartdata,
options: {
elements: {
point:{
radius: 1,
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
barValueSpacing: 2,
barPercentage: 0.2
}]
}
}
});
}}
I want to get the week in x axis and then planned_del and actual_del data in y axis which can be shown as line chart. And also should show a single point entry even when there is no data points to be connected.
One way for achieving this, would be to defined data.labels as an array of numbers from 0 to 53.
labels: [0, 1, 2, ... 53]
The data inside the two datasets would then only contain the definitions of individual points.
data: [{ x: 46, y: 20 }, { x: 53, y: 94 }] // plandata
...
data: [{ x: 8, y: 1}] // actualdata
Here's the JavaScript part that illustrates how the desired result can be obtained.
var plandata = [{ week: "46", planned_del: "20" }, { week: "53", planned_del: "94" }];
var actualdata = [{ week: "8", actual_del: "1" }];
new Chart("scurve_chart", {
type: 'line',
data: {
labels: Array.from(new Array(54), (x, i) => i),
datasets: [{
label: "Planned Deliverables",
fill: false,
borderColor: "rgba(255, 0, 0, 1)",
pointHoverBackgroundColor: "rgba(255, 0, 0, 1)",
data: plandata.map(o => ({ x: Number(o.week), y: Number(o.planned_del)}))
},
{
label: "Actual Deliverables",
fill: false,
backgroundColor: "rgba(0, 255, 0, 0.75)",
borderColor: "rgba(0, 255, 0, 1)",
pointHoverBackgroundColor: "rgba(0, 255, 0, 1)",
pointHoverBorderColor: "rgba(0, 255, 0, 1)",
data: actualdata.map(o => ({x: Number(o.week), y: Number(o.actual_del)}))
}
]
},
options: {
tooltips: {
callbacks: {
title: (tooltipItem, data) => "Week " + data.datasets[tooltipItem[0].datasetIndex].data[tooltipItem[0].index].x
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
ticks: {
min: 0,
max: 53,
stepSize: 1
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
<canvas id="scurve_chart" height="90"></canvas>
Related
I have a mixed chart (scatter and line), hence I need 2 xAxis.
There's an extra grid that appears on the bottom of the chart, because that's where the other x axis normally has its labels (I removed them because I don't need them)
I'm trying to get rid of that extra grid, but I can't find how to do it. I've tried to specify the ticks color as white but the grid's still there.
Look at the image, it's that solitary extra grid at the bottom (marked with an horizontal bracket):
This is my code:
const ctx = document.getElementById('myChart');
const labels1 = ['A','R','Fyo','A-MAC','HR','Do','Rs','Dpr','GM','GF','EPK','EPS','Is1','Is2','Is3','FP','INVAR','INVER'];
const lasIs = (ctx, value) => ctx.p0DataIndex > 11 ? value: undefined;
const markedIdxs = [0,5,10,15,20,25,30,35,44, //... and many more];
const markedVals = [0,5,10,15,20,25,30,35,10,// ... and many more];
const data1 = {
labels: labels1,
datasets: [
{
type: 'line',
label: 'Line Dataset',
data: [65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65],
pointRadius: 0,
borderWidth: 1,
borderColor: '#0070C5',
xAxisID: 'x2'
},
{
type: 'line',
label: 'Line Dataset',
data: [50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50],
pointRadius: 0,
borderWidth: 1,
borderColor: '#0070C5',
xAxisID: 'x2'
},
{
type: 'line',
label: 'Line Dataset',
data: [102, 38, 54, 56, 102, 38, 54, 56, 102, 38, 54, 56, 102, 38, 54, 87, 62, 91],
pointStyle: 'circle',
pointRadius: 5,
borderWidth: 2,
borderColor: 'rgba(0, 120, 161,0.5)',
backgroundColor: 'rgba(0, 120, 161,0.5)',
fill: true,
segment: {
borderColor: ctx => lasIs (ctx, 'rgba(0, 168, 172, 0.5'),
backgroundColor: ctx => lasIs (ctx, 'rgba(0, 168, 172, 0.5'),
},
xAxisID: 'x2'
},
{
type: 'scatter',
pointStyle: 'dash',
pointRadius: 6,
borderColor: 'rgba(0, 0, 255,0.2)',
xAxisID: 'x',
data: [{x:1, y:36}, {x:1, y:37}, {x:1, y:39}, {x:1, y:40}, {x:1, y:42}... //and many more]
},
],
};
const multiplos5 = {
id: 'multiplos5',
afterDatasetsDraw(chart, args, options) {
const {ctx} = chart;
ctx.save();
ctx.font = "8px Verdana";
ctx.fillStyle = "#0070C5";
yaSeDibujo=84;
paddLeft = 0;
for (i=0; i < markedIdxs.length; i++) {
if (markedVals[i] < 10)
paddLeft=8;
else
paddLeft=12;
ctx.fillText(markedVals[i], chart.getDatasetMeta(3).data[markedIdxs[i]].x - paddLeft, chart.getDatasetMeta(3).data[markedIdxs[i]].y + 3);
}
}
};
Chart.register(multiplos5);
const myChart = new Chart(ctx, {
data: data1,
options: {
scales: {
x2: { // add extra axes
min: 0,
max: 18,
position: 'bottom',
type: 'category',
ticks: {color: '#0070C5'},
offset: true
},
x: {
min: 1,
max: 18,
ticks: {stepSize: 1, display: false},
offset: true
},
y: {
min: 20,
max: 120,
ticks: {stepSize: 10, color: '#555555', crossAlign: 'start'},
grid:{color:'#f1f1f1', display:true},
},
y2: {
position: 'right',
min: 20,
max: 120,
ticks: {stepSize: 10, color: '#555555'},
grid:{display:false}
},
},
plugins: {
multiplos5,
legend: false,
tooltip: {
displayColors: false,
filter: function (tooltipItem) {
return tooltipItem.datasetIndex == 2;
},
callbacks: {
//title: "el tÃtulo",
label: function(context) {
let label = labels2[context.dataIndex] + ': ' + context.parsed.y;
return label;
}
}
}
},
},
});
Chart.js version is 3.6.2
Any help/workaround will be really appreciated.
Regards!!
Forgot to mention that the axis I'm talking about is 'x' (xAxisID: 'x')
In your config for the X axis where you set the ticks to display false, if you instead do this in the root of the X scale config it will hide that line so you will get:
scales:{
x: {
display: false,
min: 1,
max: 18,
offset: true
}
}
My chart has 100 labels. These labels are from 0 to 10. Some labels are decimal. But i just want to see integers on my chart. How can i hide decimals? You can check my picture and code below.
chart
var timeLabels = [];
for (let j = 0; j <= scheduling.totalPeriod; j++) {
timeLabels.push(j / 10);
}
var schedulingChart = new Chart(ctx, {
type: 'line',
data: {
labels: timeLabels,
datasets: [{
steppedLine: true,
label: scheduling.process[i].name,
data: scheduling.process[i].chart,
backgroundColor: ['rgba(255, 255, 255, 0.5)'],
borderColor: ['rgba(255, 255, 255, 1)'],
borderWidth: 1,
pointBackgroundColor: 'green',
pointBorderColor: 'black',
pointRadius: 4
}]
},
options: {
maintainAspectRatio: false,
scales: {
yAxes: [{
gridLines: {
color: 'rgba(0, 0, 0, 0.5)',
},
ticks: {
stepSize: 1,
fontColor: 'rgba(255, 255, 255, 1)'
}
}],
xAxes: [{
gridLines: {
color: 'rgba(0, 0, 0, 0.5)',
},
ticks: {
fontColor: 'white',
}
}]
}
}
});
New for other problem
I have to display a line chart with two different datasets in one single chart. After execution of the query I got the plan_plan and actual_plan of the following form.
plan_plan = 0: {label: "Feb-20", plan_hrs: "20"}
1: {label: "Oct-20", plan_hrs: "94"}
actual_plan = 0: {label: "Mar-20", actual_hrs: "1"}
javacript code:
function show_Graph()
{
{
var plandata = <?php echo json_encode($plan_plan); ?>;
var actualdata = <?php echo json_encode($actual_plan); ?>;
var labels = [];
for (var i in plandata) {
labels.push(plandata[i].label);
}
for (var j in actualdata) {
labels.push(actualdata[j].label);
}
new Chart("scurve_chart", {
type: 'line',
data: {
labels: Array.from(labels),
datasets: [{
label: "Planned Hours",
fill: false,
borderColor: "rgba(255, 0, 0, 1)",
pointHoverBackgroundColor: "rgba(255, 0, 0, 1)",
data: plandata.map(o => ({ x: Number(o.label), y: Number(o.plan_hrs)}))
},
{
label: "Actual Hours",
fill: false,
backgroundColor: "rgba(0, 255, 0, 0.75)",
borderColor: "rgba(0, 255, 0, 1)",
pointHoverBackgroundColor: "rgba(0, 255, 0, 1)",
pointHoverBorderColor: "rgba(0, 255, 0, 1)",
data: actualdata.map(o => ({x: Number(o.label), y: Number(o.actual_hrs)}))
}
]
},
options: {
tooltips: {
callbacks: {
title: (tooltipItem, data) => "Month " + data.datasets[tooltipItem[0].datasetIndex].data[tooltipItem[0].index].x
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Hours'
}
}],
xAxes: [{
ticks: {
min: 0,
max: 53,
stepSize: 1
},
scaleLabel: {
display: true,
labelString: 'Month'
}
}]
}
}
});
}}
I want to get the month in the format (Jan-20) in x-axis and then plan_hrs and actual_hrs data in y-axis which can be shown as a line chart. And also should show a single point entry even when there are no data points to be connected. I have used the script tags:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
But it is not showing graph when I am including the following script for bootstrap:
<script src="build/js/custom.min.js">
I can help for parsing and displaying the dates on the xAxis but unfortunately I don't know Bootstrap.
Define your xAxis as follows:
xAxes: [{
type: 'time',
time: {
parser: 'MMM-YY',
unit: 'month',
displayFormats: {
month: 'MMM-YY'
}
}
}]
Chart.js internally uses Moment.js, hence you can use the following date/time formats for parsing and displaying the date. In your case, this is 'MMM-YYD'.
const plan_plan = [{label: "Feb-20", plan_hrs: "20"}, {label: "Oct-20", plan_hrs: "94"}];
const actual_plan = [{label: "Mar-20", actual_hrs: "1"}];
new Chart("scurve_chart", {
type: 'line',
data: {
datasets: [{
label: "Planned Hours",
fill: false,
borderColor: "rgba(255, 0, 0, 1)",
data: plan_plan.map(o => ({ x: o.label, y: Number(o.plan_hrs)}))
},
{
label: "Actual Hours",
fill: false,
borderColor: "rgba(0, 255, 0, 1)",
data: actual_plan.map(o => ({x: o.label, y: Number(o.actual_hrs)}))
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
type: 'time',
time: {
parser: 'MMM-YY',
unit: 'month',
displayFormats: {
month: 'MMM-YY'
}
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
<canvas id="scurve_chart" height="90"></canvas>
I am trying to add some data to a chart created with chart.js.
I get "undefined" as an error. How do I add data into this? Looks like a stupid silly newbie error...please bear with me and help. Thanks
var birdsCanvas = document.getElementById("birdsChart");
Chart.defaults.global.defaultFontFamily = "Lato";
Chart.defaults.global.defaultFontSize = 18;
var birdsData = {
labels: ["Spring", "Summer", "Fall", "Winter"],
datasets: [{
//data: [1200, 1700, 800, 200],
data: [5, 10, 3, 9],
backgroundColor: [
"rgba(255, 0, 0, 0.6)",
"rgba(0, 255,200, 0.6)",
"rgba(200, 0, 200, 0.6)",
"rgba(0, 255, 0, 0.6)"
],
borderColor: "rgba(0, 0, 0, 0.8)"
}]
};
var chartOptions = {
startAngle: -Math.PI / 4,
legend: {
position: 'left'
},
animation: {
animateRotate: false
}
};
var polarAreaChart = new Chart(birdsCanvas, {
type: 'polarArea',
data: birdsData,
options: chartOptions
});
//alert ('checking value... birdsData label 1 ' + birdsData.labels[1]);
polarAreaChart.birdsData.datasets.push({
label: 'label2',
backgroundColor: 'rgba(255, 0, 0, 0.6)',
borderColor: 'rgba(255, 0, 0, 0.6)',
data: [9]
});
barChart.update();
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="birdsChart" width="600" height="550"></canvas>
I get TypeError: polarAreaChart.birdsData is undefined .. I just want to add data dynamically through functions when users click on something..
Thanks
You might want to use polarAreaChart.data.datasets.push({ instead of birdsData as there is no bridsData object in the chart object:
var birdsCanvas = document.getElementById("birdsChart");
Chart.defaults.global.defaultFontFamily = "Lato";
Chart.defaults.global.defaultFontSize = 18;
var birdsData = {
labels: ["Spring", "Summer", "Fall", "Winter"],
datasets: [{
//data: [1200, 1700, 800, 200],
data: [5, 10, 3, 9],
backgroundColor: [
"rgba(255, 0, 0, 0.6)",
"rgba(0, 255,200, 0.6)",
"rgba(200, 0, 200, 0.6)",
"rgba(0, 255, 0, 0.6)"
],
borderColor: "rgba(0, 0, 0, 0.8)"
}]
};
var chartOptions = {
startAngle: -Math.PI / 4,
legend: {
position: 'left'
},
animation: {
animateRotate: false
}
};
var polarAreaChart = new Chart(birdsCanvas, {
type: 'polarArea',
data: birdsData,
options: chartOptions
});
//alert ('checking value... birdsData label 1 ' + birdsData.labels[1]);
polarAreaChart.data.datasets.push({
label: 'label2',
backgroundColor: 'rgba(255, 0, 0, 0.6)',
borderColor: 'rgba(255, 0, 0, 0.6)',
data: [9]
});
polarAreaChart.update();
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="birdsChart" width="400" height="400"></canvas>
Here is an example of one run of my chart:
Chart configuration:
At the moment I just set a maximum tick value, i.e. max: 100000000. I figure I need to pass some function that adjusts the maximum value whenever the largest exceeds the largest value of the y axis. How can this be done?
_chart.chart_3.config = {
type: 'line',
data: {
labels: ['Harvest 1', 'Harvest 2', 'Harvest 3', 'Harvest 4','Harvest 5'],
datasets: [{
lineTension: 0,
label: 'Bill',
data: [],
fill: false,
fillColor : "rgba(0, 0, 0, 1)",
strokeColor : "rgba(0, 0, 0, 1)",
backgroundColor: "rgb(54, 162, 235)",
borderColor: "rgb(54, 162, 235)",
},
{
lineTension: 0,
label: 'Ann',
data: [],
fill: false,
fillColor : "rgba(0, 0, 0, 1)",
strokeColor : "rgba(0, 0, 0, 1)",
backgroundColor: "rgb(255, 99, 132)",
borderColor: "rgb(255, 99, 132)",
},
{
lineTension: 0,
label: 'Bill (Sharing)',
data: [],
fill: false,
fillColor : "rgba(0, 0, 0, 1)",
strokeColor : "rgba(0, 0, 0, 1)",
backgroundColor: "rgb(4, 0, 255)",
borderColor: "rgb(4, 0, 255)",
},
{
lineTension: 0,
label: 'Ann (Sharing)',
data: [],
fill: false,
fillColor : "rgba(0, 0, 0, 1)",
strokeColor : "rgba(0, 0, 0, 1)",
backgroundColor: "rgb(255, 0, 0)",
borderColor: "rgb(255, 0, 0)",
},
{
lineTension: 0,
label: 'Pool',
data: [],
fill: false,
fillColor : "rgba(0, 0, 0, 1)",
strokeColor : "rgba(0, 0, 0, 1)",
backgroundColor: "rgb(128,36,171)",
borderColor: "rgb(128,36,171)",
}]
},
options: {
responsive: true,
title: {
display: true,
text: ''
},
tooltips: {
enabled: false,
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'KG',
},
type: 'logarithmic',
position: 'left',
ticks: {
min: 0, //minimum tick
max: newMax(value), //maximum tick
callback: function (value, index, values) {
return Number(value.toString()); //pass tick values as a string into Number function
}
}
}]
}
}
};
New max function:
newMax = function(values) {
max = Math.max(values)
max = max * 1.2
return Number(max.toString())
}
I'm not sure what your data looks like, but I'm assuming it's an array of values with numbers, all you'd need to do is find the max number than add a little buffer on the end to keep the graph looking pretty, so the max number it goes to, then add a little on the end.
function getMax(arr) {
const max = Math.max(...arr).toString();
const newMax = 1 + "0".repeat(max.length);
return newMax
}
max: getMax(values)