How to show data in a chart? - javascript

Hey there actually I am retrieving some data from database
The data is is like this format
id: "5"
p_amount: "120"
p_date: "09/20/2019"
p_id: "12345"
p_method: "Bank"
p_status: "OPEN"
This is what i did in ajax response, I convert the month of date in its name
success: function(response){
var obj=JSON.parse(response);
if(obj!=""){
$.each(obj, function(i, item) {
var selectedMonthName = months[obj[i].p_date.slice(0,2)-1];
});
}
Now i have another file of name main.js and i made a chart in javascript
(function ($) {
// USE STRICT
"use strict";
try {
//WidgetChart 1
var ctx = document.getElementById("widgetChart1");
if (ctx) {
ctx.height = 115;
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July','August','September','October','November','December'],
type: 'line',
datasets: [{
data: [0, 0, 0, 0, 0, 0, 0,0,0,0,0,0], //Here data should be added e.g, if month is september the value p_amount should add here in 8th index
label: 'Dataset',
backgroundColor: 'rgba(255,255,255,.1)',
borderColor: 'rgba(255,255,255,.55)',
},]
},
options: {
maintainAspectRatio: true,
legend: {
display: false
},
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
responsive: true,
scales: {
xAxes: [{
gridLines: {
color: 'transparent',
zeroLineColor: 'transparent'
},
ticks: {
fontSize: 2,
fontColor: 'transparent'
}
}],
yAxes: [{
display: false,
ticks: {
display: false,
}
}]
},
title: {
display: false,
},
elements: {
line: {
borderWidth: 0
},
point: {
radius: 0,
hitRadius: 10,
hoverRadius: 4
}
}
}
});
}
} catch (error) {
console.log(error);
}
})(jQuery);
Now i want when i get the month name the data(which is retrieved from DB) in other js file should be updated

We used something like this, made chart.js object global, set its data from Ajax response and called update method.
var labels = [];
var data = [];
var smallDB = {};
var lastYear = 0;
var limit = 5; // limit history to (5) years
var obj = TestData();
for (var i in obj) {
var d = new Date(obj[i].b_date);
var idy = d.getFullYear();
lastYear = Math.max(lastYear, idy)
var num = parseInt(obj[i].b_amount);
smallDB[idy] = (smallDB[idy] || 0) + num;
}
lastYear++;
for(var i=0;i<limit;i++) {
labels[i] = i+lastYear-limit;
data[i] = smallDB[i+lastYear-limit] || 0;
console.log(labels[i], data[i]);
}
function TestData() {
return [{
b_date:"11/01/2017",
b_amount:"110"
},{
b_date:"10/01/2016",
b_amount:"100"
},{
b_date:"01/01/2020",
b_amount:"200"
},{
b_date:"12/01/2018",
b_amount:"120"
}];
};
This one limits last 5 years.

Related

Chart JS custom message on tooltip, not x and y axis

I am displaying a bar chart that has 3 different pieces of information, (project name, number of days remaining, and the end date.) I am displaying the project name on one axis, and the number of days remaining determines the height of the bar. Currently, when I hover over a bar the tooltip displays the information already on the x and y axis. I want it to instead have the end date.
ie: project "b" will end in 2 days (August 4th), when I hover over the bar I want the tooltip to say "End date of 2022-08-04" instead of "b Work Days Remaining: 2"
My json of the data looks like this:
[{"po_num": "a", "days_rem": 10, "date_end": "2022-08-16"},
{"po_num": "b", "days_rem": 2, "date_end": "2022-08-04"},
{"po_num": "c", "days_rem": 6, "date_end": "2022-08-10"}]
Here is the link of the current graph.
https://i.stack.imgur.com/HefRz.png
Here is an MS paint rendering of what I am trying to do:
https://i.stack.imgur.com/GAT2I.png
The implementation code:
link = "{{{BASE_BACK_URL}}}";
$.getJSON(link, function (data) {
let po_names = [];
let days_rem = [];
for (let i = 0; i < data.length; i++) {
po_names.push(data[i]["po_num"]);
days_rem.push(data[i]["days_rem"]);
}
const ctx = document.getElementById('po-timeline-chart');
const myChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: po_names,
datasets: [{
label: 'Work Days Remaining',
data: days_rem,
backgroundColor: 'rgb(0, 89, 178)'
}],
},
options: {
legend: {
align: "end"
},
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
});
Solution listed below:
$.getJSON(link, function (data) {
let po_names = [];
let days_rem = [];
for (let i = 0; i < data.length; i++) {
po_names.push(data[i]["po_num"]);
days_rem.push(data[i]["days_rem"]);
}
const ctx = document.getElementById("po-timeline-chart");
const myChart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: po_names,
datasets: [
{
label: "Work Days Remaining",
data: days_rem,
backgroundColor: "rgb(0, 89, 178)",
},
],
},
options: {
tooltips: {
enabled: true,
callbacks: {
// To change title in tooltip
title: (data) => {
return "This PO will run out on";
},
// To change label in tooltip
label: (data) => {
return date_end[data['index']];
},
},
},
legend: {
align: "end",
},
scales: {
xAxes: [
{
ticks: {
beginAtZero: true,
},
},
],
},
},
});
});

