Chart.js time series - html

Just to preface, I'm very new to code! I'm working with Chart.js to show the number of recruitment candidates generated from a marketing campaign. I'm trying to display the data generated on a weekly basis. So I'll have a start date and the x-axis will show every next week. Right now, I can only get it to show every day. Again, I'm not well versed on the topic just yet so I apologize if I'm not explaining it properly. For this example the x-axis would sat 2020/11/20, 2020/12/07, 2020/12/14 and so on. Thanks!
What I have so far
<script src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js'></script>
<canvas id="timeSeriesChart"></canvas>
<script>
Chart.defaults.global.defaultFontFamily = 'Poppins';
const ctx = document.getElementById('timeSeriesChart').getContext('2d');
const startDate = new Date(2020, 10, 30);
const labels = [];
for (let i = 0; i < 13; i++) {
const date = moment(startDate).add(i, 'days').format('YYYY/MM/DD');
labels.push(date.toString());
}
const chart = new Chart(ctx, {
type: 'line',
data: {
labels,
datasets: [{
label: 'Recruitment Candidates',
data: [4, 5, 6, 90, 56, 32, 14, 6, 72, 99],
borderWidth: 1
}]
},
options: {}
});
</script>

Welcome to the world of coding. Never mind asking questions - it's professional, and we all started one day :-)
I hope I understood correctly your need and offer a solution right away with latest version:
Chart.js v3.xx (not compatible with v2.xx)
Time Series Axis (with moment.js + adapter):
Source: https://www.chartjs.org/docs/latest/axes/cartesian/timeseries.html
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
//gets you the latest version of chart, now v3.2.1
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
//you need this adapter for timeseries to work with momentjs
<div>
<canvas id="timeSeriesChart"></canvas>
</div>
<script>
Chart.defaults.font.family = 'Poppins';
// watch out, it's not Chart.defaults.global.defaultFontFamily anymore as in v2.xx
const ctx = document.getElementById('timeSeriesChart').getContext('2d');
const startDate = new Date(2020, 10, 30);
const labels = [];
let i = 0;
//tip: declare variable `i` outside `for ()` loop - better performance
let date = new Date();
//also: declare variable `date` outside `for ()` loop
for (i; i < 13; i++) {
date = moment(startDate).add(i, 'weeks').format('YYYY/MM/DD');
//add `weeks` instead of `days` if you have weekly totals
//add `days` if you have daily totals
labels.push(date.toString());
}
const chart = new Chart(ctx, {
type: 'line',
data: {
labels,
datasets: [{
label: 'Recruitment Candidates',
data: [4, 5, 6, 90, 56, 32, 14, 6, 72, 99],
borderWidth: 1,
tension: 0.3,
fill: true
}]
},
options: {
scales: { //watch out here - new syntax in v3.xx
x: {
type: 'timeseries',
time: {
unit: 'week', //this does the trick :-)
isoWeekday: true,
// declare Monday as the first day of the week
// because in some locale, sunday would be first day of week
}
}
}
}
});
</script>
You should get following result:
Hope this helps and happy coding ...

Related

Google Charts column chart how to change vertical axis scale?

I have a column chart which I am trying to set the vertical axis scale to whole numbers i.e. 0, 1, 2... instead of 0, 0.5, 1...
Using vAxis : {format : '#'} merely rounds up the decimals, leaving duplicates i.e. 0, 1, 1, 2, 2...
Using vAxis : { gridlines : { count : 5 // for example } } does not seem to have an effect.
Ticks look like a solution but my question is what if my chart is to be dynamic? If I don't know what the max number of jobs would be, so as to set the ticks?
The last resort seems to be putting a height constraint on the chart, forcing the v-axis unit to be larger.
Thank you in advance!
to use ticks and still be dynamic,
you can use data table method getComumnRange(columnIndex)
to determine the min and max values of the y-axis values
then use those values to build the ticks array,
see following working snippet...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['category', 'value'],
['a', 1],
['b', 10],
['c', 4],
['d', 3],
['e', 7]
]);
var yAxisRange = data.getColumnRange(1);
var ticks = [];
for (var i = 0; i <= yAxisRange.max; i++) {
ticks.push(i);
}
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, {
vAxis: {
format: '0',
ticks: ticks
}
});
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

