Chart.js group data by month\year - chart.js

I have such chart with some dates with days https://jsfiddle.net/wvtfe6sr/
var ctx = $("#myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['2019-04-10','2019-04-20','2019-05-11','2019-05-21','2019-06-12','2019-06-22'],
datasets: [{
label: '#1',
data: [
{x:'2019-04-10', y:1},
{x:'2019-04-20', y:2},
{x:'2019-05-10', y:3},
{x:'2019-05-20', y:4},
{x:'2019-06-12', y:5},
{x:'2019-06-22', y:6}
],
}]
}
});
Is possible to group this data by month\year using just chart functional? Like in excel
For example group by month will generate such chart https://jsfiddle.net/1o2xfa57/
With 3 months with sum of all days of each month
Also group by year will generate one dot with value 21

You will have to do the group by outside of Chart.js yourself before passing the data in

Related

Chartjs - Fill dates between given labels

I've been experimenting with Chartjs for several hours now and I'm not sure if this is possible. I have some data that is sorted date wise but not all dates are included. For example:
const salesChart = new Chart(document.getElementById('graph-sales'),
{
type: 'line',
data: {
labels: ['Aug 23','Aug 26','Aug 31','Sep 02'],
datasets: [{
label: 'Sales',
borderColor: '#ccc',
data: [2750.00,1100.00,3080.00,4320.00],
}]
}
}
);
Chartjs plots this data as 4 datapoints and joins them with a line like so
This is fine, but I want intermediate days to be added on the chart with datapoint value being 0. So essentially it would be like passing this data:
labels: ['Aug 23','Aug 24','Aug 25','Aug 26','Aug 27','Aug 28','Aug 29','Aug 30','Aug 31','Sep 01','Sep 02'],
datasets: [{
label: 'Sales',
borderColor: '#ccc',
data: [2750.00,0,0,1100.00,0,0,0,0,3080.00,0,4320.00],
}]
I've looked into timescales but can't get them to work. The docs says I need a time adapter but there's no example of it in use so I'm not sure what that means.
It would probably be easier to do this on the backend serving up the data; but this code works if you want to do it in JavaScript on the frontend.
My method was to use a defined self-executing function which returns an array containing two arrays.
The first array is called finalLabels and contains all date strings between, and including, the dates provided in the original labels.
Which gives us ['Aug 23', 'Aug 24', 'Aug 25', 'Aug 26', 'Aug 27', 'Aug 28', 'Aug 29', 'Aug 30', 'Aug 31', 'Sep 01', 'Sep 02']
The second returned array is called finalDatas and contains all of the original data values at the same index of the original label; and a value of zero where the value wasn't previously defined.
Which gives us: [2750, 0, 0, 1100, 0, 0, 0, 0, 3080, 0, 4320]
Working Codepen: https://codepen.io/vpolston/pen/NWMgwOw
My account doesn't have ability to embed pictures, but this is what you end up with: image of final chart created.
JS
const labels = ['Aug 23','Aug 26','Aug 31','Sep 02'];
const data = [2750.00,1100.00,3080.00,4320.00];
const datasets = (function () {
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul","Aug", "Sep", "Oct", "Nov", "Dec"];
/* define start and end date from labels and create date objects */
const startDateString = labels[0];
const endDateString = labels[labels.length - 1];
const startDateObj = new Date(startDateString);
const endDateObj = new Date(endDateString);
/* create empty dates array to hold dates within range */
let dates = [];
/*
create currentDateObj var to increment in while loop
loop through, add currentDateObj to array, increment until false
*/
let currentDateObj = new Date(startDateString);
while( currentDateObj <= endDateObj ){
/* format date to match the provided label and push to dates array */
let dateString = currentDateObj.toDateString();
let month = months[currentDateObj.getMonth()];
let day = currentDateObj.getDate();
if( day < 10 ){
day = '0' + day
};
let date = month + ' ' + day;
dates.push(date);
/* increment CurrentDateObj */
currentDateObj.setDate(currentDateObj.getDate() + 1);
};
/*
use counter to loop through original datas
*/
let valueExistsCounter = 0;
let finalLabels = [];
let finalDatas = [];
for( const [index, date] of dates.entries() ){
if( labels.includes(date) ){
/* if date was provided in labels get the data value */
finalLabels.push(date);
finalDatas.push(data[valueExistsCounter]);
valueExistsCounter += 1
} else {
/* set date value to 0 */
finalLabels.push(date);
finalDatas.push(0);
}
};
return [finalLabels, finalDatas]
}());
const finalLabels = datasets[0];
const finalDatas = datasets[1];
/* now we can build the chart */
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: finalLabels,
datasets: [{
label: 'Sales',
'fill': true,
borderColor: '#ccc',
backgroundColor: 'rgba(204,204,204,0.5)',
tension: 0.2,
data: finalDatas
}]
},
options: {
scales: {
x: {
grid: {
color: 'rgba(204,204,204,0.1)'
}
},
y: {
grid: {
color: 'rgba(204,204,204,0.1)'
}
}
}
}
});
HTML
<!-- Canvas -->
<div class="chartContainer">
<canvas id="myChart"></canvas>
</div>
<!-- include Chart.js 3.9.1 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.js" integrity="sha512-d6nObkPJgV791iTGuBoVC9Aa2iecqzJRE0Jiqvk85BhLHAPhWqkuBiQb1xz2jvuHNqHLYoN3ymPfpiB1o+Zgpw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
CSS
body {
background-color: #0d1117;
}
.chartContainer {
width: 800px;
height: 400px;
}
I think that covers it? If that was helpful please mark answered.