Why parents of level 2 are linking to same child nodes either their child are different in organization Highcharts

I am using organization Highcharts in which the parents on Level 2 are linking to same childs.
As you can see in the picture Nurrettin & Mohammad Sabir nodes linked to all same child nodes. However Nurretin is a parent of Cemil Ceylan & Mustafa while M.Sabir is a parent of remaining 7 child nodes.
But issue is why Nurretin node is linked to all?
Can somebody answer it ?
Organization Highcharts
The Code is Here
renderSubordinates=(data)=>{
console.log('data',data)
var array2D =[];
var arraySeries2D =[];
var arr = [];
var levelObj;
var arrSeries = [];
const rec = (val) => {
let name = val.from;
for(let j=0;j<val.to.length;j++){
let nameChild = val.to[j].from;
array2D.push([name,nameChild])
}
return [...array2D]
}
const createHC = (data) => {
arr.push(rec(data));
if(data.to.length){
data.to.map(x=>{
arr.push(rec(x));
createHC(x);
})
}
}
var data1 = data[0];
createHC(data1);
console.log('arr',arr.pop())
var dataArr = arr.pop()
var levelInd = arr;
var levelArr =levelInd.map((x,index)=>{
// console.log('index',index);
levelObj={
level: index,
color: {
linearGradient: { x1: 0, x2: 1, y1: 0, y2: 1 },
stops: [
[0, "#0376b0"],
[1, "#b4e5fe"],
],
},
dataLabels: {
color: 'white',
style:{
fontSize:'10px'
}
}}
return levelObj
})
const seriesRec = (val) => {
let obj = {id:val.name,title:val.title,name:val.name,image:val.image,
dataLabels: {
enabled: true,
style: {
fontSize: '10px'
}
}};
arraySeries2D.push(obj)
return [...arraySeries2D]
}
const seriesHC = (data) => {
arrSeries.push(seriesRec(data));
if(data.to.length){
data.to.map(x=>{
arrSeries.push(seriesRec(x));
seriesHC(x);
})
}
}
var data1 = data[0];
seriesHC(data1);
var dataSeriesArr = arrSeries.pop()
let obj: Highcharts.Options = {
chart: {
height: 1200,
inverted: true
},
title: {
text: ''
},
series: [{
type: 'organization',
name: '',
keys: ['from', 'to'],
data: dataArr,
levels: levelArr,
nodes:dataSeriesArr,
colorByPoint: false,
color: '#007ad0',
dataLabels: {
color: 'white'
},
borderColor: '',
borderRadius:20,
nodeWidth: 120,
className:'node-class'
}],
tooltip: {
outside: true
},
plotOptions: {
organization: {
linkColor: 'gray',
linkLineWidth:2,
}
},
exporting: {
allowHTML: true,
sourceWidth: 800,
sourceHeight: 600
}
};
return obj
}

How to use a Data Array within a Chart JS dataset?

I have the following JSON, that I want to insert a chart using Chart JS:
{"Results":[{"Data":"25/02/2021","Valor":18},{"Data":"24/02/2021","Valor":2993},{"Data":"23/02/2021","Valor":1936},{"Data":"22/02/2021","Valor":1844},{"Data":"21/02/2021","Valor":1114},{"Data":"20/02/2021","Valor":1060},{"Data":"19/02/2021","Valor":1134}]}
And I created a function to load this JSON into an Array:
function ShowData(jsonObj) {
var bases = jsonObj['Results'];
var Date = [];
var Val = [];
for (var i = bases.length-1; i >= 0; i--) {
Date.push([bases[i].Data]);
Val.push([bases[i].Valor]);
}
}
When I load this Array into the Chart, As below:
var chartGraph = new Chart(ctx,{
type:'line',
data:{
labels: Date,
datasets: [
{
label: "Lbl Name",
data: Val,
borderWidth: 6,
borderColor: 'rgba(77,166,253, 0.85)',
backgroundColor: 'transparent'
}
]
},
options: {
title: {
display: true,
fontSize: 20,
text: 'Chart Name'
},
legend: {
display: true,
position: 'right',
labels: {
fontColor: '#666'
}
}
}
})
No information on "datasets" appears to me, only the "label", what is the mistake I am making?
Graphic Image
Try to split series and data, something like:
function splitData(type) {
return json.Results.map(v => v[type]);
}
// your Chart.js config
data: {
labels: splitData('Date'),
datasets: [
{
// ...otherProps,
data: splitData('Valor')
}
]
}
You cant use Date as variable name since its a build in class. Also from my testing couldnt reference the vars inside the function. But the real problem with your code is that you push an array to the val array. This made it an array containing arrays. This is not supported. If you change your code to the sample below it will work
let date = [];
let val = [];
function ShowData(jsonObj) {
var bases = jsonObj['Results'];
date = [];
val = [];
for (var i = bases.length-1; i >= 0; i--) {
date.push(bases[i].Data);
val.push(bases[i].Valor);
}
}
var chartGraph = new Chart(ctx,{
type:'line',
data:{
labels: Date,
datasets: [
{
label: "Lbl Name",
data: Val,
borderWidth: 6,
borderColor: 'rgba(77,166,253, 0.85)',
backgroundColor: 'transparent'
}
]
},
options: {
title: {
display: true,
fontSize: 20,
text: 'Chart Name'
},
legend: {
display: true,
position: 'right',
labels: {
fontColor: '#666'
}
}
}
})