node js mysql query result rendered to chart.js labels in pug page

I've this strange behaviour when i make a get request. A query to mysql calls for totals of sells(float) group by days (nvarchar). I've made 2 arrays (for totals and datas) where i push the content of the result
router.get('/movmensili', function(req, res ,next){
if(!req.session.user){
return res.redirect('/');
}
executeQuery("SELECT SUM(price) as Totale, Data FROM db10101.10101 group by Data order
by Data", function(error, resmov){
var dateArray = [];
var totaliArray = [] ;
for (var i = 0; i<resmov.length; i++) {
dateArray.push(resmov[i].Data)
}
for (var i = 0; i<resmov.length; i++) {
totaliArray.push(resmov[i].Totale)
}
res.render('movmensili', {title: 'movs', date: (dateArray), totali: totaliArray
});
});
});
console.log(dateArray); //['2022-05-01','2022-05-02','2022-05-03','2022-05-04','2022-05-05']
console.log(totaliArray); //[ '4.00', '5.50', '3.00', '1.75', null ]
so far so good
once I open my Pug page i got to draw a bar chart with Chart.js
the two arrays used for the chart axes, contains numeric values, no problems for the sell totals, but the xlabels should be strings. So far the xlabes are 2016(=2022 minus 05 minus 01), 2015, 2014 and so on....
canvas#myChart(style='width: 100%; height: 100%; margin: 10 auto')
script.
const xlabels = [#{date}] //[2022-05-01,2022-05-02,2022-05-03,2022-05-04,2022-05-05]
const ydatas = [#{totali}] //[4.00,5.50,3.00,1.75,]
I wasn't able to convert / cast / stringify the x values to get the result needed.
Any suggestions?
David, this worked for me. Are you sure you are passing the labels correctly on render (try date: dateArray instead of date: (dateArray)). I didn't create a render function for this page so hard coded the labels and data arrays:
script.
var labels = ['2022-05-01','2022-05-02','2022-05-03','2022-05-04','2022-05-05',]
var data = {
labels: labels,
datasets: [{
label: 'My First dataset',
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: ['4.00', '5.50', '3.00', '1.75', null],
}]
};
var config = {type: 'line',data: data,options: {}};
var myChart = new Chart(document.getElementById("myChart"),config);
Not best solution, but it works....
async function GetData()
var xlabel = '#{date}';
var xlabel = xlabel.replace(/"/g, '"');
alert(xlabel);
var xlabel = xlabel.split(",");
alert(xlabel);
for(i = 0; i < xlabel.length; i += 1){
xlabel[i] = xlabel[i];
//alert(numarray[i]);
xlabels.push(xlabel[i]);
}
if I hardcode the labels in:
const xlabels = [#{date}]
instead of importing from page render, everything works fine. It's exactly that the point. The console.log of dateArray is perfectly as I would like to be in the xlabels, while once imported the quotes disappear
console.log(dateArray); // ['2022-05-01','2022-05-02','2022-05-03','2022-05-04','2022-05-05']
const xlabels = [#{date}]; // [2022-05-01,2022-05-02,2022-05-03,2022-05-04,2022-05-05]

Razor chart.js labels/data not in sync

I have a Razor application that generates three columns of data to use in a chart graph. The page and javascript to do that looks like this:
<div><canvas id="myChart"></canvas></div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
var Maanden = [];
var Totalen = [];
#foreach (var m in Model.Grafieks)
{
#:Maanden.push("#m.maand" + "-" + "#m.jaar");
#:Totalen.push(#m.Total);
}
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Maanden,
datasets: [
{ label: 'Facturen €',
data: Totalen,
backgroundColor: 'rgb(255, 255, 132)',
borderColor: 'rgb(255, 99, 132)',
borderWidth: 1,
}
]
},
});
</script>
Problem is that the labels are displayed OK but the data is off. Every second column is empty and its data pushed to the next column:
Chrome says:
Is there something wrong pushing the data into the arrays?
I had to convert the comma in decimal Totalen to a period!
#foreach (var m in Model.Grafieks)
{
#:Maanden.push("#m.maand" + "-" + "#m.jaar");
<text>bedrag = parsePotentiallyGroupedFloat("#m.Total");</text>
#:Totalen.push(bedrag);
}
function parsePotentiallyGroupedFloat(stringValue) {
stringValue = stringValue.trim();
var result = stringValue.replace(/[^0-9]/g, '');
if (/[,\.]\d{2}$/.test(stringValue)) {
result = result.replace(/(\d{2})$/, '.$1');
}
return parseFloat(result);
}
The function "parsePotentiallyGroupedFloat" is from here: Convert String with Dot or Comma as decimal separator to number in JavaScript

Google column chart showing incorrect date

I am working on google column chart. I have created 3 columns while generating charts. Here are those columns.
var dtblData = new google.visualization.DataTable();
dtblData.addColumn('string', 'Names');
dtblData.addColumn('datetime', 'Intime');
dtblData.addColumn('datetime', 'Outtime');
I am using following data to show on graph.
[{"display_name":"Aditi Badurkar
","in_time":{"year":2017,"month":6,"day":22,"hours":11,"minutes":7,"seconds":8,"miliseconds":470},"out_time":{"year":2017,"month":6,"day":22,"hours":12,"minutes":45,"seconds":44,"miliseconds":237}}]
Here is my code :-
google.charts.load('current', { 'packages': ['corechart', 'bar'] });
google.charts.setOnLoadCallback(drawStuff);
function drawStuff() {
var chartDiv = document.getElementById('chart_div');
var dtblData = new google.visualization.DataTable();
dtblData.addColumn('string', 'Names');
dtblData.addColumn('datetime', 'Intime');
dtblData.addColumn('datetime', 'Outtime');
for (var i = 0; i < data.length; i++) {
if (data[i].out_time.year == 0) {
dtblData.addRow([data[i].display_name, new Date(data[i].in_time.year, data[i].in_time.month, data[i].in_time.day, data[i].in_time.hours, data[i].in_time.minutes, data[i].in_time.seconds, data[i].in_time.miliseconds), null]);
}
else {
dtblData.addRow([data[i].display_name, new Date(data[i].in_time.year, data[i].in_time.month, data[i].in_time.day, data[i].in_time.hours, data[i].in_time.minutes, data[i].in_time.seconds, data[i].in_time.miliseconds), new Date(data[i].out_time.year, data[i].out_time.month, data[i].out_time.day, data[i].out_time.hours, data[i].out_time.minutes, data[i].out_time.seconds, data[i].out_time.miliseconds)]);
}
}
var dateinFormat = new google.visualization.DateFormat({ formatType: 'long', pattern: "dd/MM/yyyy HH:mm:ss ZZZZ" });
dateinFormat.format(dtblData, 1);
var dateOutFormat = new google.visualization.DateFormat({ formatType: 'long', pattern: "dd/MM/yyyy HH:mm:ss ZZZZ" });
dateOutFormat.format(dtblData, 2);
var materialOptions = {
//width: 900,
chart: {
title: '',
subtitle: 'Intime, Outime of your kids or staff'
},
series: {
0: { axis: 'In Time' }, // Bind series 0 to an axis named 'In Time'.
1: { axis: 'Out time' } // Bind series 1 to an axis named 'Out Time'.
},
axes: {
y: {
distance: { label: 'In Time' }, // Left y-axis.
brightness: { side: 'right', label: 'Out Time' }, // Right y-axis.
}
},
};
function drawMaterialChart() {
var materialChart = new google.charts.Bar(chartDiv);
materialChart.draw(dtblData, google.charts.Bar.convertOptions(materialOptions));
}
drawMaterialChart();
}
My problem is, on graph it is showing month as July but in data it is June. I am not getting why it is showing wrong month when I scroll mouse pointer on bar? Can someone help me to solve this? I think it might be time zone issue.
Please see screenshot.
The Month in JavaScript is Zero Based, so ranges from 0 to 11 (0 meaning January and 11 meaning December).
For your code, you may decrement the month value by 1 to solve this.
Something that may be useful:
Why does the month argument range from 0 to 11 in JavaScript's Date constructor?

Google Visualization Column Chart specify Target line as Certainty role

When i put this below code i came with on visualization playground i get the Goal/Target line, but i want it to be dashed/dotted which requires certainty role as specified in the docs. Can anyone enlighten me how to do it with a array input to Google Datatable, or Datatable json string format
Code
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([
['Year', 'Red', 'Yellow', 'Green','Target'],
['2003', 20, 0, 0,80],
['2004', 0, 55, 0,80],
['2005', 0, 0, 80,80],
['2005', 0, 0, 85,80]
]);
// Create and draw the visualization.
new google.visualization.ColumnChart(document.getElementById('visualization')).
draw(data,
{title:"Yearly Coffee Consumption by Country",
width:600, height:400,
hAxis: {title: "Year"},
legend:'none',
colors:['red','yellow','green'],
//isStacked: true,
series:{
3:{type:'steppedArea',areaOpacity:0}
}
//interpolateNulls: true
}
);
}​
Update
I got it to this level below, with the code but how do i make the line stretch graph width
function drawVisualization() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month'); // Implicit domain label col.
data.addColumn('number', 'Sales'); // Implicit series 1 data col.
data.addColumn({type:'number'}); // interval role col.
data.addColumn({type:'number'}); // interval role col.
data.addColumn({type:'number'}); // interval role col.
data.addColumn({type:'boolean',role:'certainty'}); // certainty col.
data.addRows([
['Red',20, 0,0, 80,true],
['Yellow', 0, 55, 0, 80,false],
['Green', 0, 0, 85, 80,false]
]);
// Create and draw the visualization.
new google.visualization.ColumnChart(document.getElementById('visualization')).
draw(data,
{title:"Yearly Coffee Consumption by Country",
width:600, height:400,
hAxis: {title: "Year"},
legend:'none',
colors:['red','yellow','green'],
//isStacked: true,
series:{
3:{type:'line',areaOpacity:0}
}
//interpolateNulls: true
}
);
}​
PlayGround:
https://code.google.com/apis/ajax/playground/?type=visualization#column_chart
Roles Docs:
https://developers.google.com/chart/interactive/docs/roles
So what is the right JSON format for dashed lines?
Is there any, i mean anyway i can display a arrow indicator at the right corner of the Target line to visually indicate the Goal?
You can achieve this by creating empty columns at the beginning and end of your chart, and then setting the view window to be within the range that you actually want. The code below achieves this:
function drawVisualization() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month'); // Implicit domain label col.
data.addColumn('number', 'Sales'); // Implicit series 1 data col.
data.addColumn({type:'number'}); // interval role col.
data.addColumn({type:'number'}); // interval role col.
data.addColumn({type:'number'}); // interval role col.
data.addColumn({type:'boolean',role:'certainty'}); // certainty col.
data.addRows([
['', null, null, null, 80, false],
['Red',20, 0,0, 80,true],
['Yellow', 0, 55, 0, 80,false],
['Green', 0, 0, 85, 80,false],
['', null, null, null, 80, true]
]);
// Create and draw the visualization.
new google.visualization.ColumnChart(document.getElementById('visualization')).
draw(data,
{title:"Yearly Coffee Consumption by Country",
width:600, height:400,
hAxis: {title: "Year"},
legend:'none',
colors:['red','yellow','green'],
//isStacked: true,
series:{
3:{type:'line',areaOpacity:0}
},
hAxis: {
viewWindow: {
min: 1,
max: 4
}
}
//interpolateNulls: true
}
);
}
​