How to compare one value to another in chartJS

I have been working on a broadband management website.I want to show the user how much data he/she has used.For example if the total data they have in their name is 300GB.If they have used 150GB the remaining is 150GB right?.How to do i visualize this using a doughnut chart,Using ChartJS.
I have some code going but im not sure how to accomplish this please help me out
var ctx = document.getElementById('myChart').getContext('2d');
var constdata=document.getElementById("constantdata").textContent;
var data=document.getElementById("data").textContent;
console.log(data);
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'doughnut',
// The data for our dataset
data: {
datasets: [{
label: 'My First dataset',
backgroundColor: ['red','green'],
borderColor: 'rgb(255, 99, 132)',
data: [300,150] //300 being the total data,150 being the data used
}]
},
// Configuration options go here
options: {}
But the above code isnt working out.Assume a doughnut chart,If the used data is 150GB(out of 300).The doughnut
chart must be like image1(please refer image 1)
But im getting image2(please refer image 2)
https://i.stack.imgur.com/nFTym.png //image 1
https://i.stack.imgur.com/MG99s.png //image 2
Assuming that the used data should appear in red, data should be defined as follows:
data: [used, total - used]
Please have a look at your amended code sample below.
const total = 300;
const used = 100;
var chart = new Chart(document.getElementById('myChart'), {
type: 'doughnut',
data: {
datasets: [{
label: 'My First dataset',
backgroundColor: ['red', 'green'],
borderColor: 'rgb(255, 99, 132)',
data: [used, total - used]
}]
},
options: {}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="myChart" height="90"></canvas>

chart.js scatter chart- datasets data in array not showing data [duplicate]

I wish to pass values of an array to the data and label fields of the chart.js dataset.
Here the code from success of ajax call made to fetch json data. I fetch the json data and store it into an array.
Data = jQuery.parseJSON(result);
var count = Data.length;
var counter = 0;
while(count > 0) {
LabelResult[counter] =[Data[counter].TIME];
counter++;
count --;
}
Now i wish to use this label values into the labels filed.
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [LabelResult],
datasets: [{
label: '# of Votes',
data: [DataResult],
borderWidth: 1
}]
}
});
But there seems some issue and the data is not getting rendered on the chart
LabelResult is an array, change
labels: [LabelResult]
to
labels: LabelResult
Also:
data: [DataResult]
to
data: DataResult
Like:
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: LabelResult,
datasets: [{
label: '# of Votes',
data: DataResult,
borderWidth: 1
}]
}
});
I think you could try to remove some brackets.
while(count > 0){
LabelResult[counter] = Data[counter].TIME; // here removed brackets
counter++;
count --;
}
and
data: {
labels: LabelResult, // here removed brackets
datasets: [{
label: '# of Votes',
data: DataResult, // here removed brackets
borderWidth: 1
}]
},
I hope that will works.

