CWIS Developer Documentation

- Home
- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

Graph.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: Graph.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2002-2014 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9
10 class Graph {
11 const TYPE_DATE = 1;
12 const TYPE_DATE_BAR = 2;
13
14 const OK = 1;
15 const NO_DATA = 2;
16 const ERROR_UNKNOWN_TYPE = 3;
17
18 const DAILY = 0;
19 const WEEKLY = 1;
20 const MONTHLY = 2;
21
28 function __construct($GraphType, array $GraphData)
29 {
30 if (count($GraphData)==0)
31 {
32 $this->Status = self::NO_DATA;
33 }
34 elseif ($GraphType == self::TYPE_DATE ||
35 $GraphType == self::TYPE_DATE_BAR )
36 {
37 $this->Status = self::OK;
38 # Convert input data into a form that Javascript will deal with
39
40 if ($GraphType == self::TYPE_DATE)
41 {
42 $this->Data = $this->ToJsFormat($GraphData);
43 }
44 elseif ($GraphType == self::TYPE_DATE_BAR)
45 {
46 # Summarize the search data passed in into daily, weekly, monthly:
47 $DailyData = array();
48 $WeeklyData = array();
49 $MonthlyData = array();
50
51 foreach ($GraphData as $Xval => $Yvals)
52 {
53 $DailyTS = strtotime( date('Y-m-d', $Xval) );
54 # Find the Monday preceeding this day for the weekly TS:
55 $WeeklyTS = $DailyTS - 86400* (date('N',$Xval) - 1);
56 $MonthlyTS = strtotime( date('Y-m-01', $Xval) );
57
58 $this->AddToArray( $DailyData, $DailyTS, $Yvals );
59 $this->AddToArray( $WeeklyData, $WeeklyTS, $Yvals );
60 $this->AddToArray( $MonthlyData, $MonthlyTS , $Yvals);
61 }
62
63 $this->Data = array(
64 "Daily" => $this->ToJsFormat( $DailyData ),
65 "Weekly" => $this->ToJsFormat( $WeeklyData ),
66 "Monthly"=> $this->ToJsFormat( $MonthlyData ) );
67 }
68
69 $this->Type = $GraphType;
70
71 $this->Width = 960;
72 $this->Height = 500;
73
74 $this->LabelChars = strlen(max( array_map('max', $GraphData) ) ) ;
75
76 $this->TopMargin = 5;
77 $this->LeftMargin = 5;
78 $this->RightMargin = 50;
79 $this->BottomMargin = 40;
80
81 $this->LabelFontSize = 14;
82
83 $this->Legend = array();
84
85 $this->Scale = self::DAILY;
86 $this->Title = "";
87 }
88 else
89 {
90 $this->Status = self::ERROR_UNKNOWN_TYPE;
91 }
92 }
93
98 function Status(){ return $this->Status; }
99
104 function XLabel($Label){ $this->XLabel = $Label; }
105
110 function YLabel($Label){ $this->YLabel = $Label; }
111
116 function LabelFontSize($X){ $this->LabelFontSize = $X; }
117
122 function TopMargin($X) { $this->TopMargin = $X; }
123
128 function RightMargin($X) { $this->RightMargin = $X; }
129
134 function BottomMargin($X) { $this->BottomMargin = $X; }
135
140 function LeftMargin($X) { $this->LeftMargin = $X; }
141
146 function Width($X) { $this->Width = $X; }
147
152 function Height($X) { $this->Height = $X; }
153
158 function Legend($X) { $this->Legend = $X; }
159
164 function Scale($X) { $this->Scale = $X; }
165
170 function Title($X) { $this->Title = $X; }
171
175 function Display()
176 {
177 if ($this->Status == self::NO_DATA)
178 {
179 print $this->Title;
180 print "<p><em>No data to display</em></p>";
181 return;
182 }
183
184 if ($this->Status != self::OK)
185 return;
186
187 $ChartNumber = self::GetNumber();
188
189 global $AF;
190 ?>
191
192 <?PHP if($ChartNumber==0) { ?>
193 <script type="text/javascript" src="<?PHP $AF->PUIFile("d3.js"); ?>"></script>
194 <script type="text/javascript" src="<?PHP $AF->PUIFile("CW-Graph.js"); ?>"></script>
195 <style>
196 .cw-chart { width: 100%; }
197 .cw-chart-button { padding: 5px; margin-bottom: 15px; cursor: pointer; }
198 svg { font: 12px sans-serif;}
199 .axis { shape-rendering: crispEdges; }
200
201 .axis path, .axis line {
202 fill: none;
203 stroke-width: .5px;
204 }
205
206 .x.axis path { stroke: #000; }
207 .x.axis line { stroke: #fff; stroke-opacity: .5; }
208 .y.axis line { stroke: #ddd; }
209
210 path.line {
211 fill: none;
212 stroke-width: 1.5px;
213 }
214
215 rect.pane {
216 cursor: move;
217 fill: none;
218 pointer-events: all;
219 }
220
221 .focus circle {
222 fill: none;
223 stroke: steelblue;
224 }
225
226 .focus { fill: black; }
227
228 .line.graph_color0 { stroke: #4D7588; }
229 .line.graph_color1 { stroke: ##975078; }
230
231 .area.graph_color0 { fill: #4D7588; }
232 .area.graph_color1 { fill: #975078; }
233 .area.graph_color2 { fill: #818181; }
234 .area.graph_color3 { fill: #5CAA5C; }
235 .area.graph_color4 { fill: #DDBC6D; }
236
237 </style>
238 <?PHP } ?>
239
240 <style>
241 <?PHP if ($this->Type == self::TYPE_DATE) { ?>
242 .x-label<?PHP print($ChartNumber); ?> { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
243 .y-label<?PHP print($ChartNumber); ?> { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
244 <?PHP } elseif ($this->Type == self::TYPE_DATE_BAR) { ?>
245 .x-label<?PHP print($ChartNumber); ?>a { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
246 .y-label<?PHP print($ChartNumber); ?>a { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
247
248 .x-label<?PHP print($ChartNumber); ?>b { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
249 .y-label<?PHP print($ChartNumber); ?>b { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
250
251 .x-label<?PHP print($ChartNumber); ?>c { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
252 .y-label<?PHP print($ChartNumber); ?>c { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
253 <?PHP } ?>
254 </style>
255
256 <?PHP if ($this->Type == self::TYPE_DATE) { ?>
257 <?PHP print $this->Title; ?>
258 <div class="cw-chart" id="chart<?PHP print $ChartNumber; ?>"></div>
259 <?PHP } elseif ($this->Type == self::TYPE_DATE_BAR) { ?>
260 <div style="max-width: <?PHP print $this->Width; ?>px;">
261
262 <div>
263 <span style="float: right; margin-top: 3px; padding-right: <?PHP print $this->LabelChars + 1 ; ?>em; margin-right: <?PHP print $this->RightMargin; ?>px; ">
264 <span class="cw-chart-button" id="cw-chart-button<?PHP print $ChartNumber; ?>a"
265 <?PHP if ($this->Scale == self::DAILY) { ?> style="font-weight: bold;" <?PHP } ?>
266 >Daily</span>|
267 <span class="cw-chart-button" id="cw-chart-button<?PHP print $ChartNumber; ?>b"
268 <?PHP if ($this->Scale == self::WEEKLY) { ?> style="font-weight: bold;" <?PHP } ?>
269 >Weekly</span>|
270 <span class="cw-chart-button" id="cw-chart-button<?PHP print $ChartNumber; ?>c"
271 <?PHP if ($this->Scale == self::MONTHLY) { ?> style="font-weight: bold;" <?PHP } ?>
272 >Monthly</span>
273 </span>
274 <?PHP print $this->Title; ?>
275 </div>
276
277 <div id="chart<?PHP print $ChartNumber; ?>">
278 <div class="cw-chart" id="chart<?PHP print $ChartNumber; ?>a"
279 <?PHP if ($this->Scale != self::DAILY) { ?> style="display: none;" <?PHP } ?> ></div>
280 <div class="cw-chart" id="chart<?PHP print $ChartNumber; ?>b"
281 <?PHP if ($this->Scale != self::WEEKLY) { ?> style="display: none;" <?PHP } ?> ></div>
282 <div class="cw-chart" id="chart<?PHP print $ChartNumber; ?>c"
283 <?PHP if ($this->Scale != self::MONTHLY) { ?> style="display: none;" <?PHP } ?> ></div>
284 </div>
285 </div>
286 <script type="text/javascript">
287 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>a').click( function(){
288 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>a').css('font-weight', 'bold');
289 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>b').css('font-weight', 'normal');
290 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>c').css('font-weight', 'normal');
291 jQuery('#chart<?PHP print $ChartNumber; ?>a').show();
292 jQuery('#chart<?PHP print $ChartNumber; ?>b').hide();
293 jQuery('#chart<?PHP print $ChartNumber; ?>c').hide();
294 });
295 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>b').click( function(){
296 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>a').css('font-weight', 'normal');
297 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>b').css('font-weight', 'bold');
298 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>c').css('font-weight', 'normal');
299 jQuery('#chart<?PHP print $ChartNumber; ?>a').hide();
300 jQuery('#chart<?PHP print $ChartNumber; ?>b').show();
301 jQuery('#chart<?PHP print $ChartNumber; ?>c').hide();
302 });
303 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>c').click( function(){
304 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>a').css('font-weight', 'normal');
305 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>b').css('font-weight', 'normal');
306 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>c').css('font-weight', 'bold');
307 jQuery('#chart<?PHP print $ChartNumber; ?>a').hide();
308 jQuery('#chart<?PHP print $ChartNumber; ?>b').hide();
309 jQuery('#chart<?PHP print $ChartNumber; ?>c').show();
310 });
311 </script>
312 <?PHP } ?>
313
314 <script type="text/javascript">
315 <?PHP if ($this->Type == self::TYPE_DATE ) { ?>
316 jQuery(document).ready(function(){
317 new LineDateGraph(<?PHP print($ChartNumber); ?>,
318 <?PHP print(json_encode($this->Data)); ?>,
319 "<?PHP print($this->XLabel); ?>",
320 "<?PHP print($this->YLabel); ?>",
321 {top: <?PHP print $this->TopMargin; ?>, right: <?PHP print $this->RightMargin; ?>,
322 bottom: <?PHP print $this->BottomMargin; ?>, left: <?PHP print $this->LeftMargin; ?> },
323 <?PHP print($this->Width); ?>, <?PHP print($this->Height); ?>, <?PHP print(json_encode($this->Legend)); ?> ); });
324 <?PHP } else if ($this->Type == self::TYPE_DATE_BAR) { ?>
325 jQuery(document).ready(function(){
326 new BarDateGraph(
327 "<?PHP print($ChartNumber); ?>a",
328 <?PHP print(json_encode($this->Data["Daily"])); ?>,
329 "<?PHP print($this->XLabel); ?>",
330 "<?PHP print($this->YLabel); ?> (Daily)",
331 {top: <?PHP print $this->TopMargin; ?>, right: <?PHP print $this->RightMargin; ?>,
332 bottom: <?PHP print $this->BottomMargin; ?>, left: <?PHP print $this->LeftMargin; ?> },
333 <?PHP print($this->Width); ?>, <?PHP print($this->Height); ?>, <?PHP print(json_encode($this->Legend)); ?>,
334 <?PHP print(22*3600); ?>); });
335 jQuery(document).ready(function(){
336 new BarDateGraph(
337 "<?PHP print($ChartNumber); ?>b",
338 <?PHP print(json_encode($this->Data["Weekly"])); ?>,
339 "<?PHP print($this->XLabel); ?>",
340 "<?PHP print($this->YLabel); ?> (Weekly)",
341 {top: <?PHP print $this->TopMargin; ?>, right: <?PHP print $this->RightMargin; ?>,
342 bottom: <?PHP print $this->BottomMargin; ?>, left: <?PHP print $this->LeftMargin; ?> },
343 <?PHP print($this->Width); ?>, <?PHP print($this->Height); ?>, <?PHP print(json_encode($this->Legend)); ?>,
344 <?PHP print(7*86400); ?>); });
345 jQuery(document).ready(function(){
346 new BarDateGraph(
347 "<?PHP print($ChartNumber); ?>c",
348 <?PHP print(json_encode($this->Data["Monthly"])); ?>,
349 "<?PHP print($this->XLabel); ?>",
350 "<?PHP print($this->YLabel); ?> (Monthly)",
351 {top: <?PHP print $this->TopMargin; ?>, right: <?PHP print $this->RightMargin; ?>,
352 bottom: <?PHP print $this->BottomMargin; ?>, left: <?PHP print $this->LeftMargin; ?> },
353 <?PHP print($this->Width); ?>, <?PHP print($this->Height); ?>, <?PHP print(json_encode($this->Legend)); ?>,
354 <?PHP print(28*86400); ?>); });
355 <?PHP } ?>
356 </script>
357 <?PHP
358 }
359
360 private $Status;
361
362 private static $ChartNumber = 0;
363 private function GetNumber(){ return self::$ChartNumber++; }
364
373 private function AddToArray(&$Array, $Key, $Value)
374 {
375 if (!isset($Array[$Key]))
376 $Array[$Key] = $Value;
377 else
378 $Array[$Key] = array_map( function($a,$b){ return $a+$b; },
379 $Array[$Key], $Value );
380
381 }
382
390 private function ToJsFormat($Data, $IsDate=TRUE)
391 {
392 $Result = array();
393 foreach ($Data as $Xval => $Yvals)
394 {
395 $DataRow = array();
396
397
398 if ($IsDate)
399 $DataRow["X"] = 1000 * $Xval;
400 else
401 $DataRow["X"] = $Xval;
402
403 $Count = 0;
404 foreach ($Yvals as $Yval)
405 $DataRow[ "Y".$Count++ ] = $Yval;
406
407 $Result []= $DataRow;
408 }
409
410 return $Result;
411 }
412 }
PHP
PHP
Definition: RSSClient--Test.php:12