Charts Js Stacked Bar Graph displays no values?

I have a javascript map like this..
var Severity = {
3M:[0, 3, 1, 0, 0],
5T:[0, 0, 1, 0, 0],
6S:[0, 0, 2, 0, 0]
}
And a JS function to call Stacked Chart Bar. Here I have a created a JS function which takes id and a map from jsp page. Map structure is same as above defined. I want to display graph where in x axis the data is the keys in map and in y axes is the stacked up data of 5 elements.
function StackedBar(id,Severity) {
var label = Object.keys(Severity); // getting the labels
var Critical = [];
var High = [];
var Medium = [];
var Low = [];
var Others = [];
for(let i=0;i<label.length;i++){ //assigning the data to arrays created
Critical.push(Severity[label[i]][0]);
High.push(Severity[label[i]][1]);
Medium.push(Severity[label[i]][2]);
Low.push(Severity[label[i]][3]);
Others.push(Severity[label[i]][4]);
}
var ctxL = document.getElementById(id).getContext('2d'); //id from the html canvas
var chart = new Chart(ctxL, {
type: 'bar',
data: {
labels: label,
datasets: [
{
label: 'Critical',
data: Critical,
backgroundColor: '#aa000e'
},
{
label: 'High',
data: High,
backgroundColor: '#e65905'
},
{
label: 'Medium',
data: Medium,
backgroundColor: '#e00ce6'
},
{
label: 'Low',
data: Low,
backgroundColor: '#b8ab16'
},
{
label: 'Others',
data: Others,
backgroundColor: '#00aaaa'
}
]
},
options: {
responsive: true,
legend: {
position: 'right'
},
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
}
}
});
}
Here graph displays and i get label in x axes...but graph values doesn't show and i get following error..
Html
<canvas id="overall"></canvas>
<script>StackedBar('overall',Overall);</script>
I wanted to know what went wrong and want me to help fix this issue...
I put the above together into one file and it works (although I had to change "Overall" to "Severity" in the call). So I'd expect that something you are using might not match your example above.
The version I used:
<html>
<body>
<canvas id="overall"></canvas>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<script>
var Severity = {
"3M": [0, 3, 1, 0, 0],
"5T": [0, 0, 1, 0, 0],
"6S": [0, 0, 2, 0, 0]
};
</script>
<script>
function StackedBar(id, Severity) {
var label = Object.keys(Severity); // getting the labels
var Critical = [];
var High = [];
var Medium = [];
var Low = [];
var Others = [];
for (let i = 0; i < label.length; i++) { //assigning the data to arrays created
Critical.push(Severity[label[i]][0]);
High.push(Severity[label[i]][1]);
Medium.push(Severity[label[i]][2]);
Low.push(Severity[label[i]][3]);
Others.push(Severity[label[i]][4]);
}
var ctxL = document.getElementById(id).getContext('2d'); //id from the html canvas
var chart = new Chart(ctxL, {
type: 'bar',
data: {
labels: label,
datasets: [
{
label: 'Critical',
data: Critical,
backgroundColor: '#aa000e'
},
{
label: 'High',
data: High,
backgroundColor: '#e65905'
},
{
label: 'Medium',
data: Medium,
backgroundColor: '#e00ce6'
},
{
label: 'Low',
data: Low,
backgroundColor: '#b8ab16'
},
{
label: 'Others',
data: Others,
backgroundColor: '#00aaaa'
}
]
},
options: {
responsive: true,
legend: {
position: 'right'
},
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
}
}
});
}
</script>
<script>StackedBar('overall', Severity);</script>
</html>

