2 canvasjs chart in one pageproblem, - javascript

i tried to put 2 Canvasjs chart in one html page. i have included jquery, and it works when i put only one chart div, once i add second chart, it show error, only show up one chart.
I want to show 2 or more chart in a page, is it possible?
here's my code. thank you
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="canvas/js/jquery.canvasjs.min.js"></script>
<!FIRST JAVASCRIPT>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
data: [
{
type: "column",
dataPoints: [
{ x: 10, y: 10 },
{ x: 20, y: 15 },
{ x: 30, y: 25 },
{ x: 40, y: 30 },
{ x: 50, y: 28 }
]
}
]
});
chart.render();
}
</script>
<!SECOND JAVASCRIPT>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer2");
chart.options.axisY = { prefix: "$", suffix: "K" };
chart.options.title = { text: "Fruits sold in First & Second Quarter" };
var series1 = { //dataSeries - first quarter
type: "column",
name: "First Quarter",
showInLegend: true
};
var series2 = { //dataSeries - second quarter
type: "column",
name: "Second Quarter",
showInLegend: true
};
chart.options.data = [];
chart.options.data.push(series1);
chart.options.data.push(series2);
series1.dataPoints = [
{ label: "banana", y: 18 },
{ label: "orange", y: 29 },
{ label: "apple", y: 40 },
{ label: "mango", y: 34 },
{ label: "grape", y: 24 }
];
series2.dataPoints = [
{ label: "banana", y: 23 },
{ label: "orange", y: 33 },
{ label: "apple", y: 48 },
{ label: "mango", y: 37 },
{ label: "grape", y: 20 }
];
chart.render();
}
</script>
</head>
<body>
<!FIRST CHART SHOW>
<div id="chartContainer1" style="height: 500px; width: 50%;"></div>
<!SECOND CHART SHOW>
<div id="chartContainer2" style="height: 500px; width: 50%;"></div>
</body>
</html>

Firstly, you don't need two window.onload functions. The second onload function will override the first one. So just have one and include both the charts code in the one of them.
Also, the first chart being created requires an element with id as chartContainer which is not present in the DOM. Replace that with chartContainer1.
Replace
var chart = new CanvasJS.Chart("chartContainer", {...});
with
var chart = new CanvasJS.Chart("chartContainer1", {...});
Instead of using one variable chart for both the charts use two variables so that the variable is not overridden. Something like this
window.onload = function(){
var chart1 = new CanvasJS.Chart("chartContainer1", {
data: [{
type: "column",
dataPoints: [{
x: 10,
y: 10
}, {
x: 20,
y: 15
}, {
x: 30,
y: 25
}, {
x: 40,
y: 30
}, {
x: 50,
y: 28
}]
}]
});
chart1.render();
var chart2 = new CanvasJS.Chart("chartContainer2");
chart2.options.axisY = {
prefix: "$",
suffix: "K"
};
chart2.options.title = {
text: "Fruits sold in First & Second Quarter"
};
var series1 = { //dataSeries - first quarter
type: "column",
name: "First Quarter",
showInLegend: true
};
var series2 = { //dataSeries - second quarter
type: "column",
name: "Second Quarter",
showInLegend: true
};
chart2.options.data = [];
chart2.options.data.push(series1);
chart2.options.data.push(series2);
series1.dataPoints = [{
label: "banana",
y: 18
}, {
label: "orange",
y: 29
}, {
label: "apple",
y: 40
}, {
label: "mango",
y: 34
}, {
label: "grape",
y: 24
}];
series2.dataPoints = [{
label: "banana",
y: 23
}, {
label: "orange",
y: 33
}, {
label: "apple",
y: 48
}, {
label: "mango",
y: 37
}, {
label: "grape",
y: 20
}];
chart2.render();
};
Here is a demo http://jsbin.com/rocusuhevo/edit?html,js,output

Related

Custom Apexchart

