Skip to content
This repository was archived by the owner on Mar 30, 2024. It is now read-only.

Commit f6a9f88

Browse files
committed
Add a new chart
1 parent 6924b27 commit f6a9f88

File tree

2 files changed

+154
-1
lines changed

2 files changed

+154
-1
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
latest
2-
0.4.0
2+
0.4.1
33
0.4
44
0

php/load/graphs/BarWeeks.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
function createGraph(combiData, plainData, singleDayData, canvas){
2+
/**
3+
* The DOM has jQuery as $ and the ChartJS library.
4+
* The data can be found in the three first data parameters and canvas is the canvas for the chart.
5+
* The function should return the ChartJS object.
6+
*/
7+
function getLabelFromTimestamp(t) {
8+
let date = new Date(t * 1000);
9+
10+
// month and year
11+
let month = date.getMonth() + 1
12+
let year = date.getFullYear()
13+
14+
// monday of week (day - weekday)
15+
var dayMap = {
16+
0:6,
17+
1:0,
18+
2:1,
19+
3:2,
20+
4:3,
21+
5:4,
22+
6:5,
23+
}
24+
let monday = date.getDate() - dayMap[date.getDay()]
25+
if( monday < 1 ){ // begin of month, monday was last month
26+
month--;
27+
28+
let daysPerMonth = [31, 31,(( year % 400) == 0 || ((year % 4) == 0 && (year % 100) != 0) ? 29 : 28 ), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
29+
monday += daysPerMonth[month];
30+
}
31+
if( month < 1 ){ // now january and monday in december?
32+
year--;
33+
month = 12
34+
}
35+
36+
return `${monday}.${month}.${year}`;
37+
}
38+
39+
// get time span and all categories
40+
var minDate = Number.MAX_SAFE_INTEGER;
41+
var maxDate = Number.MIN_SAFE_INTEGER;
42+
var allCategories = {}
43+
var allNames = {}
44+
plainData.forEach(data => {
45+
if( data.begin < minDate ){
46+
minDate = data.begin;
47+
}
48+
if( data.end > maxDate ){
49+
maxDate = data.end;
50+
}
51+
if( !allCategories.hasOwnProperty(data.category)){
52+
allCategories[data.category] = 0;
53+
}
54+
if( !allNames.hasOwnProperty(data.name)){
55+
allNames[data.name] = 0;
56+
}
57+
});
58+
if(Object.keys(allCategories).length === 1){
59+
var catsColumn = 'name';
60+
var allCats = allNames;
61+
}
62+
else{
63+
var catsColumn = 'category';
64+
var allCats = allCategories;
65+
}
66+
67+
// fill (empty) categories in each day
68+
let plotdata = {};
69+
let plotdataLabels = [];
70+
for( let timestamp = minDate; timestamp <= maxDate; timestamp += 604800){
71+
let label = getLabelFromTimestamp(timestamp);
72+
plotdata[label] = Object.assign({}, allCats);
73+
plotdataLabels.push(label)
74+
}
75+
let lastLabel = getLabelFromTimestamp(maxDate);
76+
if( !plotdata.hasOwnProperty(lastLabel)){
77+
plotdata[lastLabel] = Object.assign({}, allCats);
78+
plotdataLabels.push(lastLabel)
79+
}
80+
81+
// fill with data
82+
plainData.forEach(data => {
83+
plotdata[getLabelFromTimestamp(data.begin)][data[catsColumn]] += data.duration;
84+
});
85+
86+
// convert to hours
87+
Object.keys(plotdata).forEach(function(label) {
88+
Object.keys(plotdata[label]).forEach(function(category) {
89+
plotdata[label][category] = Math.round((plotdata[label][category] / 3600) * 100) / 100;
90+
});
91+
});
92+
93+
/**
94+
* Colors from
95+
* chartjs-plugin-colorschemes MIT License
96+
* Copyright (c) 2019 Akihiko Kusanagi
97+
* https://github.com/nagix/chartjs-plugin-colorschemes/blob/master/src/colorschemes/colorschemes.tableau.js
98+
*/
99+
const baseColors = ['#4E79A7', '#A0CBE8', '#F28E2B', '#FFBE7D', '#59A14F', '#8CD17D', '#B6992D', '#F1CE63', '#499894', '#86BCB6', '#E15759', '#FF9D9A', '#79706E', '#BAB0AC', '#D37295', '#FABFD2', '#B07AA1', '#D4A6C8', '#9D7660', '#D7B5A6'];
100+
101+
var categoryDatasetIdMap = {};
102+
var chartData = {
103+
labels : plotdataLabels,
104+
datasets: []
105+
};
106+
107+
var datasetIndex = 0;
108+
plotdataLabels.forEach(function(label) {
109+
Object.keys(plotdata[label]).forEach(function(category) {
110+
if(!categoryDatasetIdMap.hasOwnProperty(category)){
111+
categoryDatasetIdMap[category] = datasetIndex;
112+
chartData.datasets.push({
113+
label : category,
114+
backgroundColor: baseColors[datasetIndex % baseColors.length],
115+
data: []
116+
});
117+
datasetIndex++;
118+
}
119+
chartData.datasets[categoryDatasetIdMap[category]].data.push(
120+
plotdata[label][category]
121+
);
122+
});
123+
});
124+
125+
let config = {
126+
type: 'bar',
127+
data: chartData,
128+
options: {
129+
responsive: true,
130+
tooltips: {
131+
callbacks: {
132+
label: function(tooltipItem, chartData) {
133+
return `${chartData.datasets[tooltipItem.datasetIndex].label} ${chartData.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]} hours`;
134+
},
135+
title : function(tooltipItem, chartData) {
136+
return tooltipItem[0].label + ': '+ Math.round(chartData.datasets.reduce((p,c) => p + c.data[tooltipItem[0].index], 0) * 100) / 100 + ' hours';
137+
}
138+
}
139+
},
140+
scales: {
141+
xAxes: [{
142+
stacked: true,
143+
beginAtZero: true
144+
}],
145+
yAxes: [{
146+
stacked: true
147+
}]
148+
}
149+
}
150+
};
151+
152+
return new Chart(canvas, config);
153+
}

0 commit comments

Comments
 (0)