Live Update Callback -> afterTitle with Array via JSON file

I'm working on a chart, I'm live updating the Chart every 5 seconds that the data comes in. I could manage to get the info from the database and update it really easy, but I just came across a problem with involves setting a path to a part of the chart, in the case: options->tootltips->callbacks->afterTitle and inside of it create an array and pass the array from the JSON to an array inside the callback.
What I would need to do, In a really brief way is, since I already made a function to update the info from my Data and Labels, somehow I will need to make inside this function, a path to the afterTitle, than I will be able send the fifth array, in with stores the data. As you can see in my function, I could manage to do it for the data and label.
I can't have another function that updates, so basically I can't have 2 loadData(), because it makes the Chart blink every time it updates, and that's not what I'm aiming for (The chart can't blink).
Inside this patch, I made an example that didn't work, with is the //:
$.getJSON('loadchart.php', function(response) {
myLineChart.data.datasets[0].data = response[0];
myLineChart.data.datasets[1].data = response[1];
myLineChart.data.datasets[2].data = response[2];
myLineChart.data.datasets[3].data = response[3];
myLineChart.data.labels = response[4];
//The response array that I need is response[5];
//myLineChart.options.tooltips.callbacks[1] = return response[tooltipItem[0]['index']];
myLineChart.update();
});
All my Chart so you can see the path:
<script>
function loadData() {
$.getJSON('loadchart.php', function(response) {
myLineChart.data.datasets[0].data = response[0];
myLineChart.data.datasets[1].data = response[1];
myLineChart.data.datasets[2].data = response[2];
myLineChart.data.datasets[3].data = response[3];
myLineChart.data.labels = response[4];
myLineChart.update();
});
}
loadData();
setInterval(loadData, 5000);
var lbl = [];
var ctx1 = document.getElementById('mychart1').getContext('2d');
var myLineChart = new Chart(ctx1, {
type: 'line',
data: {
labels: lbl,
datasets: [
{
label: "Corrente 1",
data: [],
borderWidht: 6,
borderColor: 'red',
backgroundColor: 'transparent'
},
{
label: "Corrente 2",
data: [],
borderWidht: 6,
borderColor: 'blue',
backgroundColor: 'transparent'
},
{
label: "Corrente 3",
data: [],
borderWidht: 6,
borderColor: 'green',
backgroundColor: 'transparent'
},
{
label: "Corrente Total",
data: [],
borderWidht: 6,
borderColor: 'black',
backgroundColor: 'transparent'
},
]
},
options: {
animation:{
update: 0
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
gridLines: {
display: false
}
}]
},
title: {
display: true,
fontSize: 20,
text: "Gráfico das Correntes"
},
labels: {
fontStyle: "bold",
},
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
tooltips: {
enabled: true,
mode: 'single',
responsive: true,
backgroundColor: 'black',
titleFontFamily: "'Arial'",
titleFontSize: 14,
titleFontStyle: 'bold',
titleAlign: 'center',
titleSpacing: 4,
titleMarginBottom: 10,
bodyFontFamily: "'Mukta'",
bodyFontSize: 14,
borderWidth: 2,
borderColor: 'grey',
callbacks:{
title: function(tooltipItem, data) {
return data.labels[tooltipItem[0].index];
},
afterTitle: function(tooltipItem, data) {
var tempo = [];
return tempo[tooltipItem[0]['index']];
},
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
label += (tooltipItem.yLabel)+"A";
return label;
}
}
},
aspectRatio: 1,
maintainAspectRatio: false
}
});
</script>
The part I need is this one:
afterTitle: function(tooltipItem, data) {
var tempo = [];
return tempo[tooltipItem[0]['index']];
This will display a clock but you can also set it to 5000 seconds and call your chart update. Which i would suggest to put in some kind of AJAX to let it work asynchonous.
<!DOCTYPE html>
<html>
<head>
<script>
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = checkTime(m);
s = checkTime(s);
document.getElementById('txt').innerHTML =
h + ":" + m + ":" + s;
var t = setTimeout(startTime, 500); //<---- !!!
}
function checkTime(i) {
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
return i;
}
</script>
</head>
<body onload="startTime()">
<div id="txt"></div>
</body>
</html>
As you mention in afterTitle function you want to create an array and pass the array from the JSON to an array inside the callback, and the missing part is you are creating an array tempo and treating it like an object tempo[tooltipItem[0]['index']];, but what you need to do is push this object tooltipItem[0]['index'] to tempo array.
Please replace afterTitle function with the below code
afterTitle: function(tooltipItem, data) {
var tempo = [];
return tempo.push(tooltipItem[0]['index']);

Categories

Resources