Skip to content

Commit 3255b09

Browse files
author
Ahmad Gneady
committed
Add Projects chart.
Add label to left column in both charts.
1 parent 70bf21b commit 3255b09

File tree

4 files changed

+251
-9
lines changed

4 files changed

+251
-9
lines changed

app/hooks/chart-projects.php

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
<?php
2+
define('PREPEND_PATH', '../');
3+
$appDir = dirname(__DIR__);
4+
include("$appDir/lib.php");
5+
6+
// config
7+
$chart = [
8+
'dayWidth' => .2,
9+
'projectHeight' => 5,
10+
'left' => 19,
11+
'top' => 22,
12+
'projectSeparator' => .3,
13+
'colors' => [
14+
'#FFC57F', '#B9FF7F', '#7FFFC5', '#7FB9FF', '#C47FFF', '#FF7FB9', '#D8984B', '#8BD84B', '#4BD898', '#4B8BD8', '#984BD8', '#D84B8B', '#D8B68C', '#AFD88C', '#8CD8B6', '#8CAFD8', '#B68CD8', '#D88CAF'
15+
],
16+
];
17+
18+
// some initilization
19+
$project = $projectColor = $proejectIndex = [];
20+
21+
// chart parameters
22+
$year = intval($_GET['year']);
23+
if(!$year) $year = date('Y');
24+
25+
$startDate = "$year-01-01";
26+
$endDate = "$year-12-31";
27+
28+
// get projects that are active during specified year
29+
$eo = ['silentErrors' => true];
30+
$res = sql("SELECT `Id`, `Name`, `StartDate`, `EndDate` FROM `projects` WHERE NOT `StartDate`>'$endDate' AND NOT `EndDate`<'$startDate'", $eo);
31+
$i = 0;
32+
while($row = db_fetch_assoc($res)) {
33+
$projectIndex[] = $row['Id'];
34+
$project[$row['Id']] = $row;
35+
$projectColor[$row['Id']] = $chart['colors'][$i++];
36+
}
37+
38+
// invert projectIndex so that we can retrieve the 1-based index of a project given project id
39+
$projectIndex = array_flip($projectIndex);
40+
41+
42+
/*******************************************************
43+
View code begins below
44+
TODO: the code below is in need of serious refactoring
45+
*******************************************************/
46+
include_once("$appDir/header.php");
47+
48+
// Years navigator
49+
$prevYear = $year - 1;
50+
$nextYear = $year + 1;
51+
?>
52+
53+
<script>
54+
$j(function() {
55+
// hide today button if not current year
56+
let showToday = false;
57+
try {
58+
showToday = parseInt(location.search.match(/year=(\d+)/)[1]) == (new Date).getFullYear();
59+
} catch(e) {
60+
showToday = true; // if no year in url, this means we're displaying current year
61+
}
62+
63+
$j('.toggle-today')
64+
.toggleClass('hidden', !showToday)
65+
.on('click', function() {
66+
let btn = $j(this), activate = btn.hasClass('btn-default');
67+
68+
btn
69+
.toggleClass('btn-info', activate)
70+
.toggleClass('btn-default', !activate)
71+
72+
$j('.today-line').toggleClass('hidden', !activate);
73+
})
74+
})
75+
</script>
76+
77+
<div class="page-header" style="position: absolute; left: 10vw; top: 3vh; width: 80vw;"><h1 class="text-center">
78+
<a class="btn btn-default btn-lg hspacer-lg" href="chart-projects.php?year=<?php echo $prevYear; ?>"><?php echo $prevYear; ?></a>
79+
<?php echo $year; ?>
80+
<a class="btn btn-default btn-lg hspacer-lg" href="chart-projects.php?year=<?php echo $nextYear; ?>"><?php echo $nextYear; ?></a>
81+
82+
<button type="button" class="btn btn-default pull-right toggle-today hidden-print" style="margin-top: 3vh;"><i class="glyphicon glyphicon-eye-open"></i> Today</button>
83+
</h1></div>
84+
85+
<div class="chart-area">
86+
<?php
87+
88+
// Display 'Project' header
89+
?>
90+
<div
91+
class="label-header"
92+
style="
93+
position: absolute;
94+
height: <?php echo ((count($project) + 1) * ($chart['projectHeight'] + $chart['projectSeparator'])); ?>vh;
95+
top: <?php echo ($chart['top'] + $chart['projectHeight'] + $chart['projectSeparator']); ?>vh;
96+
font-family: Arial; font-size: 12px; font-weight: bold;
97+
">
98+
Project
99+
</div>
100+
101+
<?php
102+
103+
// Display month grid lines
104+
$prevLeft = $chart['left'] ?? 0;
105+
$thisMonth = date('n');
106+
$thisYear = date('Y');
107+
for($m = 1; $m <= 12; $m++) {
108+
$daysPerMonth = date('t', strtotime("$year-$m-01"));
109+
?>
110+
<div
111+
class="month-label"
112+
style="
113+
position: absolute;
114+
left: <?php echo $prevLeft; ?>vw;
115+
height: <?php echo ((count($project) + 1) * ($chart['projectHeight'] + $chart['projectSeparator'])); ?>vh;
116+
border-left: dotted 1px Silver;
117+
<?php if($m == 12) { ?>border-right: dotted 1px Silver;<?php } ?>
118+
top: <?php echo ($chart['top'] + $chart['projectHeight'] + $chart['projectSeparator']); ?>vh;
119+
text-align: center;
120+
font-family: Arial; font-size: 10px; font-weight: bold;
121+
width: <?php echo ($daysPerMonth * $chart['dayWidth']); ?>vw;
122+
">
123+
<?php echo date('M Y', strtotime("$year-$m-01")); ?>
124+
</div>
125+
<?php
126+
127+
// today line
128+
if($year == $thisYear && $m == $thisMonth) {
129+
?>
130+
<div
131+
class="today-line hidden"
132+
title="Today, <?php echo date('j/n/Y'); ?>"
133+
style="
134+
border-left: solid 2px DarkRed;
135+
position: absolute;
136+
top: <?php echo ($chart['top'] + ($chart['projectHeight'] + $chart['projectSeparator']) * 1.5); ?>vh;
137+
left: <?php echo ($prevLeft + (date('j') - 1) * $chart['dayWidth']); ?>vw;
138+
height: <?php echo ((count($project) + 0.5) * ($chart['projectHeight'] + $chart['projectSeparator'])); ?>vh;
139+
z-index: 2;
140+
"></div>
141+
<?php
142+
}
143+
144+
$prevLeft += $daysPerMonth * $chart['dayWidth'];
145+
}
146+
147+
148+
// Display project names
149+
foreach($project as $projectId => $prj) {
150+
$i = $projectIndex[$projectId] + 1;
151+
?><div
152+
class="project"
153+
style="
154+
position: absolute;
155+
top: <?php echo ($chart['projectHeight'] * ($i + 1) + $chart['top'] + $i * $chart['projectSeparator']); ?>vh;
156+
border-bottom: solid 1px Silver;
157+
width: <?php echo (365 * $chart['dayWidth'] + $chart['left']); ?>vw;
158+
height: <?php echo intval($chart['projectHeight']); ?>vh;
159+
font-family: Arial;
160+
font-size: 12px;
161+
">
162+
<a
163+
href="../projects_view.php?SelectedID=<?php echo $projectId; ?>"
164+
><?php echo $prj['Name']; ?></a>
165+
</div>
166+
<?php
167+
}
168+
169+
170+
// Display project duration bars
171+
$yearStartTS = strtotime(date("$year-01-01"));
172+
$yearEndTS = strtotime(date("$year-12-31 23:59:59"));
173+
foreach($project as $id => $prj){
174+
$i = $projectIndex[$id] + 1;
175+
$chartStartTS = max(strtotime($prj['StartDate']), $yearStartTS);
176+
$chartEndTS = min(strtotime($prj['EndDate']), $yearEndTS);
177+
?><div
178+
style="
179+
position: absolute;
180+
width: <?php echo intval(($chartEndTS - $chartStartTS + 86400) / 86400 * $chart['dayWidth']); ?>vw;
181+
left: <?php echo intval(($chartStartTS - strtotime("$year-01-01")) / 86400 * $chart['dayWidth'] + $chart['left']); ?>vw;
182+
height: <?php echo intval($chart['projectHeight']); ?>vh;
183+
background-color: <?php echo $projectColor[$id]; ?>;
184+
top: <?php
185+
echo (
186+
$chart['top'] +
187+
$chart['projectHeight'] * ($i + 1) +
188+
$i * $chart['projectSeparator']
189+
); ?>vh;
190+
cursor: pointer;
191+
text-align: center;
192+
font-size: 10px;
193+
font-family: Arial;
194+
color: #004 !important;
195+
font-weight: bold;
196+
opacity: 0.5;
197+
filter:alpha(opacity=50);
198+
white-space:nowrap;
199+
overflow:hidden;
200+
"
201+
title="<?php echo htmlspecialchars($prj['Name']); ?> from <?php echo date('j/n/Y', strtotime($prj['StartDate'])); ?> to <?php echo date('j/n/Y', strtotime($prj['EndDate'])); ?>"
202+
onclick="window.location='../projects_view.php?SelectedID=<?php echo $id; ?>';">
203+
<?php echo $prj['Name']; ?>
204+
</div><?php
205+
}
206+
207+
?></div><?php
208+
209+
include_once("$appDir/footer.php");

