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
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
// 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 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.
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é
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.