Related
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>
I have this graph with four datasets. Two that shows count of values and two lines that represent a goal or target for each value. What I want is to group all tooltips while hovering but exclude the two tooltips for the goal lines. How does one do that?
The following code shows some mockup numbers for the data, and the tooltip shows me all the labels.
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [{
label: 'Count type 1',
data: [48, 33, 32, 35, 42, 38],
backgroundColor: 'transparent',
borderColor: 'rgba(255, 204, 0, 1)',
fillColor: 'rgba(255, 204, 0, 0.1)',
pointBorderColor: 'transparent',
pointBackgroundColor: 'rgba(255, 204, 0, 1)',
pointRadius: 4,
borderWidth: 2,
lineTension: 0.3
},
{
label: 'Goal 1',
data: [48.000, 47.040, 46.080, 45.120, 44.160, 43.200],
backgroundColor: 'transparent',
borderColor: 'rgba(0, 255, 0, 1)',
fillColor: 'transparent',
pointBorderColor: 'transparent',
pointRadius: 0,
borderWidth: 0.4,
lineTension: 0
},
{
label: 'Count type 2',
data: [24, 37, 30, 22, 29, 18],
backgroundColor: 'transparent',
borderColor: 'rgba(255, 0, 0, 1)',
fillColor: 'rgba(255, 0, 0, 0.1)',
pointBorderColor: 'transparent',
pointBackgroundColor: 'rgba(255, 0, 0, 1)',
pointRadius: 4,
borderWidth: 2,
lineTension: 0.3
},
{
label: 'Goal 2',
data: [24.000, 23.520, 23.040, 22.560, 22.080, 21.600],
backgroundColor: 'transparent',
borderColor: 'rgba(0, 255, 0, 1)',
pointBorderColor: 'transparent',
pointRadius: 0,
borderWidth: 0.4,
lineTension: 0
}
]
},
options: {
tooltips: {
enabled: true,
mode: 'index',
intersect: false,
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<canvas id="myChart"></canvas>
I have tried various methods, some that works half way (excludes only one dataset) or with too much extra code and 'blinking' or flickering tooltips while disappearing.
While working on the question I stumbled up on this solution using filter. It is based on a answer to simular question.
filter: function (tooltipItems, data) {
var label = data.datasets[tooltipItems.datasetIndex].label;
if ((label == "Goal 1")||(label == "Goal 2")) {
return false;
} else {
return true;
}
}
Here is the code from my original question including this filter.
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [{
label: 'Count type 1',
data: [48, 33, 32, 35, 42, 38],
backgroundColor: 'transparent',
borderColor: 'rgba(255, 204, 0, 1)',
fillColor: 'rgba(255, 204, 0, 0.1)',
pointBorderColor: 'transparent',
pointBackgroundColor: 'rgba(255, 204, 0, 1)',
pointRadius: 4,
borderWidth: 2,
lineTension: 0.3
},
{
label: 'Goal 1',
data: [48.000, 47.040, 46.080, 45.120, 44.160, 43.200],
backgroundColor: 'transparent',
borderColor: 'rgba(0, 255, 0, 1)',
fillColor: 'transparent',
pointBorderColor: 'transparent',
pointRadius: 0,
borderWidth: 0.4,
lineTension: 0
},
{
label: 'Count type 2',
data: [24, 37, 30, 22, 29, 18],
backgroundColor: 'transparent',
borderColor: 'rgba(255, 0, 0, 1)',
fillColor: 'rgba(255, 0, 0, 0.1)',
pointBorderColor: 'transparent',
pointBackgroundColor: 'rgba(255, 0, 0, 1)',
pointRadius: 4,
borderWidth: 2,
lineTension: 0.3
},
{
label: 'Goal 2',
data: [24.000, 23.520, 23.040, 22.560, 22.080, 21.600],
backgroundColor: 'transparent',
borderColor: 'rgba(0, 255, 0, 1)',
pointBorderColor: 'transparent',
pointRadius: 0,
borderWidth: 0.4,
lineTension: 0
}
]
},
options: {
tooltips: {
enabled: true,
mode: 'index',
intersect: false,
filter: function(tooltipItems, data) {
var label = data.datasets[tooltipItems.datasetIndex].label;
if ((label == "Goal 1") || (label == "Goal 2")) {
return false;
} else {
return true;
}
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<canvas id="myChart"></canvas>
Final version (I hope). Shortly after my answer I stumbled upon this plugin which is exactly what I really was looking for.
https://github.com/chartjs/chartjs-plugin-annotation
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [{
label: 'Count type 1',
data: [48, 33, 32, 35, 42, 38],
backgroundColor: 'transparent',
borderColor: 'rgba(255, 204, 0, 1)',
fillColor: 'rgba(255, 204, 0, 0.1)',
pointBorderColor: 'transparent',
pointBackgroundColor: 'rgba(255, 204, 0, 1)',
pointRadius: 4,
borderWidth: 2,
lineTension: 0.3
},
{
label: 'Count type 2',
data: [24, 37, 30, 22, 29, 18],
backgroundColor: 'transparent',
borderColor: 'rgba(255, 0, 0, 1)',
fillColor: 'rgba(255, 0, 0, 0.1)',
pointBorderColor: 'transparent',
pointBackgroundColor: 'rgba(255, 0, 0, 1)',
pointRadius: 4,
borderWidth: 2,
lineTension: 0.3
}
]
},
options: {
responsive: true,
tooltips: {
enabled: true,
mode: 'index',
intersect: false,
},
annotation: {
annotations: [{
type: 'line',
mode: 'horizontal',
drawTime: 'afterDatasetsDraw',
id: 'a-line-1',
scaleID: 'y-axis-0',
value: 48,
endValue: 43,
borderColor: 'rgb(75, 192, 192)',
borderWidth: 2,
label: {
backgroundColor: 'rgba(255,204,0, 0.4)',
fontColor: 'rgba(0, 0, 0, 0.6 )',
fontSize: 12,
enabled: true,
content: 'Goal from 48 to 43',
yAdjust: -18,
xAdjust: 0,
}
},
{
type: 'line',
mode: 'horizontal',
drawTime: 'afterDatasetsDraw',
id: 'a-line-2',
scaleID: 'y-axis-0',
value: 24,
endValue: 21,
borderColor: 'rgb(75, 192, 192)',
borderWidth: 2,
label: {
backgroundColor: 'rgba(255,0,0,0.4)',
fontColor: 'rgba(255, 255, 255 )',
fontSize: 12,
enabled: true,
content: 'Goal from 24 to 21',
yAdjust: 14,
xAdjust: 0,
}
}]
},
scales: {
yAxes: [{
scaleLabel: {
display: true,
labelString: 'interface'
},
ticks: {
beginAtZero: true
}
}]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<script src="https://rawgit.com/chartjs/chartjs-plugin-annotation/master/chartjs-plugin-annotation.js"></script>
<canvas id="myChart"></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)
I have the following mock up of a bar chart. Pretty simple except I can't seem to get the font size on the X axis to increase. I am guessing I am doing something wrong with the hAxis or just using the wrong option.
<script src="Chart.Bundle.min.js" type="text/javascript"></script>
...
<canvas id="myChart" height="220" ></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Break','Lunch','Meeting','Aux Out','Aux In'],
datasets: [{
data: [20, 20, 20, 20, 20],
backgroundColor: [
'rgba(66, 244, 98, 0.9)',
'rgba(101, 3, 96, 0.9)',
'rgba(198, 192, 194, 0.9)',
'rgba(43, 136, 234, 0.9)',
'rgba(232, 11, 55, 0.9)'
],
borderColor: [
'rgba(57,214,86,1)',
'rgba(81, 2, 77, 1)',
'rgba(145, 140, 141, 1)',
'rgba(37, 118, 203, 1)',
'rgba(173, 8, 41, 1)'
],
borderWidth: 2
}]
},
options: {
responsive: true,
legend : {
display: false,
},
hAxis: {
textStyle: {
fontSize: 32
}
}
}
});
</script>
</div>
first, you're using chart.js not google charts
for chart.js, the x-axis label font size options are as follows...
scales: {
xAxes: [{
ticks: {
fontSize: 40
}
}]
}
see following working snippet...
$(document).ready(function() {
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Break','Lunch','Meeting','Aux Out','Aux In'],
datasets: [{
data: [20, 20, 20, 20, 20],
backgroundColor: [
'rgba(66, 244, 98, 0.9)',
'rgba(101, 3, 96, 0.9)',
'rgba(198, 192, 194, 0.9)',
'rgba(43, 136, 234, 0.9)',
'rgba(232, 11, 55, 0.9)'
],
borderColor: [
'rgba(57,214,86,1)',
'rgba(81, 2, 77, 1)',
'rgba(145, 140, 141, 1)',
'rgba(37, 118, 203, 1)',
'rgba(173, 8, 41, 1)'
],
borderWidth: 2
}]
},
options: {
responsive: true,
legend : {
display: false,
},
scales: {
xAxes: [{
ticks: {
fontSize: 18
}
}]
}
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="myChart"></canvas>
I need the line graph to start from the left y axis. Here is a link to JSFiddle. Would it be possible to somehow "hack" the line to start from there without messing up the bar graphs?
datasets: [{
type: 'line',
label: 'A',
yAxisID: 'A',
fill: false,
data: [60, 80, 90, 80, 80, 60, 50],
backgroundColor: 'rgba(255, 0, 0, 1)',
borderColor: 'rgba(255, 0, 0, 1)',
radius: 0
}
You can match it to a second x Axis that you hide:
V3 example:
var ctx = document.getElementById("canvas");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Mon', 'Tue', 'Wen', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [{
type: 'line',
label: 'A',
data: [60, 80, 90, 80, 80, 60, 50],
backgroundColor: 'rgba(255, 0, 0, 1)',
borderColor: 'rgba(255, 0, 0, 1)',
radius: 0,
xAxisID: 'secondX'
}, {
type: 'bar',
label: 'B',
yAxisID: 'yB',
data: [5, 2, 1, 3, 4, 5, 6],
backgroundColor: [
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)'
]
}]
},
options: {
scales: {
x: {},
secondX: {
axis: 'x',
offset: false,
display: false
},
y: {
type: 'linear',
position: 'left',
ticks: {
max: 100,
min: 0
}
},
yB: {
position: 'right',
ticks: {
max: 10,
min: 0
}
}
}
}
});
<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
V2 Example:
var ctx = document.getElementById("canvas");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Mon', 'Tue', 'Wen', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [{
type: 'line',
label: 'A',
yAxisID: 'A',
fill: false,
data: [60, 80, 90, 80, 80, 60, 50],
backgroundColor: 'rgba(255, 0, 0, 1)',
borderColor: 'rgba(255, 0, 0, 1)',
radius: 0,
xAxisID: 'second'
}, {
type: 'bar',
label: 'B',
yAxisID: 'B',
data: [5, 2, 1, 3, 4, 5, 6],
backgroundColor: [
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)',
'rgba(0, 0, 255, 0.5)'
]
}]
},
options: {
scales: {
xAxes: [{}, {
id: 'second',
display: false
}],
yAxes: [{
id: 'A',
type: 'linear',
position: 'left',
ticks: {
max: 100,
min: 0
}
}, {
id: 'B',
position: 'right',
ticks: {
max: 10,
min: 0
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.js"></script>
<canvas id="canvas"></canvas>