I am trying to create a graph with Apexcharts that looks like below. You can ignore the 2 vertical lines as they are not necessary.
Looking at the examples that apexcharts have, the closest thing I have found is Stacked Bar Charts. Maybe there is something better and I missed? If so please let me know.
https://apexcharts.com/javascript-chart-demos/bar-charts/stacked/
The way the chart below behaves is I get an array of data such as this:
[3, 7, 21, 55, 32, 3, 7, 58, 38] // and so on. You will notice the numbers can duplicate.
To simply things I will use Book and pages as a reference. The X axis represents number of pages and Y axis represents number of books. So by looking at the image I posted you can see there are 22 books that have 100 or less pages. There are 2 books with greater than 100 but less than 300 pages and 1 book with more than 300 and less than 400 pages.
I am having a real hard time figuring out how to configure the stacked bar chart to display things in this manner. I am not looking for an answer on how to manipulate my data, but more of how to configure the settings of the graph in order to get the correct display.
I have tried several configurations to no avail. Any help on this is most appreciated!
For reference to show work, some of things I have tried:
series: [{
name: 'Range 1',
data: [{ y: 44, x: 100 }, { y: 55, x: 100 }, { y: 41, x: 100 }, { y: 37, x: 100 }, { y: 22, x: 100 }, { y: 43, x: 100 }, { y: 21, x: 100 }]
}, {
name: 'Range 2',
data: [{ y: 44, x: 200 }, { y: 55, x: 200 }, { y: 41, x: 200 }, { y: 37, x: 200 }, { y: 22, x: 200 }, { y: 43, x: 200 }, { y: 21, x: 200 }]
}]
series: [{
name: 'Range 1',
data: [{ x: 44, y: 100 }, { x: 55, y: 100 }, { x: 41, y: 100 }, { x: 37, y: 100 }, { x: 22, y: 100 }, { x: 43, y: 100 }, { x: 21, y: 100 }]
}, {
name: 'Range 2',
data: [{ x: 44, y: 200 }, { x: 55, y: 200 }, { x: 41, y: 200 }, { x: 37, y: 200 }, { x: 22, y: 200 }, { x: 43, y: 200 }, { x: 21, y: 200 }]
}]
series: [{
name: 'Range 1',
data: [44, 55, 41, 37, 22, 43, 21]
}, {
name: 'Range 2',
data: [53, 32, 33, 52, 13, 43, 32]
}]
One of the largest issues I'm finding is that I can't seem to control values on the X axis or to keep the bars same width.
Here is an example of how it comes out from one of the attempts.
Lastly, the first image I showed above is generated from a Histogram from google charts. My requirements were to move all the google charts to apex charts so I'm trying to find something in apex charts equivalent to do the job.
There are two things that I do not really understand in your question: your data and why you want a stacked bar chart.
If you need to put the number of pages on your xaxis and the number of books on your yaxis, then a basic bar chart should be enough. I give you an example below:
let options = {
series: [{
name: 'Series',
data: [22, 2, 2, 1, 0, 0, 2, 0]
}],
chart: {
type: 'bar',
height: 350
},
dataLabels: {
enabled: false
},
xaxis: {
categories: [0, 100, 200, 300, 400, 500, 600, 700],
labels: {
offsetX: -13
},
title: {
text: 'Number of pages',
offsetY: 100
}
},
yaxis: {
title: {
text: 'Number of books'
}
},
tooltip: {
custom: ({series, seriesIndex, dataPointIndex, w}) => {
return `<div class="arrow_box"><div>Book(s): <strong>${series[seriesIndex][dataPointIndex]}</strong></div><div>Pages: <strong>${w.globals.labels[dataPointIndex]}-${w.globals.labels[dataPointIndex] + 100}</strong></div>`;
}
}
};
let chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
.arrow_box {
padding: 10px;
}
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>
The trickiest part is the custom tooltip. I did this to put intervals in there instead of the category.
EDIT 1
Oops! I did not pay attention: my example above is not responsive (see labels). So maybe you could do something like that:
let options = {
series: [{
name: 'Series',
data: [22, 2, 2, 1, 0, 0, 2]
}],
chart: {
type: 'bar',
height: 350
},
dataLabels: {
enabled: false
},
xaxis: {
categories: ['0-100', '101-200', '201-300', '301-400', '401-500', '501-600', '601-700'],
title: {
text: 'Number of pages',
offsetY: 100
}
},
yaxis: {
title: {
text: 'Number of books'
}
},
responsive: [
{
breakpoint: 400,
options: {
xaxis: {
title: {
offsetY: 150
}
}
}
}
]
};
let chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>
This is not very elegant but I did not find a better solution.
EDIT 2
After reading your comment, I updated my example:
let options = {
series: [{
name: 'Sci-fi',
data: [44, 55, 41, 37, 22, 43, 21]
}, {
name: 'Fantasy',
data: [53, 32, 33, 52, 13, 43, 32]
}],
chart: {
type: 'bar',
height: 350,
stacked: true
},
dataLabels: {
enabled: false
},
xaxis: {
categories: ['0-100', '101-200', '201-300', '301-400', '401-500', '501-600', '601-700'],
title: {
text: 'Number of pages'
}
},
yaxis: {
title: {
text: 'Number of books'
}
}
};
let chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts#3.36.0"></script>
<div id="chart"></div>
EDIT 3
Using the analogy above, each stacked bar would show title of the book. As they are all different books.
If you want to do that, I think you will have to create one series for each book and just set one color to avoid getting an unreadable rainbow. But if you have a lot of books, you will most likely face performance issues.
You will find a better example below. It is not consistent because I randomized all series, but it seems closer to what you are trying to do.
function getAllSeries() {
let allSeries = [];
for (let i = 1; i <= 7; i++) {
let series = {};
series.name = `Book ${i}`;
series.data = [];
for (let j = 0; j < 7; j++) {
if ((Math.random() * 10) < 5) {
series.data.push(1);
} else {
series.data.push(null);
}
}
allSeries.push(series);
}
return allSeries;
}
let options = {
series: getAllSeries(),
chart: {
type: 'bar',
height: 350,
stacked: true
},
dataLabels: {
enabled: false
},
xaxis: {
categories: ['0-100', '101-200', '201-300', '301-400', '401-500', '501-600', '601-700'],
title: {
text: 'Number of pages'
}
},
yaxis: {
title: {
text: 'Number of books'
}
},
legend: {
show: false
},
colors: ['#269ffb'],
stroke: {
colors: ['#ffffff'],
width: 1
},
tooltip: {
custom: ({series, seriesIndex, dataPointIndex, w}) => {
return `<div class="arrow_box"><div>Name: <strong>${w.config.series[seriesIndex].name}</strong></div><div>Pages: <strong>${w.globals.labels[dataPointIndex]}</strong></div>`;
}
}
};
let chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
.arrow_box {
padding: 10px;
}
<script src="https://cdn.jsdelivr.net/npm/apexcharts#3.36.0"></script>
<div id="chart"></div>

