Related
I am trying to create a line chart that presents score level from 1-100.
Line is static and needs to be curved
but the dot on the chart is dynamic value and by that it changes its location along the existing line.
First I was thinking to add additional data that represents only the dot itself, but Y(height) is unknown.
Second attempt led me to create a second line that crosses / intersects the first one in hope of finding intersection point and making it a dot.
Unfortunately, I couldn't find a way to locate intersection.
This is expected result.
new Chart(
document.getElementById('lineChart'), {
type: 'line',
data: {
datasets: [
{
data: [
{
x: 70, y: 0,
},
{
x: 70, y: 100,
}],
fill: false,
borderColor: 'red',
showLine:true,
},
{
data: [
{
x: 0, y: 2,
},
{
x: 25, y: 10,
},
{
x: 50, y: 50,
},
{
x: 80, y: 90,
},
{
x: 100, y: 98,
}],
startWithZero: true,
fill: false,
lineTension: 0.3,
borderColor: 'blue',
}
]
},
options: {
bezierCurve : true,
lineTension: 0.3,
tooltips: {
mode: 'intersect'
},
scales: {
xAxes: [{
type: 'linear',
ticks: {
min: 0, //minimum tick
max: 100, //maximum tick
},
}],
yAxes: [{
ticks: {
bezierCurve : true,
min: 0, //minimum tick
max: 100, //maximum tick
},
bezierCurve : true,
type: 'linear',
lineTension: 0.3,
scaleLabel: {
lineTension: 0.1,
display: true,
}
}]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<body>
<div style="width: 750px; height: 250px; margin: 0 auto;">
<canvas style="width: 750px; height: 250px" id="lineChart"></canvas>
</div>
</body>
You can check snippet in order to see example and how far I got.
Can you try to create dynamic values
const lineData = [
{ x: 0, y: 2 },
{ x: 10, y: 3 },
{ x: 20, y: 10 },
{ x: 30, y: 20 },
{ x: 40, y: 35 },
{ x: 50, y: 50 },
{ x: 60, y: 65 },
{ x: 70, y: 80 },
{ x: 80, y: 90 },
{ x: 90, y: 97 },
{ x: 100, y: 98 },
];
const xValue = 70;
let key = Math.floor(xValue / 10);
let diff = (lineData[key + 1].y - lineData[key].y) / 10;
let toAdd = (xValue - lineData[key].x) * diff;
const yValue = lineData[key].y + toAdd;
And include dynamic values in chartJs code
new Chart(
document.getElementById('lineChart'), {
type: 'line',
data: {
datasets: [
{
data: lineData,
startWithZero: true,
fill: false,
lineTension: 0.3,
borderColor: 'blue',
}
]
},
options: {
bezierCurve : true,
lineTension: 0.3,
tooltips: {
mode: 'intersect'
},
scales: {
xAxes: [{
type: 'linear',
ticks: {
min: 0, //minimum tick
max: 100, //maximum tick
},
}],
yAxes: [{
ticks: {
bezierCurve : true,
min: 0, //minimum tick
max: 100, //maximum tick
},
bezierCurve : true,
type: 'linear',
lineTension: 0.3,
scaleLabel: {
lineTension: 0.1,
display: true,
}
}]
}
}
})
const lineData = [
{ x: 0, y: 2 },
{ x: 10, y: 3 },
{ x: 20, y: 10 },
{ x: 30, y: 20 },
{ x: 40, y: 35 },
{ x: 50, y: 50 },
{ x: 60, y: 65 },
{ x: 70, y: 80 },
{ x: 80, y: 90 },
{ x: 90, y: 97 },
{ x: 100, y: 98 },
];
const xValue = 70;
let key = Math.floor(xValue / 10);
let diff = (lineData[key + 1].y - lineData[key].y) / 10;
let toAdd = (xValue - lineData[key].x) * diff;
const yValue = lineData[key].y + toAdd;
new Chart(
document.getElementById('lineChart'), {
type: 'line',
data: {
datasets: [
{
data: lineData,
startWithZero: true,
fill: false,
lineTension: 0.3,
borderColor: 'blue',
}
]
},
options: {
bezierCurve : true,
lineTension: 0.3,
tooltips: {
mode: 'intersect'
},
scales: {
xAxes: [{
type: 'linear',
ticks: {
min: 0, //minimum tick
max: 100, //maximum tick
},
}],
yAxes: [{
ticks: {
bezierCurve : true,
min: 0, //minimum tick
max: 100, //maximum tick
},
bezierCurve : true,
type: 'linear',
lineTension: 0.3,
scaleLabel: {
lineTension: 0.1,
display: true,
}
}]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<body>
<div style="width: 750px; height: 250px; margin: 0 auto;">
<canvas style="width: 750px; height: 250px" id="lineChart"></canvas>
</div>
</body>
The question related to CanvasJS, but probably any expert in pure javascript could help.
I need a button to hide/unhide all elements in canvasjs graph.
There is a working code that can hide element using array index:
chart.options.data[0].visible = !chart.options.data[0].visible;
I'm trying to go through array, but it doesn't work, obviously my code is wrong:
chart.options.data.forEach(visible = !visible);
How should I fix it?
The full code snippet is:
var chart = new CanvasJS.Chart("chartContainer",
{
title:{
text: "Test Button to Hide All Series"
},
legend: {
cursor: "pointer",
itemclick: function (e) {
//console.log("legend click: " + e.dataPointIndex);
//console.log(e);
if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
e.chart.render();
}
},
data: [
{
showInLegend: true,
type: "line",
dataPoints: [
{ x: 10, y: 5 },
{ x: 20, y: 9},
{ x: 30, y: 17 },
{ x: 40, y: 32 },
{ x: 50, y: 22 },
{ x: 60, y: 14 },
{ x: 70, y: 25 },
{ x: 80, y: 18 },
{ x: 90, y: 20}
]
},
{
showInLegend: true,
type: "line",
dataPoints: [
{ x: 10, y: 31 },
{ x: 20, y: 35},
{ x: 30, y: 30 },
{ x: 40, y: 35 },
{ x: 50, y: 35 },
{ x: 60, y: 38 },
{ x: 70, y: 38 },
{ x: 80, y: 34 },
{ x: 90, y: 44}
]
},
{
showInLegend: true,
type: "line",
dataPoints: [
{ x: 10, y: 25 },
{ x: 20, y: 30},
{ x: 30, y: 20 },
{ x: 40, y: 45 },
{ x: 50, y: 30 },
{ x: 60, y: 10 },
{ x: 70, y: 15 },
{ x: 80, y: 18 },
{ x: 90, y: 20}
]
}
]
});
chart.render();
document.getElementById("showAllSeries").onclick = function(){
//Works for a single element using index:
chart.options.data[0].visible = !chart.options.data[0].visible;
//Doesn't work, need to modify
//chart.options.data.forEach(visible = !visible);
chart.render();
};
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<br/>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
<center><button id= "showAllSeries" style= "margin: 10px;">Show/Hide All series</button></center>
UP:
Found solution with for loop:
for (var i = 0; i < chart.options.data.length; i++) {
chart.options.data[i].visible = !chart.options.data[i].visible;
}
But still interesting how should it work with foreach
forEach is an Array method that you can use to execute a function on each element in an array. On the other hand for is a loop that is more flexible.
In your case, you can hide all dataSeries onclick of button either using for or forEach. Check the code below:
var chart = new CanvasJS.Chart("chartContainer", {
title:{
text: "Test Button to Hide All Series"
},
legend: {
cursor: "pointer",
itemclick: function (e) {
if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
e.chart.render();
}
},
data: [
{
showInLegend: true,
type: "line",
dataPoints: [
{ x: 10, y: 5 },
{ x: 20, y: 9 },
{ x: 30, y: 17 },
{ x: 40, y: 32 },
{ x: 50, y: 22 },
{ x: 60, y: 14 },
{ x: 70, y: 25 },
{ x: 80, y: 18 },
{ x: 90, y: 20 }
]
},
{
showInLegend: true,
type: "line",
dataPoints: [
{ x: 10, y: 31 },
{ x: 20, y: 35 },
{ x: 30, y: 30 },
{ x: 40, y: 35 },
{ x: 50, y: 35 },
{ x: 60, y: 38 },
{ x: 70, y: 38 },
{ x: 80, y: 34 },
{ x: 90, y: 44 }
]
},
{
showInLegend: true,
type: "line",
dataPoints: [
{ x: 10, y: 25 },
{ x: 20, y: 30 },
{ x: 30, y: 20 },
{ x: 40, y: 45 },
{ x: 50, y: 30 },
{ x: 60, y: 10 },
{ x: 70, y: 15 },
{ x: 80, y: 18 },
{ x: 90, y: 20 }
]
}
]
});
chart.render();
document.getElementById("showAllSeries").onclick = function(){
chart.options.data.forEach(function(dataSeries) {
if (typeof (dataSeries.visible) === "undefined" || dataSeries.visible) {
dataSeries.visible = false;
} else {
dataSeries.visible = true;
}
});
/*var dataSeries;
for(var i = 0; i < chart.data.length; i++){
dataSeries = chart.options.data[i];
if (typeof (dataSeries.visible) === "undefined" || dataSeries.visible) {
dataSeries.visible = false;
} else {
dataSeries.visible = true;
}
}*/
chart.render();
};
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 260px; width: 100%;"></div>
<center><button id= "showAllSeries" style= "margin: 10px;">Show/Hide All series</button></center>
Thanks to Vishwas for detailed answer. Generally - yes, both for & forEach are fine usable here. I will mark it as correct, but it helped me to get more concise solution using forEach that I expected:
document.getElementById(""showAllSeries"").onclick = function(){
chart.options.data.forEach(function(dataSeries) {
dataSeries.visible = !dataSeries.visible })
chart.render();
};
Will leave it here for a history also:
var chart = new CanvasJS.Chart("chartContainer",
{
title:{
text: "Test Button to Hide All Series"
},
legend: {
cursor: "pointer",
itemclick: function (e) {
//console.log("legend click: " + e.dataPointIndex);
//console.log(e);
if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
e.chart.render();
}
},
data: [
{
showInLegend: true,
type: "line",
dataPoints: [
{ x: 10, y: 5 },
{ x: 20, y: 9},
{ x: 30, y: 17 },
{ x: 40, y: 32 },
{ x: 50, y: 22 },
{ x: 60, y: 14 },
{ x: 70, y: 25 },
{ x: 80, y: 18 },
{ x: 90, y: 20}
]
},
{
showInLegend: true,
type: "line",
dataPoints: [
{ x: 10, y: 31 },
{ x: 20, y: 35},
{ x: 30, y: 30 },
{ x: 40, y: 35 },
{ x: 50, y: 35 },
{ x: 60, y: 38 },
{ x: 70, y: 38 },
{ x: 80, y: 34 },
{ x: 90, y: 44}
]
},
{
showInLegend: true,
type: "line",
dataPoints: [
{ x: 10, y: 25 },
{ x: 20, y: 30},
{ x: 30, y: 20 },
{ x: 40, y: 45 },
{ x: 50, y: 30 },
{ x: 60, y: 10 },
{ x: 70, y: 15 },
{ x: 80, y: 18 },
{ x: 90, y: 20}
]
}
]
});
chart.render();
document.getElementById("showAllSeries").onclick=function(){
chart.options.data.forEach(function(dataSeries){
dataSeries.visible = !dataSeries.visible
})
chart.render();
};
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<br/>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
<center><button id= "showAllSeries" style= "margin: 10px;">Show/Hide All series</button></center>
<html>
<head>
</head>
<body>
<script type="text/javascript" src="assets/js/canvasjs.min1.js"></script>
<script type="text/javascript">
window.onload ={
var chart = new CanvasJS.Chart("chartContainer",
{
animationEnabled: true,
legend: {
verticalAlign: "bottom",
horizontalAlign: "center"
},
theme: "theme1",
data: [
{
type: "pie",
indexLabelFontFamily: "Garamond",
indexLabelFontSize: 20,
indexLabelFontWeight: "bold",
startAngle:0,
indexLabelFontColor: "MistyRose",
indexLabelLineColor: "darkgrey",
indexLabelPlacement: "inside",
toolTipContent: "{name}: {y}hrs",
showInLegend: true,
indexLabel: "#percent%",
dataPoints: [
{ y: 52, name: "Time At Work", legendMarkerType: "triangle"},
{ y: 44, name: "Time At Home", legendMarkerType: "square"},
{ y: 12, name: "Time Spent Out", legendMarkerType: "circle"}
]
}
]
});
chart.render();
}
</script>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer2",
{
title:{
text: "Bar chart"
},
data: [
{
type: "bar",
dataPoints: [
{ x: 10, y: 90, label:"Gulam" },
{ x: 20, y: 70, label:"Husain" },
{ x: 30, y: 50, label:"Shubhankar" },
{ x: 40, y: 60, label:"Banana" },
{ x: 50, y: 20, label:"Pineapple" },
{ x: 60, y: 30, label:"Pears" },
{ x: 70, y: 35, label:"Grapes" },
{ x: 80, y: 40, label:"Lychee" },
{ x: 90, y: 30, label:"Jackfruit" }
]
}
]
});
chart.render();
}
</script>
<!-- panel body -->
<div class="panel-body">
<div id="chartContainer" style="height:400px; width: 100%;"></div>
</div>
<!-- panel body -->
<div class="panel-body">
<div id="chartContainer2" style="height: 400px; width: 100%;"></div>
</div>
</body>
</html>
i have put two codes one for pie chart and another for bar graph but those two graphs cannot be displayed simultaneously? why? is there any problem with the code only bar graph is displaying pie chart is not displaying.
First add function() after the window.onload = code
Then you don't want two window.onload events, so I combined your two onload scripts to be one as show below.
<html>
<head>
</head>
<body>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.min.js"></script>
<script type="text/javascript">
window.onload = function(){
var chart = new CanvasJS.Chart("chartContainer",
{
animationEnabled: true,
legend: {
verticalAlign: "bottom",
horizontalAlign: "center"
},
theme: "theme1",
data: [
{
type: "pie",
indexLabelFontFamily: "Garamond",
indexLabelFontSize: 20,
indexLabelFontWeight: "bold",
startAngle:0,
indexLabelFontColor: "MistyRose",
indexLabelLineColor: "darkgrey",
indexLabelPlacement: "inside",
toolTipContent: "{name}: {y}hrs",
showInLegend: true,
indexLabel: "#percent%",
dataPoints: [
{ y: 52, name: "Time At Work", legendMarkerType: "triangle"},
{ y: 44, name: "Time At Home", legendMarkerType: "square"},
{ y: 12, name: "Time Spent Out", legendMarkerType: "circle"}
]
}
]
});
chart.render();
chart = new CanvasJS.Chart("chartContainer2",
{
title:{
text: "Bar chart"
},
data: [
{
type: "bar",
dataPoints: [
{ x: 10, y: 90, label:"Gulam" },
{ x: 20, y: 70, label:"Husain" },
{ x: 30, y: 50, label:"Shubhankar" },
{ x: 40, y: 60, label:"Banana" },
{ x: 50, y: 20, label:"Pineapple" },
{ x: 60, y: 30, label:"Pears" },
{ x: 70, y: 35, label:"Grapes" },
{ x: 80, y: 40, label:"Lychee" },
{ x: 90, y: 30, label:"Jackfruit" }
]
}
]
});
chart.render();
}
</script>
<!-- panel body -->
<div class="panel-body">
<div id="chartContainer" style="height:400px; width: 100%;"></div>
</div>
<!-- panel body -->
<div class="panel-body">
<div id="chartContainer2" style="height: 400px; width: 100%;"></div>
</div>
</body>
</html>
One window.onload function is overwriting the other.
And in the first instance, window.onload ={ should be this window.onload = function() {.
It would however, be better to structure your page correctly and include the scripts at the bottom of the page. This means you can do away with the onload check altogether:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Graphs and ting</title>
</head>
<body>
<!-- panel body -->
<div class="panel-body">
<div id="chartContainer" style="height:400px; width: 100%;"></div>
</div>
<!-- panel body -->
<div class="panel-body">
<div id="chartContainer2" style="height: 400px; width: 100%;"></div>
</div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.min.js"></script>
<script type="text/javascript">
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
legend: {
verticalAlign: "bottom",
horizontalAlign: "center"
},
theme: "theme1",
data: [{
type: "pie",
indexLabelFontFamily: "Garamond",
indexLabelFontSize: 20,
indexLabelFontWeight: "bold",
startAngle:0,
indexLabelFontColor: "MistyRose",
indexLabelLineColor: "darkgrey",
indexLabelPlacement: "inside",
toolTipContent: "{name}: {y}hrs",
showInLegend: true,
indexLabel: "#percent%",
dataPoints: [
{ y: 52, name: "Time At Work", legendMarkerType: "triangle"},
{ y: 44, name: "Time At Home", legendMarkerType: "square"},
{ y: 12, name: "Time Spent Out", legendMarkerType: "circle"}
]
}]
});
chart.render();
var chart = new CanvasJS.Chart("chartContainer2", {
title:{
text: "Bar chart"
},
data: [{
type: "bar",
dataPoints: [
{ x: 10, y: 90, label:"Gulam" },
{ x: 20, y: 70, label:"Husain" },
{ x: 30, y: 50, label:"Shubhankar" },
{ x: 40, y: 60, label:"Banana" },
{ x: 50, y: 20, label:"Pineapple" },
{ x: 60, y: 30, label:"Pears" },
{ x: 70, y: 35, label:"Grapes" },
{ x: 80, y: 40, label:"Lychee" },
{ x: 90, y: 30, label:"Jackfruit" }
]
}]
});
chart.render();
</script>
</body>
</html>
I am facing problem to show chart multiple times in a page. following is my code. my application is dynamic. but if the following can show the chart twice or more, my problem will be solved.
This code is showing chart once.
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer",
{
title:{
text: "Using all form of color inputs",
fontColor: "#6A5ACD"
},
axisY:{
interlacedColor: "rgb(255,250,250)",
gridColor: "#FFBFD5"
},
data: [
{
type: "column",
color: "darkgreen",
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>
<div id="chartContainer" style="height: 300px; width: 100%;"> <br> <br> <br> <br><br> <br><br> <br><br> <br><br> <br>
<script type="text/javascript">
window.onload = function () {
var chart1 = new CanvasJS.Chart("chartContainer1",
{
title:{
text: "Using all form of color inputs",
fontColor: "#6A5ACD"
},
axisY:{
interlacedColor: "rgb(255,250,250)",
gridColor: "#FFBFD5"
},
data: [
{
type: "column",
color: "darkgreen",
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}
]
}
]
});
chart1.render();
}
</script>
<div id="chartContainer1" style="height: 300px; width: 100%;">
</div>
<script type="text/javascript" src="canvasjs.js"></script>
</body>
</html>
You only have to add them together and make sure that your first created canvas is emptied whenever the second is created:
This is the JS you need:
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Using all form of color inputs",
fontColor: "#6A5ACD"
},
axisY: {
interlacedColor: "rgb(255,250,250)",
gridColor: "#FFBFD5"
},
data: [{
type: "column",
color: "darkgreen",
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();
chart = {}; // empty your first chart
var chart1 = new CanvasJS.Chart("chartContainer1", {
title: {
text: "Using all form of color inputs",
fontColor: "#6A5ACD"
},
axisY: {
interlacedColor: "rgb(255,250,250)",
gridColor: "#FFBFD5"
},
data: [{
type: "column",
color: "darkgreen",
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
}
]
}]
});
chart1.render();
chart1 = {};
Look at this JSFIDDLE
Thanks everyone. I have exact solution with Google Chart.
https://developers.google.com/chart/interactive/docs/quick_start
Regards,
Zahirul
Is there a way to add title to the axis? Typically, it is useful to have the y-axis display units. For example: http://code.shutterstock.com/rickshaw/examples/y_axis.html has just numbers, but in any kind of plot you would need to specify: %, $, km/s, etc. How to do that?
Thank you!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'line',
height: 300,
width: 800,
series: [
{
data: [ { x: 0, y: 120 }, { x: 1, y: 890 }, { x: 2, y: 38 }, { x: 3, y: 70 }, { x: 4, y: 32 } ],
color: "#c05020"
}, {
data: [ { x: 0, y: 80 }, { x: 1, y: 200 }, { x: 2, y: 100 }, { x: 3, y: 520 }, { x: 4, y: 133 } ],
color: "#30c020"
}, {
data: [ { x: 0, y: 200 }, { x: 1, y: 390 }, { x: 2, y: 1000 }, { x: 3, y: 200 }, { x: 4, y: 230 } ],
color: "#6060c0"
}
]
} );
var y_ticks = new Rickshaw.Graph.Axis.Y( {
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis'),
} );
graph.render();