ChartJS remove previous chart when making new one - javascript

In the code below I am making a chartJS chart using database data, this is being done via a submit button which looks like this:
function showWhatSelected(str) {
$('#select2').hide();
$('#select3').hide();
if (str == "") {
document.getElementById("select1").innerHTML = "";
return;
} else {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("select1").innerHTML = this.responseText;
}
};
xmlhttp.open("GET","../controller/teamleiderController.php?action=whatToShow&value="+ str,true);
xmlhttp.send();
}
}
After that the AJAX runs which makes the new chart when a change has been detected in the submit button:
$.ajax({
url: "../controller/teamleiderController.php?action=select2JSON&value="+ str +"",
method: "GET",
success: function(data) {
console.log(data);
var label = ['aanwezig', 'afwezig'];
var aanwezigheid = [];
for(var i in data) {
aanwezigheid.push(data[i].aanwezig, data[i].afwezig, );
}
var chartdata = {
labels: label,
datasets : [
{
backgroundColor: ['rgba(0, 65, 140, 0.8)', 'rgba(215, 165, 0, 0.8)'],
borderColor: 'rgba(0, 0, 0, 0)',
hoverBackgroundColor: ['rgba(0, 65, 140, 1)', 'rgba(215, 165, 0, 1)'],
hoverBorderColor: 'rgba(200, 200, 200, 0)',
data: aanwezigheid
}
]
};
var option = {
};
var ctx = $("#mycanvas");
var barGraph = new Chart(ctx, {
type: 'pie',
data: chartdata,
options:option
});
},
error: function(data) {
console.log(data);
}
});
}
My problem is that my chart is ghosting, it keeps showing previous data, is there any way I can fix this? I have tried .destroy() and .clear() but they both don't seem to work...

