I have Chart.js set up with a form so that it takes input fields from the form and after clicking Submit/Update button, it generates a donut chart using those numbers from the input fields as data points.
The issue is how can I get the form or Chart.js to run once and generate a donut chart with the input fields numbers when its on the page (on page load).
The form input fields are already filled with numbers/data via HTML5 Local Storage).
I've tried jQuery .submit(); on page load but nothing happens. I appreciate any help. Thank you.
EDIT: I've gone ahead and created a fiddle to re-create the issue.
$(document).ready(function () {
$("#submit-btn").click(function (e) {
e.preventDefault();
var outputyearly = $('#outputyearly');
var amount = parseInt($('#amount').val().replace(/,/g, ''), 10);
var rate = parseFloat($('#rate').val(), 10);
var term = parseFloat($('#term').val(), 10);
// Some math calculations code
if (window.onload.myDoughnutChart != null) {
window.onload.myDoughnutChart.destroy();
}
var ctx = document.getElementById("myChart").getContext("2d");
window.onload.myDoughnutChart = new Chart(ctx, {
type: 'doughnut',
data: data,
options: options
});
});
});
You can put the code that draws the chart in a function and call that function on both the $(document).ready and $("#submit-btn").click event, like this:
function drawChart() {
var outputyearly = $('#outputyearly');
var amount = parseInt($('#amount').val().replace(/,/g, ''), 10);
var rate = parseFloat($('#rate').val(), 10);
var term = parseFloat($('#term').val(), 10);
//Destroy the dougnut chart here, not sure how it's accessible, but it won't work through window.onload
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, {
type: 'doughnut',
data: data,
options: options
});
}
$(document).ready(function() {
drawChart();
$("#submit-btn").click(function (e) {
e.preventDefault();
drawChart();
});
});
Note that $(document).ready already imposes the code inside of it to be executed when the page is done, so putting a window.onload inside of it won't make any difference.
Related
I have created a js constructor function to create a D3 chart object.
The function appears to work on initial load. However,I have also added an onresize listener to re-draw the chart on resize.
However, when the resize event occurs, a console.log() of the data used to make the chart shows that the dates field (the first field) is all null. I have not been successful in using console.log to find where this change actually occurs. The data seems normal before the resize and before the chart drawing function runs.
Here is a jsfiddle, which as the full code. When you resize the viewport, the chart disappears. console shows myData is null
Relevant code:
HTML
var firstChart = new LineChart(myData,'chart-container','chart_area','This Is A Chart',["red","yellow","blue"],"temp","date")
//Re draw on resize
window.onresize = function(){
firstChart.drawChart();
console.log(myData);
}
DATA
var myData = [
{"date":20111001,"New_York":63.4,"San_Francisco":62.7,"Austin":72.2},
{"date":20111002,"New_York":58,"San_Francisco":59.9,"Austin":67.7},
{"date":20111003,"New_York":53.3,"San_Francisco":59.1,"Austin":69.4},
{"date":20111004,"New_York":55.7,"San_Francisco":58.8,"Austin":68},
{"date":20111005,"New_York":64.2,"San_Francisco":58.7,"Austin":72.4},
{"date":20111006,"New_York":58.8,"San_Francisco":57,"Austin":77},
{"date":20111007,"New_York":57.9,"San_Francisco":56.7,"Austin":82.3},
{"date":20111008,"New_York":61.8,"San_Francisco":56.8,"Austin":78.9},
{"date":20111009,"New_York":69.3,"San_Francisco":56.7,"Austin":68.8},
{"date":20111010,"New_York":71.2,"San_Francisco":60.1,"Austin":68.7},
{"date":20111011,"New_York":68.7,"San_Francisco":61.1,"Austin":70.3},
{"date":20111012,"New_York":61.8,"San_Francisco":61.5,"Austin":75.3},
{"date":20111013,"New_York":63,"San_Francisco":64.3,"Austin":76.6},
{"date":20111014,"New_York":66.9,"San_Francisco":67.1,"Austin":66.6},
{"date":20111015,"New_York":61.7,"San_Francisco":64.6,"Austin":68},
{"date":20111016,"New_York":61.8,"San_Francisco":61.6,"Austin":70.6},
{"date":20111017,"New_York":62.8,"San_Francisco":61.1,"Austin":71.1},
{"date":20111018,"New_York":60.8,"San_Francisco":59.2,"Austin":70},
{"date":20111019,"New_York":62.1,"San_Francisco":58.9,"Austin":61.6},
{"date":20111020,"New_York":65.1,"San_Francisco":57.2,"Austin":57.4},
{"date":20111021,"New_York":55.6,"San_Francisco":56.4,"Austin":64.3}
]
On resize the date column is all null
JS
function LineChart(data,chartContainerID,chartAreaId,chartTitle,colorArray,yaxisLabel,xaxisLabel,legend,yaxisFormat, marginsDict){
this.data = data;
this.chartContainer = document.getElementById(chartContainerID)
this.chartArea = document.getElementById(chartAreaId);
this.chartTitle = chartTitle;
this.colors = colorArray;
this.yaxisLabel=yaxisLabel;
this.xaxisLabel=xaxisLabel;
this.isLegend = legend;
this.yaxisFormat= yaxisFormat;
this.margins = marginsDict;
///....more code here in js fiddle.....
this.drawChart = function(){
///....more code here in js fiddle.....
///Console leads me here. more code above it
var items = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
console.log(d)
return {
date: d.date,
result: +d[name]
};
})
};
});
///....more code here in js fiddle.....
}
}
I have see that using google chart creates much RAM usage.
I must say that i have code somethink with javascript which lets the browser load every 7 seconds a new chart, it does give the Google Draw Chart function new data from a new file and the chart gets drawed, but this seems to create to much RAM usage on my PC. Does somebody know a trick how to avoid this? I think maybe the browser is saving all data from before in a cache or so, if that would not be done then maybe the RAM dont go so high after few minutes? Because now it does go higher and higher with few minutes it reach 100% and the browser stop working.
Here is my current code:
function drawVisualization()
{
//-- From this textfile the chart gets info which is the new symbol chart
var Textinhalt = $.ajax({ url: "Chartsettings.txt", contentType:"application/json", dataType:"json", async: false }).responseText;
var Setting = JSON.parse(Textinhalt);
Symbol=Setting.Selection[0].symbol;
Timeframe=Setting.Selection[0].timeframe;
Broker=Setting.Selection[0].broker;
//--Now the new data is been getting from php response file
var fileurl = "getData.php?symbol="+Symbol+"&timeframe="+Timeframe+"&broker="+Broker;
var jsonData = $.ajax({
url: fileurl,
contentType:"application/json",
dataType:"json",
async: false
}).responseText;
var array=$.parseJSON(jsonData);
//--Now new data have been saved into array and will be draw
var data =google.visualization.arrayToDataTable(array,true);
var options = {
legend: 'none'
};
var chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
//--If this function is clicked the google charts get refreshed every 7 seconds and i did see that my browser creates more and more RAM usuage till it goes over 100% and stops working
function PlayCharts()
{
drawVisualization();
setTimeout(PlaySignals, 7000);
}
part of the problem could be that you are creating a new chart every time
instead of drawing the same chart with new data
recommend changing the scope a little,
move the chart variables outside of drawVisualization
but you have to wait until google is loaded until creating
not sure what you're page on load function looks like
also, async: false on $.ajax is deprecated
recommend setup similar to following...
// move declarations outside of drawVisualization
var chart;
var options = {
legend: 'none'
};
// load google charts
google.charts.load('current', {
packages:['corechart']
}).then(function () {
// create chart
chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
// move other on page load functions here
// google.charts.load can be used instead of --> $(document).ready
});
function drawVisualization() {
//-- From this textfile the chart gets info which is the new symbol chart
var Textinhalt = $.ajax({ url: "Chartsettings.txt", contentType:"application/json", dataType:"json", async: false }).responseText;
var Setting = JSON.parse(Textinhalt);
Symbol=Setting.Selection[0].symbol;
Timeframe=Setting.Selection[0].timeframe;
Broker=Setting.Selection[0].broker;
//--Now the new data is been getting from php response file
var fileurl = "getData.php?symbol="+Symbol+"&timeframe="+Timeframe+"&broker="+Broker;
$.ajax({
url: fileurl,
contentType: 'application/json',
dataType: 'json'
}).done(function (jsonData) {
var array = $.parseJSON(jsonData);
//--Now new data have been saved into array and will be draw
var data = google.visualization.arrayToDataTable(array, true);
// draw same chart
chart.draw(data, options);
});
}
function PlayCharts() {
drawVisualization();
setTimeout(PlaySignals, 7000);
}
I think my issue is a known one, everytime I make a new chart and hover my mouse over some points in the canvas, the old charts flash in and out all the time. Here's one of the threads I followed to try and fix it, but nothing seems to work. I tried re-appending the canvas, using destroy, clear, if statements which should clear it, but nothing.
Here's my code:
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: chartjsDate,
datasets: [{
label: 'temp',
data: chartjsTemp,
backgroundColor: "rgba(240,240,240,0.5)"
}]
}
});
I tried adding myChart.destroy(); before and after that code, even if(myChart!=null){myChart.destroy();}, but still nothing. Any help on how to fix it would be appreciated. All other threads I found are quite old and their solutions don't work.
Edit: Some stuff I tried, to no avail:
var myChart;
if (myChart != undefined || myChart !=null) {
myChart.destroy();
}
I also had this problem. To solve it,
you first have to declare myChart variable globally and then try this way.
//var my chart declare globally.
let chartData = {
type: 'line',
data: {
labels: chartjsDate,
datasets: [{
label: 'temp',
data: chartjsTemp,
backgroundColor: "rgba(240,240,240,0.5)"
}]
}
if (typeof(this.myChart) != "undefined") {
this.myChart.destroy();
}
const ctx = this.renderRoot.querySelector('#chart-canvas').getContext('2d');
this.myChart = new Chart(ctx, chartData);
this.myChart.update();
Solved! I added this above the javascript code:
var button = document.getElementById("submitButton");
submitButton.addEventListener("click", function(){
myChart.destroy();
});
And changed my submit button to have the id "submitButton", like this:
<input type="submit" class="btn btn-danger" id="submitButton" value="Send" />
This way, everytime you press the submit button, it destroys the previous chart. The weird thing is that when trying to use myChart.destroy(); I got errors.
Above solutions are working for me but when I have two charts on the same page, Only one is showing. Other charts are becoming empty. Here is the solution for that.
var ctx = document.getElementById("bar-chart").getContext("2d");
//Destroy the previous chart;
//Rename the "bar" according to your component
if(window.bar != undefined)
window.bar.destroy();
window.bar = new Chart(ctx , {});
if you don't change the "bar", only one chart will show in your page.
It is not bug. Basically you were creating a new graph each time. What you need here is to update graph instead of drawing a new one on that canvas. This can be done using the following code.
if(typeof Graph ==="undefined"){
window.Graph = new Chart(Graph_ctx, Graph_config);
}else{
//updating with new chart data
window.Graph.config=Graph_config;
//redraw the chart
window.Graph.update();
}
var ctxLine = document.getElementById("line-chart").getContext("2d");
//var myLineChart;
//myLineChart;
if(window.bar != undefined)
window.bar.destroy();
window.bar = new Chart(ctxLine, {});
For more clear check this:
solved-hovering-chartjs-bar-chart-showing-old-data
I usually do this before creating my chart
document.querySelector(".chart-container").innerHTML= '<canvas id="bar_chart"></canvas>';
var chart3 = $('#bar_chart');
graph = new Chart(chart3, {
type: 'bar',
data: chart_data,
options: options
});
My html:
<div class="chart-container">
<canvas id="bar_chart"></canvas>0
</div>
Just Use That and solve your Problem ;
if(window.myChart!=undefined) {
var oldcanvasid= window.myChart.chart.ctx.canvas.id;
if(chardcanvasid==oldcanvasid) {
window.myChart.destroy();
}
}
var ctx = document.getElementById(chardcanvasid).getContext('2d');
window.myChart = new Chart(ctx, {
type: charttype,
data: datass,
options: optionss,
});
I'm trying to click every label after the chart is loaded using a ChartJS chart. I've written the following code and am having trouble getting past what I've got. Any insight or help would be appreciated.
myChart.legend.legendItems.forEach(function(label, key) {
console.log(myChart.legend.legendItems[key].hidden);
if (label.datasetIndex) {
myChart.legend.legendItems[key].hidden = true;
}
console.log(myChart.legend.legendItems[key].hidden);
});
myChart.update();
I'm trying to draw the chart so that when it first loads, every label is crossed out and hidden. DO I have the right idea setting it to hidden and updating? Thanks!
This works for me:
multiLineChart.legend.legendItems[0].hidden = true;
multiLineChart.data.datasets[0].hidden = true;
For some reason the update method didn't quite work, but this did:
function init() {
myBarChart = new Chart(ctx, {
type: chartType,
data: data,
options: options
});
myBarChart.legend.legendItems[0].hidden = true;
myBarChart.data.datasets[0].hidden = true;
}
And your function:
multiLineChart.legend.legendItems.forEach(function(label, key) {
multiLineChart.legend.legendItems[key].hidden = true;
multiLineChart.data.datasets[key].hidden = true;
});
Result:
Codepen: Chart.js Pre Crossed Series
I am having a problem with the Google annotated timeline. I have this function (shown below) that is called in the jQuery ready function:
//creates an annotated timeline
function graphAnnotatedTimeLine(url) {
jQuery.get(url, function(returned_data) {
//parse returned_data ...
//build data table
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('datetime', columnHeadings[0]);
dataTable.addColumn('number', columnHeadings[1]);
//populate table
for(var i = 0; i < rawData.length; i++) {
var parsedData = data[i].split(",");
dataTable.addRow([new Date(parsedData[0]), parseFloat(parsedData[1])]);
}
//draw graph
var options = {displayAnnotations: false,
allowRedraw: true,
legendPosition: 'newRow',
displayZoomButtons: false,
wmode: 'transparent'};
var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart-div'));
chart.draw(dataTable, options);
});
}
Called in the ready function as:
$.ready(function() {
//generate url string
google.setOnLoadCallback(graphAnnotatedTimeline(url));
self.setInterval('updateGraph', 60000);
//more stuff
});
So in the ready I call it to draw the first set of data and then set an update function to be called every minute. All the update function does is basically the same as the ready function does: build a url string and call the graph function with that url. The problem I'm having is that the graph it doesn't display on startup. Once the update gets called once though, it displays fine after that. Is there anyone that can give me some insite as to why this is happening?
This is because your jquery ready function is called before the google visualization script is loaded. google.setOnLoadCallback must be called like this...
<script type="text/javascript" src='http://www.google.com/jsapi?autoload={"modules":[{"name":"visualization","version":"1","packages":["annotatedtimeline"]}]}'></script>
<script type="text/javascript">
google.setOnLoadCallback(graphAnnotatedTimeline(url));
</script>