I'm a complete newb with js and jquery but have muddled my way through getting a chart to properly display using Flask and an Ajax request. Where I'm having a problem is getting the charts data to refresh. I can get the chart to display just fine if I create it as a new chart as shown in the code below
$(document).ready(function() {
var getdata = $.post('/charts');
var ctx = document.getElementById('myChart').getContext('2d');
var myChart
getdata.done(function(results){
var chartData = {
labels: results['month'],
datasets: [{
label: 'Debits',
data: results['debit'],
backgroundColor: "rgba(153,255,51,0.4)"
}, {
label: 'Credits',
data: results['credit'],
backgroundColor: "rgba(255,153,0,0.4)"
}, {
label: 'Balance',
data: results['balance'],
backgroundColor: "rgba(50,110,0,0.4)"
}]
}
myChart = new Chart(ctx, {type: 'line', data: chartData});
});
$("form :input").change(function() {
year = $(this).val();
console.log(year)
$.ajax({
type: "POST",
url: "/data",
data: {'year':year},
success: function(results){
var updatedData = {
labels : results['month'],
datasets : [{
label: 'Debits',
data: results['debit'],
backgroundColor: "rgba(153,255,51,0.4)"
}, {
label: 'Credits',
data: results['credit'],
backgroundColor: "rgba(255,153,0,0.4)"
}, {
label: 'Balance',
data: results['balance'],
backgroundColor: "rgba(50,110,0,0.4)"
}]
}
myChart= new Chart(ctx, {type: 'line', data: updatedData});
}
});
});
});
But if I change the last line to
myChart.update(updatedData)
nothing happens, I don't get any errors, the chart doesn't update. Nothing. The strange thing is that I know the myChart is global because I don't have to create it again after the Ajax request.
Thanks
From the documentation of charts.js (http://www.chartjs.org/docs/#getting-started-creating-a-chart), you first need to change data and then call update (arguments for update function are not the data, but duration etc.):
.update(duration, lazy)
Triggers an update of the chart. This can be safely called after replacing the entire data object. This will update all scales, legends, and then re-render the chart.
// duration is the time for the animation of the redraw in milliseconds
// lazy is a boolean. if true, the animation can be interrupted by other animations
myLineChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50
myLineChart.update(); // Calling update now animates the position of March from 90 to 50.
So in your case:
myChart.data = updatedData;
myChart.update();
Related
Hey all i am using javascript with ApexCharts to draw a chart and this chart gets its data from firebase but each time the data is changed in firebase instead of replacing the chart or updating it it appends new chart under it
this is the code
function dailyTracking(){
var query = firebase.database().ref('Facilities').on('value', function(snapshot) {
var options = {
chart: {
height: 380,
width: "100%",
type: "bar",
stacked: false
},
series: [
{
name: "Library",
data: snapshotToArray(snapshot.child('Library'))
},
{
name: "Canteen",
data: [5]
},
{
name: "Free Lab",
data: [42]
}
],
xaxis: {
labels: {
formatter: function (value, timestamp) {
return new Date() // The formatter function overrides format property
},
}
}
};
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
query.off();
return snapshotToArray(snapshot);});}
I managed to solve it by adding this line
document.getElementById('chart').innerHTML = '';
before rendering the chart
Try not to wrap the chart.render() call in the event. Render the chart once and call the update event when you get new data by calling chart.updateSeries()
I have a dataset that has data something like this
var data =[10,30,20,50,80,60,120,40,20,90,30,10];
var labels = [moment("12:00:00", 'HH:mm:ss'),moment("12:00:01", 'HH:mm:ss'),moment("12:00:02", 'HH:mm:ss'),moment("12:00:03", 'HH:mm:ss')];
I fed the data to chartJS like this
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Voltage Fluctuation',
data: [10,20,30,40,50],
borderWidth: 1
}]
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'minute',
displayFormats: {
hour: 'HH:mm:ss'
}
}
}]
},
}
});
However, I'm only getting data for the first four points i.e for each label.
Here's the JSFiddle
I want the data to be distributed for all the labels, in this case one data point for every (4/12)seconds and adjust the graph accordingly.
Is there any possible way I can achieve that without hardcoding it by converting the labels to milliseconds format?
I went ahead and hardcoded the entire thing by chopping seconds into milliseconds in order to create arrays of equal length
I am using the latest version of chart JS (2.5.0) and trying to get 2 polar area charts to appear in a page that has the content of the page loaded in VIA ajax. Here are my two polar charts (I will omit the rest of the code as it is not pertinent to this):
<canvas id="myChart"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'polarArea',
options: {
responsive: true
}
data: {
labels: ["Head", "Chest", "Stomach", "Left Arm", "Right Arm", "Left Leg", "Right Leg"],
datasets: [{
backgroundColor: [
"#1AFF05",
"#0D9900",
"#197011",
"#1E4A1A",
"#4C4D4C",
"#81917F",
"#B5F7B0"
],
data: <?php getHitBoxPercents($player);?>
// data: [12, 19, 3, 17, 28, 24, 7]
}]
}
});
</script>
And Chart 2:
<canvas id="myChart1v1"></canvas>
<script>
var ctx1v1 = document.getElementById("myChart1v1").getContext('2d');
var myChart1 = new Chart(ctx1v1, {
type: 'polarArea',
options: {
responsive: true
}
data: {
labels: ["Head", "Chest", "Stomach", "Left Arm", "Right Arm", "Left Leg", "Right Leg"],
datasets: [{
backgroundColor: [
"#1AFF05",
"#0D9900",
"#197011",
"#1E4A1A",
"#4C4D4C",
"#81917F",
"#B5F7B0"
],
data: <?php getHitBoxPercents($player);?>
// data: [12, 19, 3, 17, 28, 24, 7]
}]
}
});
</script>
These are both in Tab menus which all works fine but here are the weird things:
The first chart doesn't load properly at all, it loads the "outline" of the chart but no data, although the data is all set properly in the javascript and it works just fine if I take away the second chart. See picture: Puush Image
The chart from the second bit of code works perfectly: Puush Image 2
If I press the button to generate the ajax again (a form with a search button to find matching records) The first chart goes away completely (code is all still there) and the second chart still works just fine. Puush example of this
Maybe the key to this whole thing: If I resize the page the chart appears, regardless of if I reload the ajax in the page and the chart all disappears all I have to do is resize the page (go to half size then maximize again) and it works, both charts. I don't know why or how to fix this but I don't want that to be the only solution.
EDIT: I am trying to fix mine according to this fiddle but it isn't working: fiddle The new code I am trying to use:
$(function(){
var chart_polar_options = {
responsive: true
};
var data1v1 = {
labels: ["Head", "Chest", "Stomach", "Left Arm", "Right Arm", "Left Leg", "Right Leg"],
datasets: [{
backgroundColor: [
"#1AFF05",
"#0D9900",
"#197011",
"#1E4A1A",
"#4C4D4C",
"#81917F",
"#B5F7B0"
],
data: <?php getHitBoxPercents($player);?>
}]
};
var ctx1v1 = document.getElementById("myChart1v1").getContext('2d');
var myChart1 = new Chart(ctx1v1, {
type: 'polarArea',
options: {
responsive: true
},
data: data1v1
});
$('#tab2').on('shown.bs.tab', function (e) {
myChart1.destroy();
myChart1 = new Chart(ctx1v1, {
type: 'polarArea',
options: {
responsive: true
},
data: data1v1
});
});
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'polarArea',
options: {
responsive: true
},
data: data1v1
});
$('#tab1').on('shown.bs.tab', function (e) {
myChart.destroy();
myChart = new Chart(ctx, {
type: 'polarArea',
options: {
responsive: true
},
data: data1v1
});
});
});
The problem with the code above is neither load until I resize the browser but it is pulling in the charts, they just look blank.
I am drawing graph on UI using ChartJS 2.0. And I am able to render a Pie Chart. But I want the mouse-hover to show the data along with a "%" sign. How can I append % So if on mouse hover I am getting Rented: 93 I would like to see Rented: 93 %. Kindly guide me.
Below is what I have now:
var sixthSubViewModel = Backbone.View.extend({
template: _.template($('#myChart6-template').html()),
render: function() {
$(this.el).html(this.template());
var ctx = this.$el.find('#pieChart')[0];
var data = {
datasets: [{
data: this.model.attributes.currMonthOccAvailVac,
backgroundColor: [
"#455C73",
"#BDC3C7",
"#26B99A",
],
label: 'My dataset' // for legend
}],
labels: [
"Rented",
"Vacant",
"Unavailable",
]
};
var pieChart = new Chart(ctx, {
type: 'pie',
data: data
});
},
initialize: function(){
this.render();
}
});
Understanding:
I understand that currently hover takes the label and adds a colon and then adds data to it. So if label = Rented, Data = 93 I will see something like Rented: 93 on mouse-hover. How can I change text of mouse-hover to display Rented: 93%. Below is the image of what I have till now on mouse-hover.
I understand that I need to add one "options" in the pie chart. But I am not sure how to do that. Please help me.
You can edit what is displayed in your tooltip with the callbacks.label method in your chart options, and then simply add a "%" to the default string using :
tooltipItems -- See documentation for more information (scroll up a bit to "Tooltip Item Interface")
data -- Where the datasets and labels are stored.
var ctx = document.getElementById("canvas");
var data = {
datasets: [{
data: [93, 4, 3],
backgroundColor: [
"#455C73",
"#BDC3C7",
"#26B99A",
],
label: 'My dataset' // for legend
}],
labels: [
"Rented",
"Vacant",
"Unavailable",
]
};
var pieChart = new Chart(ctx, {
type: 'pie',
data: data,
options: {
tooltips: {
callbacks: {
label: function(tooltipItems, data) {
return data.labels[tooltipItems.index] +
" : " +
data.datasets[tooltipItems.datasetIndex].data[tooltipItems.index] +
' %';
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.1/Chart.min.js"></script>
<canvas id="canvas" height="150"></canvas>
I am loading Highcharts like this.
var options = {
credits: {
enabled: false
},
chart: {
renderTo: 'chart_box',
type: 'areaspline'
},
title: {
text: ''
},
xAxis: {
crosshairs: true,
labels: {
step: 5,
rotation: -45
}
},
series: []
};
Then I have a function which is called when graph needs to be loaded. Upon calling the function, data is fetched through AJAX and assigned to series and date lie this:
$.ajax({
url: 'url/charts',
type: 'post',
data: data
}).done(function(data) {
var dateCount = data.dates.length;
var stepCount = 1;
if (dateCount > 10) {
stepCount = 5;
}
options.xAxis.categories = data.dates;
$.each(data.series, function(name, elem) {
options.series.push({
name: name.replace('_', ' ').toUpperCase().trim(),
data: elem
})
});
chart = new Highcharts.Chart(options);
});
The issue here is that even though I have given step as 5 , it is showing dates with 15 dates interval. I mean in xAxis labels. It seems like it will be multiplied by three always. If I give 2, it will show 6 days interval in labels. Everything working fine in a chart which is not using AJAX to load data.