You indeed need to use .destroy() method to remove any previous instance of chart before making a new one.
Perhaps, you were using the .destroy() method in an inappropriate manner, which made it non-effective.
Here­'s how you could properly remove / destroy any previous instance of chart, before creating a new one ...
var meta = barGraph && barGraph.data && barGraph.data.datasets[0]._meta;
for (let i in meta) {
if (meta[i].controller) meta[i].controller.chart.destroy();
}
affix the above code before initiating your chart
note: barGraph must be a global variable.
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩
var barGraph;
function init(str) {
$.ajax({
url: "https://istack.000webhostapp.com/json/" + str + ".json",
method: "GET",
success: function(data) {
console.log(data);
var label = ['aanwezig', 'afwezig'];
var aanwezigheid = [];
for (var i in data) {
aanwezigheid.push(data[i].aanwezig, data[i].afwezig);
}
var chartdata = {
labels: label,
datasets: [{
backgroundColor: ['rgba(0, 65, 140, 0.8)', 'rgba(215, 165, 0, 0.8)'],
borderColor: 'rgba(0, 0, 0, 0)',
hoverBackgroundColor: ['rgba(0, 65, 140, 1)', 'rgba(215, 165, 0, 1)'],
hoverBorderColor: 'rgba(200, 200, 200, 0)',
data: aanwezigheid
}]
};
var option = {responsive: false};
// destroy previous chart
var meta = barGraph && barGraph.data && barGraph.data.datasets[0]._meta;
for (let i in meta) {
if (meta[i].controller) meta[i].controller.chart.destroy();
}
// make new chart
var ctx = $("#mycanvas");
barGraph = new Chart(ctx, {
type: 'pie',
data: chartdata,
options: option
});
},
error: function(data) {
console.log(data);
}
});
}
body{overflow:hidden}button{margin-left: 45px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<button onclick="init('t1')">Dataset 1</button>
<button onclick="init('t2')">Dataset 2</button><br>
<canvas id="mycanvas" height="180"></canvas>

Related

chart js doesn't work properly on mobile devices

on my project im using chart js bar graph and line graph for data visualization from mysql database using php and javascript , both works perfect but when i try to open it on mobile device
only the line graph doesn't work properly .
I cant see the line and also i see only 2 axis.
I tried to change mantainAspectRatio and responsive options .
I also tried to add resize-observer-polyfill.
nothing works
Does anyone have an idea how to solve this??
js file:
'''
function myFunction() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var type = [];
var gain = [];
var range = [];
var dates =[];
var gains = [];
var gains2=[];
range=getDates(new Date(data2[data2.length-1].TargetStart), new Date(data2[data2.length-1].TargetEnd))
for(var i in data2) {
type.push("raise type: "+data2[i].type);
gain.push( data2[i].SellPrice- (data2[i].amount* data2[i].BuyPrice) );
dates.push(new Date(data2[i].EndDate));
}
var x= [];
for(let i=0;i<data2.length;i++) {
for (var j in range){
if(range[j]>=dates[i]){x.push({d:range[j],g:gain[i]});break;}
}
}
for (var j in range){
// if(range[3]<range[j])break;
var culgain=0;
for(var i in x) {
if(range[j]>=x[i].d)culgain+=x[i].g;
}
gains.push({x:range[j] , y:culgain});
}
for (var j in gains){
if(gains[3].x<gains[j].x)break;
gains2.push({x:gains[j].x,y:gains[j].y});
}
var he=data2[data2.length-1].Aname+': רווחי גיוסים צפויים';
var he2=data2[data2.length-1].Aname+':רווחי גיוסים';
const data = {
datasets: [{
label: he,
data: gains,
backgroundColor: "rgba(59, 89, 152, 0.75)",
borderColor: "rgba(59, 89, 152, 1)",
pointHoverBackgroundColor: "rgba(59, 89, 152, 1)",
pointHoverBorderColor: "rgba(59, 89, 152, 1)",
tension: 0.1,
borderWidth: 1
},
{
label: he2,
data: gains2,
backgroundColor: "rgba(211, 72, 54, 0.75)",
borderColor: "rgba(211, 72, 54, 1)",
pointHoverBackgroundColor: "rgba(211, 72, 54, 1)",
pointHoverBorderColor: "rgba(211, 72, 54, 1)",
tension: 0.3,
borderWidth: 3
}
]
};
const config = {
labels:range,
type: 'line',
data,
options :{
scales : {
x : {
type : 'time' ,
time : {
unit : 'week'
}
},
y :{
//max:data2[data2.length-1].Target,
//beginAtZero: true
suggestedMin: 0,
suggestedMax: data2[data2.length-1].Target
}
}
}
};
let el = document.getElementById("mycanvas");
//If it isn't "undefined" and it isn't "null", then it exists.
if(typeof(el) != 'undefined' && el != null){
el.parentNode.removeChild(el);
}
el = document.getElementById("myTableHead");
//If it isn't "undefined" and it isn't "null", then it exists.
if(typeof(el) != 'undefined' && el != null){
el.parentNode.removeChild(el);
}
let table = document.createElement('canvas');
table.id="mycanvas";
// Adding the entire table to the body tag
document.getElementById('wrap').appendChild(table);
var ctx = document.getElementById("mycanvas");
const myChart = new Chart(ctx,config); } };
xmlhttp.open("GET", "raisegraph.php", true);
xmlhttp.send();
}
'''
on computer
on computer
on safari
on safari

How can I highlight a particular datapoint in chartjs, where my data is coming from json array?

// here I am taking another json encoded data from phpfile
$(document).ready(function () {
showGraph();
});
function showGraph()
{
{
$.post("phpfile.php",
function (data)
{
console.log(data);
var name = [];
var marks = [];
var height=[];
//and here as I couldn't encode two json array's separetly I'm declaring it to a variable and then using it
var jsonfile =[{"height":"85","st_name":"Name1"},{"height":"100","st_name":"Name3"},{"height":"92","st_name":"Name4"},{"height":"104","st_name":"Name5"},{"height":"91","st_name":"Name2"},{"height":"99","st_name":"Name6"},{"height":"140","st_name":"AI346"},{"height":"139","st_name":"abc"},{"height":"141","st_name":"def"},{"height":"140","st_name":"ghi"},{"height":"144","st_name":"jkl"},{"height":"130","st_name":"lmn"},{"height":"142","st_name":"opq"},{"height":"132","st_name":"rst"},{"height":"135","st_name":"xyz"},{"height":"135","st_name":"asdfsf"}];
//here I am reading the data from phpfile(1st Json array)
for (var i in data) {
name.push(data[i].st_name);
marks.push(data[i].height);
}
//here i am trying to access data from second json
for (var i=0;i<jsonfile.length;i++){
if(jsonfile[i].height==100)
{ height.push(jsonfile[i].height)}
}
//my graph function ,when I do this I am getting a single point with second json(height variable) but I need to highlight the particular point under a condition... I am not understanding how to do it.
var chartdata = {
labels: name,
datasets: [
{
label: 'height',
fill:false,
lineTension:0.5,
backgroundColor: '#5B2C6F',
borderColor: '#5B2C6F',
pointHoverBackgroundColor: '#5B2C6F',
pointHoverBorderColor: '#5B2C6F',
data: marks
//data:height
},
{
label: 'weight',
fill:false,
lineTension:0.1,
backgroundColor: '#C0392B',
borderColor: '#C0392B',
pointHoverBackgroundColor: '#C0392B',
pointHoverBorderColor: '#C0392B',
data:height,
//data:height
}
]
};
var graphTarget = $("#graphCanvas");
var lineGraph = new Chart(graphTarget, {
type: 'line',
data: chartdata,
options :{
scales:{
xAxes: [{
display: false //this will remove all the x-axis grid lines
}]
}
}
});
});
}
}
</script>
i will try to improve this.
var data =[{"height":"85","st_name":"Name1","color":"rgba(85, 85, 255, 255)"},{"height":"100","st_name":"Name3","color":"rgba(255, 0, 0, 2)"},{"height":"92","st_name":"Name4","color":"rgba(85, 85, 255, 255)"},{"height":"104","st_name":"Name5","color":"rgba(85, 85, 255, 255)"}];
var height = [];
var label = [];
var color = [];
for(i = 0; i<data.length; i++){
height.push(data[i]['height']);
label.push(data[i]['st_name']);
color.push(data[i]['color']);
}
var ctx = document.getElementById('myLine').getContext('2d');
var myLineChart = new Chart(ctx, {
type: 'line',
data: {
labels: label,
datasets: [{
data: height,
pointBorderColor: color,
}]
}
});

I want to change color of individual bar of bar graph

I am getting data from mysql using php to populate the array and then using that result to fill chart data. I want to change the color of the bars which are greater than 50. I tried a few examples that are already on the stack-overflow, however I was unable to solve my problem. That is why I am now asking this question.
$(document).ready(function() {
$.ajax({
url: "http://localhost:8080/chartjs/data.php",
method: "GET",
success: function(data) {
console.log(data);
var player = [];
var score = [];
for (var i in data) {
player.push(data[i].y);
score.push(data[i].x);
}
var chartdata = {
labels: player,
datasets: [{
label: 'Records from mysql',
backgroundColor: 'rgb(92, 95, 102)',
borderColor: 'rgba(200, 200, 200, 0.75)',
hoverBackgroundColor: 'rgba(30, 0, 200)',
hoverBorderColor: 'rgba(200, 200, 197)',
data: score
}
]
};
var ctx = $("#mycanvas");
var barGraph = new Chart(ctx, {
type: 'bar',
colors: {
data: function(score) {
return (score.value >= 45) ? '#00ff00' : '#f90411';
}
},
data: chartdata
});
},
error: function(data) {
console.log(data);
}
});
});
#chart-container {
width: 640px;
height: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<div id="chart-container">
<canvas id="mycanvas"></canvas>
</div>
From what I could figure out is that your question is mostly related to the usage of chart.js. My solution to your problem would look like the following:
//Load your data (obviously this is a hardcoded example, you could use any backend code like PHP):
let data = [12, 19, 74, 38, 45, 62];
//Insantiate fields you would like to use, such as `colors` for background color and `borderColors` for, you guessed it, the color of the borders:
let colors = [];
let borderColors = [];
//Set the field values based on value (this would be your logic):
$.each(data, function(index, value) {
//When the value is higher than 45, set it to given color, else make them the other color (in the example the bars would appear red-ish):
if(value > 45) {
colors[index] = "rgba(0, 255, 0, 0.2)";
borderColors[index] = "rgba(0, 255, 1)";
}
else {
colors[index] = "rgba(249, 4, 17, 0.2)";
borderColors[index] = "rgba(249, 4, 17, 1)";
}
});
//Any code related to creating the chart with the bars (you could find any documentation regarding this code on the homepage of Chart.js):
let ctx = document.getElementById('myChart');
let myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['1', '2', '3', '4', '5', '6'],
datasets: [{
label: 'Records from mysql',
//Populate your fields here:
data: data,
backgroundColor: colors,
borderColor: borderColors,
hoverBackgroundColor: 'rgba(30, 0, 200)',
hoverBorderColor: 'rgba(200, 200, 197)',
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
#chart-container {
width: 640px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<div id="chart-container">
<canvas id="myChart"></canvas>
</div>
JSFiddle
I applied some code I found on the following post on Github:
$.each(data, function(index, value) {
//When the value is higher than 45, set it to given color, else make them the other color (in the example the bars would appear red-ish):
if(value > 45) {
colors[index] = "rgba(0, 255, 0, 0.2)";
borderColors[index] = "rgba(0, 255, 1)";
}
else {
colors[index] = "rgba(249, 4, 17, 0.2)";
borderColors[index] = "rgba(249, 4, 17, 1)";
}
});
If anyone knows a more clean solution, please let me know in the comments.

Chart.js | Trouble refreshing line chart with "setInterval"

Wondering if anyone can help me out please.
I'm having trouble getting a Chart.js LineChart (with AJAX data) to refresh every "X" seconds. I've tried to put the code below in a function inside a setInterval and eventhough it does refresh, it redraws itself in a "zoomed-in" manner...
I want the chart to refresh itself every 10 seconds.
Code:
$.ajax({
type: "POST",
url: '#Url.Action("ChartRT")',
contentType: "application/json",
dataType: "json",
success:
function (chartsdata_RT) {
var aData = chartsdata_RT;
var aLabels = aData.map(c => c.Period);
var aDatasets1 = aData.map(c => c.FAILED);
var aDatasets2 = aData.map(c => c.OTHER);
var aDatasets3 = aData.map(c => c.DELIVERED);
var aDatasets4 = aData.map(c => c.PENDING);
var dataT = {
labels: aLabels,
datasets: [
{
label: "FAILED",
data: aDatasets1,
borderColor: '#ff0000',
backgroundColor: "rgba(255, 0, 0, 0.3)",
fill: 'true'
},
{
label: "OTHER",
data: aDatasets2,
borderColor: '#3366ff',
backgroundColor: "rgba(32, 162, 219, 0.3)",
},
{
label: "DELIVERED",
data: aDatasets3,
borderColor: '#009900',
backgroundColor: "rgba(0, 102, 0, 0.3)",
},
{
label: "PENDING",
data: aDatasets4,
borderColor: '#ff9900',
backgroundColor: "rgba(255, 153, 219, 0.3)",
}
]
};
var ctx = $("#chart_last2hours").get(0).getContext("2d");
ctx.canvas.height = "50";
var myNewChart = new Chart(ctx, {
type: 'line',
data: dataT,
options: {
legend: {
display: true,
position: 'right',
fullWidth: false,
labels: {
fontColor: '#484848',
fontsize: 10,
boxWidth: 20,
padding: 5,
lineWideth: 0
}
}
}
});
}
});
ended wrapping the above code in a function (drawChartRT). I then:
1) Call the function drawChartRT() to draw the LineChart.
2) Inside a setInterval remove and add the canvas and call the function drawChartRT().
drawChartRT();
setInterval(function () {
$("canvas#chart_last2hours").remove();
$("#chartdiv_rt").append('<canvas id="chart_last2hours" height="200"></canvas>');
var div = document.getElementById("chart_last2hours");
//console.log(div);
drawChartRT();
}, 10000);
Works like a charm!
Thanks. José

Adapting a JavaScript code to be dynamic

I am kind of new in Jquery,and still learning. I am using Chart.Js in order to render data and AJAX calls.
I created a script that update a Radar Chart using a dropdown Button. The goal in mind is:
Each user is part of a team and has some data that I render in a chart. So I there is some fixed data on the chart using a fixed_array and then the user can compare the current member with other member in the team using the drop down button
I managed to do it with static data with that code but I do not know how to make it dynamic.
I imported the whole team data in the form {user_id : [data_array]} for example :
{6: [81, 68, 71, 71, 67, -72], 7: [79, 77, 86, 86, 59, -71], 8: [67, 71, 68, 68, 85, -66]}
and the current_user id with current_user = data.current_user that return the integer of the ID in this situation 6.
I made a try in a separate file in order to test the chart which look like the following:
<script type="text/javascript">
$(document).ready(function () {
// Different arrays for the different data
var array = [];
array["raphael"] = [90, 20, 80, 50, 34];
array["fraxool"] = [89, 12, 68, 89, 90];
array["johnny"] = [78, 89, 1, 90, 80];
// Default value
var fixed_array = [20, 12, 78, 50, 90];
// Chart config
var color = Chart.helpers.color;
var config = {
type: 'radar',
data: {
labels: [["label1"], "label2", "label3", "label4", "label5"],
datasets: [{
label: "Bugsy Bug 1",
backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),
borderColor: window.chartColors.red,
pointBackgroundColor: window.chartColors.red,
data: []
}, {
label: "Bugsy Bug 2",
backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),
borderColor: window.chartColors.blue,
pointBackgroundColor: window.chartColors.blue,
data: fixed_array
}]
},
options: {
legend: {
position: 'top',
display: false
},
title: {
display: false,
text: 'Fiverr Chart'
},
scale: {
ticks: {
beginAtZero: true
},
pointLabels: {
fontSize: 10,
lineHeight: 2
}
}
}
};
var mainChart = new Chart(document.getElementById("canvas"), config);
// Event for the select
$(".pick-chart").change(function (e) {
e.preventDefault();
var val = $(this).val();
if (val != 0) {
config.data.datasets[0].data = array[val];
} else {
config.data.datasets[0].data = [];
}
mainChart.update();
});
});
</script>
But my actual application is getting its data using AJAX:
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
console.log(data)
//Labels comming from wevsite.views//
info_array = data.info_array
current_user = data.current_user
</script>
right now the output of info_array is {6: [81, 68, 71, 71, 67, -72], 7: [79, 77, 86, 86, 59, -71], 8: [67, 71, 68, 68, 85, -66]}
so {user_id: [data]}
and current_user output : 6
I would like to adapt it to use dynamic data that would adapt to any size of team
Could someone help me to figure it out ?
edited code V2:
<div class="col graph-info">
<div class="card">
<h5 class="card-header text-center bg-dark text-white">Information processing</h5>
<div class="card-body">
<div class="dropdown-container">
<form>
<select id="pick-chart" class="form-control pick-chart">
<option value="0">Compare with</option>
{% for i in team_list_pop %}
<option value="{{i.id}}">{{i.first_name}} {{i.last_name}}</option>
{% endfor %}
</select>
</form>
</div>
<canvas id="info_process"></canvas>
</div>
</div>
<script>
var endpoint = 'api/chart/data'
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
console.log(data)
//Labels comming from wevsite.views//
complete_label = data.complete_label,
processing_information_label = data.processing_information_label,
motivation_label = data.motivation_label,
action_label = data.action_label,
other_data_label = data.other_data_label,
//Data comming from wevsite.views//
team_name_list2 = data.team_name_list2
info_array = data.info_array
current_user = data.current_user
team_list_id = data.team_list_id
fixed_array = info_array[current_user]
function random_color(){
var color = 'rgba(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256))+ ',' + 0.2 + ')';
return color
}
//ctx//
var ctx2 = document.getElementById("info_process").getContext('2d');
//graph 2//
var info_process = new Chart(ctx2,{
type: 'radar',
data: {
labels: processing_information_label,
datasets:[{
data: fixed_array, //processing_information_data,
backgroundColor: random_color()
},
{
backgroundColor: random_color(),
data: []
}]
},
options: {
legend: {
position: 'top',
display: false
},
scale: {
display: true,
ticks: {
beginAtZero: true,
}
},
responsive:true,
maintainAspectRatio: true,
}
});
//end graph 2//
$(".pick-chart").change(function (e) {
e.preventDefault();
var val = $(this).val();
if (val != 0) {
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
console.log(data)
//Labels coming from website.views//
info_array = data.info_array
current_user = data.current_user
config.data.datasets[0].data = info_array[val];
config.data.datasets[1].data = info_array[current_user];
mainChart.update();
}
});
} else {
config.data.datasets[0].data = [];
}
mainChart.update();
});
}
})
</script>
If you format your dropdown box as such: (so the user_id in the value of each option)
<select name="pick-chart" class="pick-chart">
<option value="6">Raphael</option>
...
</select>
You could rewrite your pick-chart.change function to something like:
$(".pick-chart").change(function (e) {
e.preventDefault();
var val = $(this).val();
if (val != 0) {
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
console.log(data)
//Labels coming from website.views//
info_array = data.info_array
current_user = data.current_user
config.data.datasets[0].data = info_array[val];
config.data.datasets[1].data = info_array[current_user];
mainChart.update();
}
});
} else {
config.data.datasets[0].data = [];
}
mainChart.update();
});
Assuming your data really is dynamic and could change while the user stays at your page. Also assuming that you want to compare current_user (which should also be a user_id) in dataset 1, like your fixed data, to a selected other user in dataset 0.

Categories