How to adjust spaces between points in chart js?

I am trying to make a line chart by using chart.js. But I facing a problem. I want to control the space between points, but the chart.js makes it equal.
Here is my code:
<canvas id="myChart"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.js" integrity="sha512-OD9Gn6cAUQezuljS6411uRFr84pkrCtw23Hl5TYzmGyD0YcunJIPSBDzrV8EeCiFxGWWvtJOfVo5pOgB++Jsag==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
var ctx = document.getElementById("myChart");
var points = [1,1,9,9.3];
var Dates = ["Dec 29th", "jan 10th", "Feb 21st", "Feb 25th"];
var myChart = new Chart(ctx, {
type: "line",
data: {
labels: Dates,
datasets: [
{
label: "My chart",
data: points,
backgroundColor: "black",
borderColor: "blue",
borderWidth: 3,
fill: false,
lineTension: 0.4,
}
]
},
options: {
legend: {display: false},
scales: {
yAxes:[{
ticks: {
min:1,
max: 9.9,
callback: function(value, index, values) {
return '$' + value;
}
}
}],
},
elements: {
point:{
radius: 0
}
}
}
});
</script>
Here is the result of my code:
But I want the big space in middle like this:
How can I make the big space between point 3 and point4, please?
Can you use time on the x axis?
Below is an example
// "+" before (new Date(2021,11,29)) return miliseconds from 1970 year
const dataA = [
{x:+new Date(2021,11,29), y:1}, // { x: 1640732400000, y: 1},
{x:+new Date(2022,0,10), y:1}, // { x: 1641769200000, y: 1},
{x:+new Date(2022,1,21), y:9}, // { x: 1645398000000, y: 9},
{x:+new Date(2022,1,25), y:9.3}, // { x: 1645743600000, y: 9.3}
];
const cfgChart = {
type: 'line',
data: {
datasets: [
{
backgroundColor: '#74adf7',
borderColor: '#74adf7',
data: dataA,
label: 'A',
lineTension: 0.4,
},
],
},
options: {
animation: false,
parsing: false,
interaction: {
mode: 'index',
axis: 'x',
intersect: false,
},
scales: {
x: {
type: 'time',
},
},
},
};
const chart = new Chart(document.querySelector('#chart').getContext('2d'), cfgChart);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.3.1/luxon.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-adapter-luxon/1.1.0/chartjs-adapter-luxon.min.js"></script>
<div>
<canvas id="chart"></canvas>
</div>

