i am trying to put 2 vertical lines on a chart.JS chart using the annotations plugin. i am using the following versions:
chart.js = 2.8.0
annotations plugin = 0.5.7
here's the JSFiddle
please see my code below:
var ann = ["4.35"];
var ann_labels = ["start"];
var annotations_array = ann.map(function(value, index) {
return {
type: 'line',
id: 'vline' + index,
mode: 'vertical',
scaleID: 'x-axis-0',
value: value,
borderColor: 'green',
borderWidth: 1,
label: {
enabled: true,
position: "bottom",
content: ann_labels
}
}
});
var ann2 = ["4.29"];
var ann_labels2 = ["stop"];
var annotations_array2 = ann2.map(function(value, index) {
return {
type: 'line',
id: 'vline2' + index,
mode: 'vertical',
scaleID: 'x-axis-0',
value: value,
borderColor: 'green',
borderWidth: 1,
label: {
enabled: true,
position: "top",
content: ann_labels2
}
}
});
var ctx = document.getElementById('test').getContext('2d');
var test = new Chart(ctx, {
type: 'line',
data: {
labels: ["1.44","4.03","4.35","3.99","3.58","3.75","4.29","5.02","5.95","6.65"],
datasets: [{
data: ["1", "2", "1", "2", "1", "2", "1", "2", "1", "2"],
yAxisID: 'A',
backgroundColor: [
'rgba(91, 192, 222, 0.1)',
],
borderColor: [
'rgba(0, 123, 255, 0.8)',
],
borderWidth: 1.3,
},
{
data: ["10", "11", "12","13","14","15","16","17",],
yAxisID: 'B',
backgroundColor: [
'rgba(255, 206, 86, 0.0)',
],
borderColor: [
'rgba(217, 83, 79, 0.6)',
],
borderWidth: 1.3,
}]
},
options: {
annotation: {
drawTime: 'afterDatasetsDraw',
annotations: annotations_array
},
maintainAspectRatio: true,
scales: {
yAxes: [{
id: 'A',
ticks: {
callback: function(value, index, values) {
return value + ' m';
},
reverse: true,
}
},
{
id: 'B',
position: 'right',
ticks: {
callback: function(value, index, values) {
return value + ' °C';
},
reverse: true,
}
}]
},
elements: {
point:{
radius: 0,
}
},
legend: {
position: 'bottom',
display: false,
},
}
});
however, i am unable to display both vertical lines (annotations_array and annotations_array2) at the same time.
everything works fine when i do this:
annotations: annotations_array
or this:
annotations: annotations_array2
but when i try to print both arrays, it doesnt work:
annotations: annotations_array, annotations_array2
I have also tried this without any luck:
annotations: [{annotations_array},{annotations_array2}]
does anyone know what am i doing wrong?
Thanks in advance!
You have to provide both annotations as object in 1 array, not an array containing objects containing arrays, see example:
var ann = ["4.35", "4.29"];
var ann_labels = ["start", "stop"];
var annotations_array = ann.map(function(value, index) {
return {
type: 'line',
id: 'vline' + index,
mode: 'vertical',
scaleID: 'x-axis-0',
value: value,
borderColor: 'green',
borderWidth: 1,
label: {
enabled: true,
position: "bottom",
content: ann_labels[index]
}
}
});
var ctx = document.getElementById('test').getContext('2d');
var test = new Chart(ctx, {
type: 'line',
data: {
labels: ["1.44", "4.03", "4.35", "3.99", "3.58", "3.75", "4.29", "5.02", "5.95", "6.65"],
datasets: [{
data: ["1", "2", "1", "2", "1", "2", "1", "2", "1", "2"],
yAxisID: 'A',
backgroundColor: [
'rgba(91, 192, 222, 0.1)',
],
borderColor: [
'rgba(0, 123, 255, 0.8)',
],
borderWidth: 1.3,
},
{
data: ["10", "11", "12", "13", "14", "15", "16", "17", ],
yAxisID: 'B',
backgroundColor: [
'rgba(255, 206, 86, 0.0)',
],
borderColor: [
'rgba(217, 83, 79, 0.6)',
],
borderWidth: 1.3,
}
]
},
options: {
annotation: {
drawTime: 'afterDatasetsDraw',
annotations: annotations_array
},
maintainAspectRatio: true,
scales: {
yAxes: [{
id: 'A',
ticks: {
callback: function(value, index, values) {
return value + ' m';
},
reverse: true,
}
},
{
id: 'B',
position: 'right',
ticks: {
callback: function(value, index, values) {
return value + ' °C';
},
reverse: true,
}
}
]
},
elements: {
point: {
radius: 0,
}
},
legend: {
position: 'bottom',
display: false,
},
}
});
<h3 class="card-text"><canvas id="test"></canvas></h3>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/0.5.7/chartjs-plugin-annotation.min.js"></script>
Fiddle: https://jsfiddle.net/Leelenaleee/6Ltycqfh/7/
Related
I would like to change the direction of scrolling on a horizontal scrollable bar chart in such way scrolling start from right to left (RTL). I'm not sure if it is supported or not. in case, it is not, then is there a way to programmatically scroll to the far right of the chart upon loading to achieve the desired outcome.
const chartsoptions = {
type: 'bar',
data: {
labels: ["1", "2", "3", "4", "5", "6",],
datasets: [{
label: 'OFF',
data: [1, 2, 3, 4, 5, 6],
backgroundColor: [ 'rgba(255, 99, 132, 0.4)', ],
borderColor: [ 'rgb(255, 99, 132)', ],
borderWidth: 1
},{
label: 'On',
data: [6, 5, 4, 3, 2, 1],
backgroundColor: [ 'rgba(75, 192, 192, 0.4)', ],
borderColor: ['rgb(75, 192, 192)', ],
borderWidth: 1
}]
},
options: {
plugins: {
legend: {
display: true,
labels: {
font: {
size: 20,
weight: "bold",
},
}
},
datalabels: {
anchor: 'center',
clamp: true,
display: true,
textAlign: 'center',
borderRadius: 3,
color: "black",
clip: true,
font: {
size: 20,
weight: "bold",
},
},
zoom: {
zoom: { wheel: { enabled: false, }, mode: 'x', },
pan: { enabled: true, mode: 'x', },
limits: { x: { minRange: 3 }, },
}
},
scales: {
x: { ticks: { font: { size: 20, weight: "bold" }, } },
y: { ticks: { font: { size: 20, weight: "bold" }, } },
}
}
}
const ctx = document.getElementById('dailyonoff').getContext('2d');
document.getElementById('dailyonoff').style.backgroundColor = "white";
const chart = new Chart(ctx, chartsoptions);
setTimeout(() => {
chart.zoom(2);
chart.pan({
x: Number.MAX_SAFE_INTEGER
}, undefined, 'default');
}, 10)
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.9.1/dist/chart.min.js" integrity="sha256-+8RZJua0aEWg+QVVKg4LEzEEm/8RFez5Tb4JBNiV5xA=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.1.1/chartjs-plugin-zoom.js"></script>
</head>
<body>
<canvas id="dailyonoff" class="onoff" width="300" height="200" ></canvas>
</body>
</html>
I found the solution to navigate (pan) to the end of the graph. just replace:
MAX_SAFE_INTEGER
with:
MIN_SAFE_INTEGER
Is it possible to select a column in a stack bar chart with a colored border? Like this
I started from here:
https://jsfiddle.net/sdfx/hwx9awgn/
// Return with commas in between
var numberWithCommas = function(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};
var dataPack1 = [40, 47, 44, 38, 27, 31, 25];
var dataPack2 = [10, 12, 7, 5, 4, 6, 8];
var dataPack3 = [17, 11, 22, 18, 12, 7, 5];
var dates = ["SN 1.0.1", "SN 1.0.2", "SN 1.0.3", "SN 1.0.4", "SN 1.0.5", "SN 2.0.0", "SN 2.0.1"];
// Chart.defaults.global.elements.rectangle.backgroundColor = '#FF0000';
var bar_ctx = document.getElementById('bar-chart');
var bar_chart = new Chart(bar_ctx, {
type: 'bar',
data: {
labels: dates,
datasets: [{
label: 'Bad Style',
data: dataPack1,
backgroundColor: "#512DA8",
hoverBackgroundColor: "#7E57C2",
hoverBorderWidth: 0
}, {
label: 'Warning',
data: dataPack2,
backgroundColor: "#FFA000",
hoverBackgroundColor: "#FFCA28",
hoverBorderWidth: 0
}, {
label: 'Error',
data: dataPack3,
backgroundColor: "#D32F2F",
hoverBackgroundColor: "#EF5350",
hoverBorderWidth: 0
}, ]
},
options: {
animation: {
duration: 10,
},
tooltips: {
mode: 'label',
callbacks: {
label: function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].label + ": " + numberWithCommas(tooltipItem.yLabel);
}
}
},
scales: {
xAxes: [{
stacked: true,
gridLines: {
display: false
},
}],
yAxes: [{
stacked: true,
ticks: {
callback: function(value) {
return numberWithCommas(value);
},
},
}],
}, // scales legend: {display: true} } // options } );
Yes what you can do is in the onClick as second argument you get an array with all the active elements. So what you can do is loop over each dataset in your chart and see if the index matches one of the list with active elements.
If this is the case you give it a borderWidth of 1, else you put it to 0. After you did this you call chart variable.update();
To make this work you need to remove the hoverBorderWidth of all datasets and give all datasets a borderColor of yellow
Use attribute borderColor with an array and borderWith with and object.
datasets: [
{
label: 'Bad Style',
data: dataPack1,
backgroundColor: "#512DA8",
borderColor: [
'rgb(243, 255, 51)',
'rgb(81,45,168)',
'rgb(243, 255, 51)',
'rgb(81,45,168)',
'rgb(81,45,168)',
'rgb(81,45,168)',
'rgb(81,45,168)',
],
borderWidth: {
top: 0,
right: 4,
bottom: 0,
left: 4
},
},
rgb(243, 255, 51) is yellow color.
To change the color, try this:
var borderColor = [
'rgb(81,45,168)',
'rgb(81,45,168)',
'rgb(81,45,168)',
'rgb(81,45,168)',
'rgb(81,45,168)',
'rgb(81,45,168)',
'rgb(81,45,168)',
];
var bar_ctx = document.getElementById('bar-chart');
var bar_chart = new Chart(bar_ctx, {
type: 'bar',
data: {
labels: dates,
datasets: [
{
label: 'Bad Style',
data: dataPack1,
backgroundColor: "#512DA8",
hoverBackgroundColor: "#7E57C2",
hoverBorderWidth: 0,
borderColor: borderColor,
borderWidth: '4',
},
{
label: 'Warning',
data: dataPack2,
backgroundColor: "#FFA000",
hoverBackgroundColor: "#FFCA28",
hoverBorderWidth: 0,
borderColor: borderColor,
borderWidth: '4',
},
{
label: 'Error',
data: dataPack3,
backgroundColor: "#D32F2F",
hoverBackgroundColor: "#EF5350",
hoverBorderWidth: 0,
borderColor: borderColor,
borderWidth: '4',
},
]
},
options: {
onClick: function(e){
var element = this.getElementAtEvent(e);
borderColor[element[0]._index] = 'rgb(244,140,4)';
this.update();
},
animation: {
duration: 10,
},
tooltips: {
mode: 'label',
callbacks: {
label: function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].label + ": " + numberWithCommas(tooltipItem.yLabel);
}
}
},
scales: {
xAxes: [{
stacked: true,
gridLines: { display: false },
}],
yAxes: [{
stacked: true,
ticks: {
callback: function(value) { return numberWithCommas(value); },
},
}],
}, // scales
legend: {display: true}
} // options
}
);
I'm new using ApexChart and I am having issue with a bar chart. I create the ApexChart, but the columns does not look aligned.
var options777 = {
chart: {
id: 'test',
height: 350,
type: 'bar'
},
plotOptions: {
bar: {
columnWidth: '50%'
}
},
series: [{
name: 'Eligibility',
data: [ 438, 360, 171, 322, 248, 190, 121, 206, 3 ]
}],
dataLabels: {
enabled: false
},
stroke: {
width: 2
},
grid: {
row: {
colors: ['#fff', '#f2f2f2']
}
},
xaxis: {
labels: {
rotate: -45
},
categories: [ "2020-04-27", "2020-04-22", "2020-04-20", "2020-04-24", "2020-04-23", "2020-04-28", "2020-04-25", "2020-04-21", "2020-04-19" ],
tickPlacement: 'on',
type: 'datetime'
},
yaxis: {
title: {
text: 'Eligibility',
},
},
fill: {
type: 'gradient',
gradient: {
shade: 'light',
type: "horizontal",
shadeIntensity: 0.25,
gradientToColors: undefined,
inverseColors: true,
opacityFrom: 0.85,
opacityTo: 0.85,
stops: [50, 0, 100]
},
}
};
var chart777 = new ApexCharts(
document.querySelector("#myChart"),
options777
);
chart777.render();
When the chart is rendered it looks like the image below. Why are the columns like that? Shouldn't it be one beside another?
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 create a line chart with two datasets, each with its own Y scale / axis (one to the left, one to the right of the graph) using Chart.js.
This is my code (jsfiddle):
var canvas = document.getElementById('chart');
new Chart(canvas, {
type: 'line',
data: {
labels: [ '1', '2', '3', '4', '5' ],
datasets: [
{
label: 'A',
yAxesGroup: 'A',
data: [ 100, 96, 84, 76, 69 ]
},
{
label: 'B',
yAxesGroup: 'B',
data: [ 1, 1, 1, 1, 0 ]
}
]
},
options: {
yAxes: [
{
name: 'A',
type: 'linear',
position: 'left',
scalePositionLeft: true
},
{
name: 'B',
type: 'linear',
position: 'right',
scalePositionLeft: false,
min: 0,
max: 1
}
]
}
});
However, the second axis is not visible and the second dataset is still scaled exactly as the first (0 to 100 instead of 0 to 1). What do I need to change?
For ChartJs 2.x only a couple changes need to be made (it looks like you have tried to combine 2.x options with the multi-axes options from my fork?),
The yAxes field needs to be in a scales object
the yAxis is referenced by id not name.
For the scale steps/size you just need to wrap these options in a ticks object.
No need forscalePositionLeft this is covered by position
Example:
var canvas = document.getElementById('chart');
new Chart(canvas, {
type: 'line',
data: {
labels: ['1', '2', '3', '4', '5'],
datasets: [{
label: 'A',
yAxisID: 'A',
data: [100, 96, 84, 76, 69]
}, {
label: 'B',
yAxisID: 'B',
data: [1, 1, 1, 1, 0]
}]
},
options: {
scales: {
yAxes: [{
id: 'A',
type: 'linear',
position: 'left',
}, {
id: 'B',
type: 'linear',
position: 'right',
ticks: {
max: 1,
min: 0
}
}]
}
}
});
fiddle example
The accepted answer no longer works as of 3.5, and the cause is listed as part of the breaking changes for 3.X (See 3.x Migration Guide)
The updated code below changes the scales property, from scales: {yScales: [...]} to scales: {[id]: {[options]}} , and also adds fill: true, (Was changed at 3.X from defaulting to true) and tension: 0.4 (The example provided before does have smooth curves, and seems like it was an undocumented "breaking" change)
var canvas = document.getElementById('myChart');
new Chart(canvas, {
type: 'line',
data: {
labels: ['1', '2', '3', '4', '5'],
datasets: [{
label: 'A',
yAxisID: 'A',
data: [100, 96, 84, 76, 69],
fill: true,
tension: 0.4
}, {
label: 'B',
yAxisID: 'B',
data: [1, 1, 1, 1, 0],
fill: true,
tension: 0.4
}]
},
options: {
scales: {
A: {
type: 'linear',
position: 'left',
},
B: {
type: 'linear',
position: 'right',
ticks: {
max: 1,
min: 0
}
}
}
}
});
This solution is working in react.
// "chart.js": "^2.9.4"
// "react-chartjs-2": "^2.11.1"
const lineChartData = {
data: {
labels: ['1', '2', '3', '4', '5', '6'],
datasets: [
{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
fill: false,
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgba(255, 99, 132, 0.2)',
},
{
label: '# of Votes',
data: [19, 9, 2, 1, 1, 21],
fill: false,
backgroundColor: 'rgb(122, 99, 255)',
borderColor: 'rgba(102, 99, 255, 0.2)',
}
],
},
options: {
scales: {
yAxes: [
{
type: 'linear',
display: true,
position: 'left',
ticks: {
beginAtZero: true,
},
},
{
type: 'linear',
display: true,
position: 'left',
ticks: {
beginAtZero: true,
},
},
],
},
}
}
<Line
data={lineChartData.data}
options={lineChartData.options}
height={30}
width={80}
options={{ maintainAspectRatio: true }}
/>