app/hooks/chart.php renamed to app/hooks/chart-resources.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,31 @@
113113
</script>
114114

115115
<div class="page-header" style="position: absolute; left: 10vw; top: 3vh; width: 80vw;"><h1 class="text-center">
116-
<a class="btn btn-default btn-lg hspacer-lg" href="chart.php?year=<?php echo $prevYear; ?>"><?php echo $prevYear; ?></a>
116+
<a class="btn btn-default btn-lg hspacer-lg" href="chart-resources.php?year=<?php echo $prevYear; ?>"><?php echo $prevYear; ?></a>
117117
<?php echo $year; ?>
118-
<a class="btn btn-default btn-lg hspacer-lg" href="chart.php?year=<?php echo $nextYear; ?>"><?php echo $nextYear; ?></a>
118+
<a class="btn btn-default btn-lg hspacer-lg" href="chart-resources.php?year=<?php echo $nextYear; ?>"><?php echo $nextYear; ?></a>
119119

120120
<button type="button" class="btn btn-default pull-right toggle-today hidden-print" style="margin-top: 3vh;"><i class="glyphicon glyphicon-eye-open"></i> Today</button>
121121
</h1></div>
122122

123123
<div class="chart-area">
124124
<?php
125-
125+
126+
// Display 'Resource' header
127+
?>
128+
<div
129+
class="label-header"
130+
style="
131+
position: absolute;
132+
height: <?php echo ((count($resource) + 1) * ($chart['resourceHeight'] + $chart['resourceSeparator'])); ?>vh;
133+
top: <?php echo ($chart['top'] + $chart['resourceHeight'] + $chart['resourceSeparator']); ?>vh;
134+
font-family: Arial; font-size: 12px; font-weight: bold;
135+
">
136+
Resource
137+
</div>
138+
139+
<?php
140+
126141
// Display month grid lines
127142
$prevLeft = $chart['left'] ?? 0;
128143
$thisMonth = date('n');