Chart.js sum y values depending on time unit

New to Chart.js, I was wondering if there is a built in method to sum y values depending on time unit.
Asking here after a lot of search in the docs.
For now, the bar for March shows 20 and the bar for June shows 10.
I want to have 25 for March and 15 for June, so to sum y for the same month.
const ctx = document.getElementById("tests-chart")
const testsChart = new Chart(ctx, {
type: "bar",
data: {
datasets: [
{
label: 'Dataset 1',
data: [
{ x: "24/03/2022", y: 20 },
{ x: "25/03/2022", y: 5 },
{ x: "24/06/2022", y: 10 },
{ x: "25/06/2022", y: 5 },
],
backgroundColor: 'rgb(255, 99, 132)',
},
],
},
options: {
scales: {
x: {
type: "time",
time: {
parser: "dd/MM/yyyy",
unit: "month",
// Luxon format string
tooltipFormat: "MM",
round: 'month'
},
},
},
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/luxon#2.3.1/build/global/luxon.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon#1.1.0/dist/chartjs-adapter-luxon.min.js"></script>
<div>
<canvas id="tests-chart"></canvas>
</div>
You can manipulate your dataset as mentioned below and achieve your expected output.
const ctx = document.getElementById("tests-chart");
const data =[
{ x: "24/03/2022", y: 20 },
{ x: "25/03/2022", y: 5 },
{ x: "24/06/2022", y: 10 },
{ x: "25/06/2022", y: 5 }
];
let updatedData =[];
let tempDateCollection =[];
data.map((yData , index)=> {
const formatedDate = moment(yData.x, "DD/MM/YYYY").format('MMM/YYYY');
if(tempDateCollection.includes(formatedDate)){
const index = tempDateCollection.indexOf(formatedDate);
const element = updatedData[index];
updatedData[index] = {...element, y: element.y + yData.y}
} else{
tempDateCollection.push(formatedDate);
updatedData.push(yData);
}
})
const testsChart = new Chart(ctx, {
type: "bar",
data: {
datasets: [
{
label: 'Dataset 1',
data:updatedData,
backgroundColor: 'rgb(255, 99, 132)',
},
],
},
options: {
scales: {
x: {
type: "time",
time: {
parser: "dd/MM/yyyy",
unit: "month",
// Luxon format string
tooltipFormat: "MM",
round: 'month'
},
},
},
},
})
<script type = "text/JavaScript" src = " https://MomentJS.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/luxon#2.3.1/build/global/luxon.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon#1.1.0/dist/chartjs-adapter-luxon.min.js"></script>
<div>
<canvas id="tests-chart"></canvas>
</div>

Make a CanvasJS Chart using JSON data

I need to make this coding in a way where I can show JSON data in graph. but I don't know how to convert this coding in a way so that this graph will show JSON data. I am posting coding in here for your convenience.
<!DOCTYPE HTML>
<html>
<head>
<script>
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
theme: "dark2",
title:{
text: "MOVEMENT CATEGORY"
},
subtitles:[
{
text: "(STANDSTILL, ON FOOT or ON VEHICLE)",
},],
axisX:{
title: "TIME SLOT"
},
axisY:{
title:"Number of users(%)",
suffix: "%"
},
toolTip:
{
shared: true
},
data: [{
type: "stackedArea100",
name: "STANDSTILL",
showInLegend: "true",
yValueFormatString: "#,##0.##\"%\"",
dataPoints: [
{ y: 83, label: "6am - 10am" },
{ y: 51, label: "10am - 4pm" },
{ y: 64, label: "4pm - 8pm" },
{ y: 71, label: "8pm - 12am" },
{ y: 45, label: "12am - 6am" }
]
},
{
type: "stackedArea100",
name: "ON FOOT",
showInLegend: "true",
yValueFormatString: "#,##0.##\"%\"",
dataPoints: [
{ y: 20 , label: "6am - 10am" },
{ y: 30, label: "10am - 4pm" },
{ y: 24, label: "4pm - 8pm" },
{ y: 38, label: "8pm - 12am" },
{ y: 51, label: "12am - 6am" }
]
},
{
type: "stackedArea100",
name: "ON VEHICLE",
showInLegend: "true",
yValueFormatString: "#,##0.##\"%\"",
dataPoints: [
{ y: 11, label: "6am - 10am" },
{ y: 61, label: "10am - 4pm" },
{ y: 50, label: "4pm - 8pm" },
{ y: 23, label: "8pm - 12am" },
{ y: 31, label: "12am - 6am" }
]
}]
});
chart.render();
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 600px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</body>
</html>

How to show only first and last labels in CanvasJS

I need to show first and last labels only in CanvasJS. It's always showing all the labels but my requirement is to show only first and last. Is there any way out to do so?
You can use axisY labelFormatter to do so.
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Chart showing only First and Last Axis Labels",
},
axisY: {
tickColor: "transparent",
labelFormatter: function(e){
if(e.chart.axisY[0].minimum === e.value || e.chart.axisY[0].maximum === e.value)
return e.value;
return "";
}
},
data: [{
type: "column",
dataPoints: [
{ x: 10, y: 71 },
{ x: 20, y: 55 },
{ x: 30, y: 50 },
{ x: 40, y: 65 },
{ x: 50, y: 95 },
{ x: 60, y: 68 },
{ x: 70, y: 28 },
{ x: 80, y: 34 },
{ x: 90, y: 14 }
]
}]
});
chart.render();
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 260px; width: 100%;"></div>
You can also try hiding all axis-labels and add stripLines at the minimum and maximum.
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Chart showing only First and Last Axis Labels",
},
axisX: {
valueFormatString: "####"
},
axisY:[{
tickColor: "transparent",
labelFontColor: "transparent"
}],
axisY2:[{
tickColor: "transparent",
labelFontColor: "transparent"
}],
data: [
{
type: "column",
showInLegend: true,
name: "Axis Y-1",
xValueFormatString: "####",
dataPoints: [
{ x: 2006, y: 6 },
{ x: 2007, y: 2 },
{ x: 2008, y: 5 },
{ x: 2009, y: 7 },
{ x: 2010, y: 1 },
{ x: 2011, y: 5 },
{ x: 2012, y: 5 },
{ x: 2013, y: 2 },
{ x: 2014, y: 2 }
]
},
{
type: "column",
showInLegend: true,
axisYType: "secondary",
//axisYIndex: 0, //Defaults to Zero
name: "Axis Y2-1",
xValueFormatString: "####",
dataPoints: [
{ x: 2006, y: 12 },
{ x: 2007, y: 20 },
{ x: 2008, y: 28 },
{ x: 2009, y: 34 },
{ x: 2010, y: 24 },
{ x: 2011, y: 45 },
{ x: 2012, y: 15 },
{ x: 2013, y: 34 },
{ x: 2014, y: 22 }
]
}
]
});
chart.render();
addStripLine(chart);
function addStripLine(chart){
for(var i = 0; i < chart.axisY.length; i++){
min = chart.axisY[i].get("minimum");
max = chart.axisY[i].get("maximum");
chart.axisY[i].addTo("stripLines", {value: min, color: "black", label: min, labelFontColor: "black", labelBackgroundColor: "transparent", labelPlacement: "outside"});
chart.axisY[i].addTo("stripLines", {value: max, color: "black", label: max, labelFontColor: "black", labelBackgroundColor: "transparent", labelPlacement: "outside"});
}
for(var i = 0; i < chart.axisY2.length; i++){
min = chart.axisY2[i].get("minimum");
max = chart.axisY2[i].get("maximum");
chart.axisY2[i].addTo("stripLines", {value: min, color: "black", label: min, labelFontColor: "black", labelBackgroundColor: "transparent", labelPlacement: "outside"});
chart.axisY2[i].addTo("stripLines", {value: max, color: "black", label: max, labelFontColor: "black", labelBackgroundColor: "transparent", labelPlacement: "outside"});
}
}
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 260px; width: 100%;"></div>

Categories

Resources