display none breaks chart.js when selected in dropdown - javascript

I want to show only one chart after the page load and then you can select a chart in the dropdown menu. The issues is when I add the class display:none; the graph won't load when selected in the dropdown.
How can I solve this?
<select id='chart-graph-progress'>
<option value="revenue-opt">Revenue</option>
<option value="rpu-opt">Revenue per user</option>
</select>
<div class="card2 full-chart-topmargin" id='revenue'>
<div class="big-text1-blue text-center">
Revenue
</div>
<div class="card-block">
<div class="chart-wrapper fullsize">
<canvas id="revenue-chart"></canvas>
</div>
</div>
</div>
<div style="display:none;" class="card2 full-chart-topmargin" id='rpu'>
<div class="big-text1-blue text-center">
Revenue per user
</div>
<div class="card-block">
<div class="chart-wrapper fullsize">
<canvas id="rpu-chart"></canvas>
</div>
</div>
</div>
Here is my custom.js file.
$(document).ready(function(){
$('#chart-graph-progress').on('change', function() {
if ( this.value == 'revenue-opt')
{
$("#revenue").show();
}
else
{
$("#revenue").hide();
}
});
$('#chart-graph-progress').on('change', function() {
if ( this.value == 'rpu-opt')
{
$("#rpu").show();
}
else
{
$("#rpu").hide();
}
});
});
Chart.js
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
var lineChartData = {
labels : ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
datasets : [
{
label: 'Revenue',
labelColor : '#fff',
fontColor : '#fff' ,
backgroundColor : 'rgba(220,220,220,0.2)',
borderColor : 'rgba(220,220,220,1)',
pointBackgroundColor : 'rgba(220,220,220,1)',
pointBorderColor : '#fff',
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
}
]
};
var options = {
maintainAspectRatio: false,
legend: {
display: false,
},
scales: {
xAxes: [{
gridLines: {
display: false,
color: '#03A5C5',
lineWidth: 8,
},
ticks: {
fontColor: "white",
},
}],
yAxes: [{
gridLines: {
display: false,
color: '#03A5C5',
lineWidth: 8,
},
ticks: {
fontColor: "white",
beginAtZero: true,
}
}]
}
};
var ctx = document.getElementById('revenue-chart');
var chart = new Chart(ctx, {
responsive: true,
type: 'line',
data: lineChartData,
options: options
});
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
var lineChartData = {
labels : ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
datasets : [
{
label: 'Revenue',
labelColor : '#fff',
fontColor : '#fff' ,
backgroundColor : 'rgba(220,220,220,0.2)',
borderColor : 'rgba(220,220,220,1)',
pointBackgroundColor : 'rgba(220,220,220,1)',
pointBorderColor : '#fff',
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
}
]
};
var options = {
maintainAspectRatio: false,
legend: {
display: false,
},
scales: {
xAxes: [{
gridLines: {
display: false,
color: '#03A5C5',
lineWidth: 8,
},
ticks: {
fontColor: "white",
},
}],
yAxes: [{
gridLines: {
display: false,
color: '#03A5C5',
lineWidth: 8,
},
ticks: {
fontColor: "white",
beginAtZero: true,
}
}]
}
};
var ctx = document.getElementById('rpu-chart');
var chart = new Chart(ctx, {
responsive: true,
type: 'line',
data: lineChartData,
options: options
});