How to add a second set of labels to a Chart.js doughnut chart?

I have a doughnut graph created using Chart.js with two datasets. The graph displays the number of employees in offices around the world, with the second dataset breaking this down into permanent and contract employees.
There's a jsfiddle of this running here: https://jsfiddle.net/tetsujin1979/tt3ch8z7/
The "labels" attribute of the options for the graph contains the names of the offices, but since there is only one array of labels, they are repeated for the second dataset, and appear on the mouseover text for it.
var config = {
type: 'doughnut',
data: {
datasets: [
{
data: [124,231,152,613,523],
backgroundColor: [chartColors.red, chartColors.orange, chartColors.yellow, chartColors.green, chartColors.blue],
label: 'Offices'
},
{
data: [60,64,100,131,71,81,337,276,405,118],
backgroundColor: [chartColors.purple, chartColors.grey],
label: 'Permanent/Contract'
}
],
labels: ['London', 'New York', 'Paris', 'Moscow', 'Mumbai']
}
};
var ctx = document.getElementById('employees-graph').getContext('2d');
var employeesGraph = new Chart(ctx, config);
Is it possible to specify a second array of labels for the permanent/contract dataset so the hover text displays the values from this second
Add a labels array to both of the datasets
var config = {
type: 'doughnut',
data: {
datasets: [
{
data: [124,231,152,613,523],
backgroundColor: [chartColors.red, chartColors.orange, chartColors.yellow, chartColors.green, chartColors.blue],
label: 'Offices',
labels: ['London', 'New York', 'Paris', 'Moscow', 'Mumbai']
},
{
data: [60,64,100,131,71,81,337,276,405,118],
backgroundColor: [chartColors.purple, chartColors.grey],
label: 'Permanent/Contract',
labels: ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
}
]
}
};
And add the following to the options:
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var index = tooltipItem.index;
return dataset.labels[index] + ": " + dataset.data[index];
}
}
}
}

google chart api material date month

I have a google bar chart with multiple series and a date hAxis.
My problem is that i want to show months only, but i get the label multiple times.
Here's an example
google.charts.load('current', {'packages': ['bar'], 'language': 'de'});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var chart;
var chartDiv = document.getElementById('test');
var data = new google.visualization.DataTable('{"cols":[{"type":"date","pattern":""},{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"}],"rows":[{"c":[{"v":"Date(2016,2,1)"},{"v":2030,"f":"2030 km"},{"v":2098,"f":"2098 km"},{"v":1352,"f":"1352 km"},{"v":4412,"f":"4412 km"},{"v":132,"f":"132 km"},{"v":2435,"f":"2435 km"},{"v":3952,"f":"3952 km"}]},{"c":[{"v":"Date(2016,3,1)"},{"v":3177,"f":"3177 km"},{"v":2901,"f":"2901 km"},{"v":2491,"f":"2491 km"},{"v":1480,"f":"1480 km"},{"v":2272,"f":"2272 km"},{"v":400,"f":"400 km"},{"v":1096,"f":"1096 km"}]}]}');
var options = {
legend: { position: 'none' },
hAxis: {
type: 'category',
format: 'MMMM'
}
};
chart = new google.charts.Bar(chartDiv);
chart.draw(data, google.charts.Bar.convertOptions(options));
}
https://jsfiddle.net/1Lusd06n/3/
If i shrink the width of the fiddle, the month names are grouped and displayed once but this does not happen if there is more space.