app/hooks/links-home.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,24 @@
1414
);
1515
*/
1616

17-
$homeLinks[] = array(
18-
'url' => 'hooks/chart.php',
17+
$homeLinks[] = [
18+
'url' => 'hooks/chart-resources.php',
1919
'title' => 'Resources Utilization Chart',
2020
'description' => 'Visualize the utilization of resources accross projects.',
2121
'groups' => array('*'), // groups allowed to see this link, use '*' if you want to show the link to all groups
2222
'grid_column_classes' => 'col-xs-12 col-lg-6', // optional CSS classes to apply to link block. See: http://getbootstrap.com/css/#grid
2323
'panel_classes' => 'panel-info', // optional CSS classes to apply to panel. See: http://getbootstrap.com/components/#panels
2424
'link_classes' => 'btn-info', // optional CSS classes to apply to link. See: http://getbootstrap.com/css/#buttons
2525
'icon' => 'images/chart_bar.png' // optional icon to use with the link
26-
);
26+
];
27+
28+
$homeLinks[] = [
29+
'url' => 'hooks/chart-projects.php',
30+
'title' => 'Projects Chart',
31+
'description' => 'Chart of project schedules.',
32+
'groups' => array('*'), // groups allowed to see this link, use '*' if you want to show the link to all groups
33+
'grid_column_classes' => 'col-xs-12 col-lg-6', // optional CSS classes to apply to link block. See: http://getbootstrap.com/css/#grid
34+
'panel_classes' => 'panel-info', // optional CSS classes to apply to panel. See: http://getbootstrap.com/components/#panels
35+
'link_classes' => 'btn-info', // optional CSS classes to apply to link. See: http://getbootstrap.com/css/#buttons
36+
'icon' => 'images/chart_bar.png' // optional icon to use with the link
37+
];

app/hooks/links-navmenu.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,16 @@
1010
);
1111
*/
1212

13-
$navLinks[] = array(
14-
'url' => 'hooks/chart.php',
13+
$navLinks[] = [
14+
'url' => 'hooks/chart-resources.php',
1515
'title' => 'Resources Utilization Chart',
1616
'groups' => array('*'), // groups allowed to see this link, use '*' if you want to show the link to all groups
1717
'icon' => 'images/chart_bar.png'
18-
);
18+
];
19+
20+
$navLinks[] = [
21+
'url' => 'hooks/chart-projects.php',
22+
'title' => 'Projects Chart',
23+
'groups' => array('*'), // groups allowed to see this link, use '*' if you want to show the link to all groups
24+
'icon' => 'images/chart_bar.png'
25+
];

0 commit comments

Comments
 (0)