If you are using ChartJS 1, then look at the first possible fixes below. If you are using ChartJS 2, then apparently this bug has been fixed (GitHub issue #762). However, after some long debugging I found out that when display: none; is used with maintainAspectRatio: false, some times the height of the graph is squashed to none, which I think it's your problem here. I have logged an issue for this.
Possible fixes (1 is very simple, so you might want to try that):
1. Use jQuery to initially hide the containers
Remove the style="display:none;" from the #rpu div:
<div class="card2 full-chart-topmargin" id='rpu'>
Use jQuery to hide it initially:
$(document).ready(function(){
$("#rpu").hide();
// ...
});
2. Use fixed size canvases
Set both canvas to some fixed size:
<canvas id="revenue-chart" width="600" height="400"></canvas>
<canvas id="rpu-chart" width="600" height="400"></canvas>
Then use maintainAspectRatio: true instead:
var options = {
maintainAspectRatio: true,
// ...
};

In the html, on the element with the id='rpu' try to add "opacity: 0" instead of "display: none", and in the custom.js file instead of show and hide change to:
$(document).ready(function(){
$('#chart-graph-progress').on('change', function() {
if ( this.value == 'revenue-opt')
{
$("#revenue").css("opacity", "1");
}
else
{
$("#revenue").css("opacity", "0");
}
});
$('#chart-graph-progress').on('change', function() {
if ( this.value == 'rpu-opt')
{
$("#rpu").css("opacity", "1");
}
else
{
$("#rpu").css("opacity", "0");
}
});
});
I am pretty sure that the issue is that the chart is not initialized on a display: none element. So we're trying to hide the element by opacity:0.
I hope it helps!

Related

How to add onclick event on chart label in react-chartjs-2?

I want open a dialog when clicking on chart js label. This is the dataset code:-
const data = {
datasets: [
{
label: 'Reviews',
backgroundColor: theme.palette.primary.main,
data: dataProp.reviews,
barThickness: 12,
maxBarThickness: 10,
barPercentage: 0.5,
categoryPercentage: 0.5
},
{
label: 'Talents',
backgroundColor: theme.palette.secondary.main,
data: dataProp.talents,
barThickness: 12,
maxBarThickness: 10,
barPercentage: 0.5,
categoryPercentage: 0.5
}
],
labels
};
This is the screenshot the chart created.
I know how to set onclick on legend but how can i set an onClick on labels ?
I Tried this in option but it is not working and giving me error
const options = {
responsive: true,
maintainAspectRatio: false,
animation: false,
cornerRadius: 20,
legend: {
display: false
},
layout: {
padding: 0
},
scales: {
xAxes: [
{
}
],
yAxes: [
{
}
]
},
tooltips: {
},
onClick: function(evt, element) {
if (element.length > 0) {
console.log(element);
// you can also get dataset of your selected element
data.datasets[element[0]._datasetIndex].data[element[0]._index];
}
}
};
All you need to do is just add onClick callback in graph options property
options={{
.....
onClick: function(evt, element) {
if(element.length > 0) {
console.log(element,element[0]._datasetInde)
// you can also get dataset of your selected element
console.log(data.datasets[element[0]._datasetIndex])
}
}}
You need to get ref, and add event getElementAtEvent.
import { Bar } from 'react-chartjs-2'
import { Chart } from 'chart.js'
const BarChart = () => {
const chartRef = useRef<HTMLCanvasElement>(null)
...
return ( <Bar
type='horizontalBar'
data={chartData}
ref={chartRef}
getElementAtEvent={(i: any, event: any) => {
if (chartRef.current) {
const chart = Chart.getChart(chartRef.current)
const clickedElements = chart!.getElementsAtEventForMode(event, 'y',{axis: 'x', intersect: false}, true)
if (clickedElements.length > 0) {
console.log(clickedElements[0].index) // Here clicked label | data index
}
}
}}
options={options}/>
)
}

chart.js display a default chart with option value

so I'm generating charts with a database and displaying them with JSON script and it works fine but the chart only displays when I click an option value, what I'm trying to do now is set a default value option for when the website opens it displays a default chart if that makes sense, below is my chart.js code.
function renderHtmlChart(){
$(document).ready(function (){
var selection= document.getElementById('YEAR').value;
var link = "https://udon.ads.ntu.ac.uk/web/itec30151/N0773065/new/data.php?YEAR='"+selection+"'";
$.ajax({
url: link,
method: "GET",
success: function(data=this.responseText) {
console.log(data);
var Destination = [];
var Bookings = [];
for(var i in data) {
Destination.push(data[i].Destination);
Bookings.push(data[i].Bookings);
}
createChart(Destination,Bookings,selection)
},
error: function(data) {
console.log(data);
}
});
});
}
function createChart(Destination,Bookings,selection){
var universalOptions = {
maintainAspectRatio: true,
responsive: false,
title: {
display: true,
text: 'Top 5 Flight Bookings'
},
legend: {
display: true,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
},
scaleLabel: {
display: true,
labelString: 'Bookings'
}
}],
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Destinations'
}
}],
}
}
var chartdata = {
labels: Destination,
datasets : [
{
label: selection,
data: Bookings,
backgroundColor: ["#3366cc","#dc3912","#ff9900","#109618","#990099"],
borderWidth: '1',
borderColour: 'grey',
hoverBorderColor: 'black',
fill: false,
pointRadius: 0,
}
]
};
//stop overlap
$('select').on('change',function(){
barGraph.destroy();
});
// this makes legend hidden
var update_caption = function(legend) {
labels[legend.text] = legend.hidden;
var selected = Object.keys(labels).filter(function(key) {
return labels[key];
});
};
//this creates new graph
var ctx = document.getElementById('myChart');
var barGraph = new Chart(ctx, {
type: 'bar',
data: chartdata,
options: universalOptions,
responsive: false,
});
}
hope you have latest version of jquery like:-
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
hope this will help
//create renderHtmlChart function
function renderHtmlChart()
{
var selection= document.getElementById('YEAR').value;
var link = "https://udon.ads.ntu.ac.uk/web/itec30151/N0773065/new/data.php?YEAR='"+selection+"'";
$.ajax({
url: link,
method: "GET",
success: function(data=this.responseText)
{
console.log(data);
var Destination = [];
var Bookings = [];
for(var i in data)
{
Destination.push(data[i].Destination);
Bookings.push(data[i].Bookings);
}
createChart(Destination,Bookings,selection)
},
error: function(data)
{
console.log(data);
}
});
}
//create createChart function
function createChart(Destination,Bookings,selection)
{
var universalOptions =
{
maintainAspectRatio: true,
responsive: false,
title:
{
display: true,
text: 'Top 5 Flight Bookings'
},
legend:
{
display: true,
},
scales:
{
yAxes: [{
ticks: {
beginAtZero: true,
},
scaleLabel: {
display: true,
labelString: 'Bookings'
}
}],
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Destinations'
}
}],
}
}
var chartdata = {
labels: Destination,
datasets : [
{
label: selection,
data: Bookings,
backgroundColor: ["#3366cc","#dc3912","#ff9900","#109618","#990099"],
borderWidth: '1',
borderColour: 'grey',
hoverBorderColor: 'black',
fill: false,
pointRadius: 0,
}
]
};
// this makes legend hidden
var update_caption = function(legend) {
labels[legend.text] = legend.hidden;
var selected = Object.keys(labels).filter(function(key) {
return labels[key];
});
};
//this creates new graph
var ctx = document.getElementById('myChart');
var barGraph = new Chart(ctx, {
type: 'bar',
data: chartdata,
options: universalOptions,
responsive: false,
});
}
$(funtion(){
//onload call renderHtmlChart function
renderHtmlChart();
//on select input change call renderHtmlChart function
$('select').on('change',function(){
renderHtmlChart();
});
})

Charts.js destroy previous data and update

It seems like this is a common issue with charts.js. I created a site that allows you to choose a date. When you click a specific date a line chart updates given that dates' csv file. If you then go and click on a new date the chart.js line chart updates but if you over over the data it briefly displays the previous dates data.
I have seen a bunch of questions on this before and have tried to use the .destroy() along with updating the chart but every time I add this to any point of the code, the canvas simply gets destroyed and a chart is never created.
HTML:
<div class="chooseGame">
<button onclick="dropDownFunction()" class="gameDropDown">Select a Game Date & Time</button>
<div id="dropdown" class="dates"></div>
</div>
JS:
function dropDownFunction() {
document.getElementById("dropdown").classList.toggle("show");
}
window.onclick =
function(event) {
if (!event.target.matches('.gameDropDown')) {
var dropdowns = document.getElementsByClassName("dates");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
$(document).on("click", ".test",function(e){
var selectedDate= ($(this).text())
document.getElementById("today").innerText = selectedDate;
var cFD = document.getElementById('Canvas').getContext('2d');
var backgroundFD = document.getElementById('fDChart').style.background='white';
FirstData = new Chart(cFD, {
type: 'line',
data: {
labels: fdgameArray,
datasets: [{
label: 'New',
backgroundColor: "#f15a22",
borderColor: "#f15a22",
data: fdNewData,
fill: false,
},
{
label: 'Completed',
backgroundColor: "#004684",
borderColor: "#004684",
data: fdCompData,
fill: false,
},
{
label: 'Oustanding',
fontColor: '#a7b1c2',
borderColor: '#a7b1c2',
data: fdOutData,
fill: false,
}]
},
options: {
responsive: true,
title:{
display:false,
text: 'Delta Club',
fontSize: 15,
fontFamily: 'Arial',
fontColor: '#004684'
},
tooltips:{
mode: "index",
intersect: false,
},
hover:{
mode:"nearest",
intersect: true
},
scales:{
xAxes:[{
display: true,
ticks:{
fontColor:'#004684',
fontSize: 10
},
scaleLabel:{
display: true,
labelString: "Time",
fontColor:'#004684',
fontSize: 12
}
}],
yAxes:[{
display: true,
ticks:{
fontColor:'#004684',
fontSize: 10,
beginAtZero: true,
steps: 10,
stepValue: 1,
Max: 100
},
scaleLabel:{
display: true,
labelString: "# Orders",
fontColor:'#004684',
fontSize: 12
}
}]
}
}})
};
Whenever you change the date and hover over the chart, the previous date's data is displayed and then reverts back to current selected date. I want current data displayed always.
I actually was able to adjust the following and now I am all set:
var cFD = document.getElementById('Canvas').getContext('2d');
var backgroundFD = document.getElementById('firstDataChart').style.background='white';
if(window.chart && window.chart !== null){
window.chart.destroy();
}
window.chart = new Chart(cFD, {...})

How to add labels on top of the chart bar with Chart.js 2

I need to apply labels on top of chart following the columns just like the image (the numbers aside the text 'Resultado mês'):
Image of the desired result
Some help please?
The page is bellow (the labels need to go before the legends).
I've provided a HTML/CSS solution temporarily in the page bellow , but I'm waiting for the real solution:
http://www.pdagencia.com.br/porto/pages/10.3%20-%20consultar-dados-bancarios-01_v2.html#tab3
window.onload = function() {
var ctx = document.getElementById('ps-chart').getContext('2d');
var data = {
labels: ["Jan/18", "Fev/18", "Mar/18", "Abr/18", "Mai/18", "Jun/18", "Jul/18", "Ago/18", "Set/18", "Out/18", "Nov/18", "Dez/18"],
datasets: [{
label: "Entradas",
data: [650, 590, 800, 810, 560, 550, 400, 800, 810, 560, 550, 400],
backgroundColor: '#33bfff'
},
{
label: "Saídas",
data: [-280, -480, -400, -190, -860, -270, -900, -400, -190, -860, -270, -900],
backgroundColor: '#E75A5B'
}
]
}
var myChart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
responsive: false,
plugins: {
datalabels: {
formatter: function(value, context) {
return context.dataset.data[context.dataIndex].toLocaleString('pt-BR', {
style: 'currency',
currency: 'BRL'
});
}
}
},
legend: {
display: true,
},
tooltips: {
"enabled": false
},
scales: {
yAxes: [{
display: false,
ticks: {
display: false
}
}],
xAxes: [{
stacked: true,
barPercentage: 1.2,
gridLines: {
display: false
}
}]
}
}
});
}
<script src="https://github.com/chartjs/Chart.js/releases/download/v2.7.2/Chart.bundle.min.js"></script>
<script src="https://github.com/chartjs/chartjs-plugin-datalabels/releases/download/v0.3.0/chartjs-plugin-datalabels.min.js"></script>
<canvas id="ps-chart" style="width:100%"></canvas>
I am new to the chart js and javascript.
As I have faced the same problem, I wanted to display the sum of two values into the label,
I got some solution for the same as below.
Maybe it can help you.
Check it out:
http://www.chartjs.org/samples/latest/tooltips/callbacks.html
tooltips: {
mode: 'index',
callbacks: {
// Use the footer callback to display the sum of the items
showing in the tooltip
footer: function(tooltipItems, data) {
var sum = 0;
tooltipItems.forEach(function(tooltipItem) {
sum += data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
});
return 'Sum: ' + sum;
},
},
footerFontStyle: 'normal'
},
hover: {
mode: 'index',
intersect: true
},

How to change xaxis location in flotcharts?

Consider the options :
<style type="text/css">
.wrapperClass .xAxis .tickLabel{margin-left:40px;}
</style>
var options = {
series: {
lines: {
show: true,
color: "#CCFFCC"
},
points: { show: true }
},
xaxis: {
show: true,
mode: "time",
font :{
color: "Green",
size: 16
}
},
yaxis: {
show: true,
tickDecimals: 0
minTickSize : 1,
}
}
And :
<div class="wrapperClass">
var plotChart = $('.someChart').plot(myJson, options).data("plot");
</div>
How can I move the xaxis left by 40px ?
I searched in the documentation here but didn't find a clear way .
Any thoughts ?
Much appreciated
You can do this by adding this:
.xAxis .tickLabel{margin-left:40px;}
to your CSS. Let me know if this is what you want.

Categories

Resources