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-2017 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9
10 class Graph
11 {
12 const TYPE_DATE = 1;
13 const TYPE_DATE_BAR = 2;
14
15 const OK = 1;
16 const NO_DATA = 2;
17 const ERROR_UNKNOWN_TYPE = 3;
18
19 const DAILY = 0;
20 const WEEKLY = 1;
21 const MONTHLY = 2;
22
29 public function __construct($GraphType, array $GraphData)
30 {
31 if (count($GraphData)==0)
32 {
33 $this->Status = self::NO_DATA;
34 }
35 elseif ($GraphType == self::TYPE_DATE ||
36 $GraphType == self::TYPE_DATE_BAR )
37 {
38 $this->Status = self::OK;
39 # Convert input data into a form that Javascript will deal with
40
41 if ($GraphType == self::TYPE_DATE)
42 {
43 $this->Data = $this->ToJsFormat($GraphData);
44 }
45 elseif ($GraphType == self::TYPE_DATE_BAR)
46 {
47 # Summarize the search data passed in into daily, weekly, monthly:
48 $DailyData = array();
49 $WeeklyData = array();
50 $MonthlyData = array();
51
52 foreach ($GraphData as $Xval => $Yvals)
53 {
54 $DailyTS = strtotime( date('Y-m-d', $Xval) );
55 # Find the Monday preceeding this day for the weekly TS:
56 $WeeklyTS = $DailyTS - 86400* (date('N', $Xval) - 1);
57 $MonthlyTS = strtotime( date('Y-m-01', $Xval) );
58
59 $this->AddToArray( $DailyData, $DailyTS, $Yvals );
60 $this->AddToArray( $WeeklyData, $WeeklyTS, $Yvals );
61 $this->AddToArray( $MonthlyData, $MonthlyTS, $Yvals);
62 }
63
64 $this->Data = array(
65 "Daily" => $this->ToJsFormat( $DailyData ),
66 "Weekly" => $this->ToJsFormat( $WeeklyData ),
67 "Monthly"=> $this->ToJsFormat( $MonthlyData ) );
68 }
69
70 $this->Type = $GraphType;
71
72 $this->Width = 960;
73 $this->Height = 500;
74
75 $this->LabelChars = strlen(max( array_map('max', $GraphData) ) ) ;
76
77 $this->TopMargin = 5;
78 $this->LeftMargin = 5;
79 $this->RightMargin = 50;
80 $this->BottomMargin = 40;
81
82 $this->LabelFontSize = 14;
83
84 $this->Legend = array();
85
86 $this->Scale = self::DAILY;
87 $this->Title = "";
88 }
89 else
90 {
91 $this->Status = self::ERROR_UNKNOWN_TYPE;
92 }
93 }
94
99 public function Status()
100 {
101 return $this->Status;
102 }
103
108 public function XLabel($Label)
109 {
110 $this->XLabel = $Label;
111 }
112
117 public function YLabel($Label)
118 {
119 $this->YLabel = $Label;
120 }
121
126 public function LabelFontSize($Size)
127 {
128 $this->LabelFontSize = $Size;
129 }
130
135 public function TopMargin($Margin)
136 {
137 $this->TopMargin = $Margin;
138 }
139
144 public function RightMargin($Margin)
145 {
146 $this->RightMargin = $Margin;
147 }
148
153 public function BottomMargin($Margin)
154 {
155 $this->BottomMargin = $Margin;
156 }
157
162 public function LeftMargin($Margin)
163 {
164 $this->LeftMargin = $Margin;
165 }
166
171 public function Width($Width)
172 {
173 $this->Width = $Width;
174 }
175
180 public function Height($Height)
181 {
182 $this->Height = $Height;
183 }
184
189 public function Legend($Legend)
190 {
191 $this->Legend = $Legend;
192 }
193
198 public function Scale($Scale)
199 {
200 $this->Scale = $Scale;
201 }
202
208 public function Title($Title)
209 {
210 $this->Title = $Title;
211 }
212
216 public function Display()
217 {
218 if ($this->Status == self::NO_DATA)
219 {
220 print $this->Title;
221 print "<p><em>No data to display</em></p>";
222 return;
223 }
224
225 if ($this->Status != self::OK)
226 {
227 return;
228 }
229
230 $ChartNumber = self::GetNumber();
231
232 global $AF;
233 // @codingStandardsIgnoreStart
234 ?>
235
236 <?PHP if($ChartNumber==0) { ?>
237 <script type="text/javascript" src="<?PHP $AF->PUIFile("d3.js"); ?>"></script>
238 <script type="text/javascript" src="<?PHP $AF->PUIFile("CW-Graph.js"); ?>"></script>
239 <style>
240 .cw-chart { width: 100%; }
241 .cw-chart-button { padding: 5px; margin-bottom: 15px; cursor: pointer; }
242 svg { font: 12px sans-serif;}
243 .axis { shape-rendering: crispEdges; }
244
245 .axis path, .axis line {
246 fill: none;
247 stroke-width: .5px;
248 }
249
250 .x.axis path { stroke: #000; }
251 .x.axis line { stroke: #fff; stroke-opacity: .5; }
252 .y.axis line { stroke: #ddd; }
253
254 path.line {
255 fill: none;
256 stroke-width: 1.5px;
257 }
258
259 rect.pane {
260 cursor: move;
261 fill: none;
262 pointer-events: all;
263 }
264
265 .focus circle {
266 fill: none;
267 stroke: steelblue;
268 }
269
270 .focus { fill: black; }
271
272 .line.graph_color0 { stroke: #4D7588; }
273 .line.graph_color1 { stroke: ##975078; }
274
275 .area.graph_color0 { fill: #4D7588; }
276 .area.graph_color1 { fill: #975078; }
277 .area.graph_color2 { fill: #818181; }
278 .area.graph_color3 { fill: #5CAA5C; }
279 .area.graph_color4 { fill: #DDBC6D; }
280
281 </style>
282 <?PHP } ?>
283
284 <style>
285 <?PHP if ($this->Type == self::TYPE_DATE) { ?>
286 .x-label<?PHP print($ChartNumber); ?> { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
287 .y-label<?PHP print($ChartNumber); ?> { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
288 <?PHP } elseif ($this->Type == self::TYPE_DATE_BAR) { ?>
289 .x-label<?PHP print($ChartNumber); ?>a { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
290 .y-label<?PHP print($ChartNumber); ?>a { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
291
292 .x-label<?PHP print($ChartNumber); ?>b { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
293 .y-label<?PHP print($ChartNumber); ?>b { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
294
295 .x-label<?PHP print($ChartNumber); ?>c { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
296 .y-label<?PHP print($ChartNumber); ?>c { font-weight: bold; font-size: <?PHP print $this->LabelFontSize; ?>px; }
297 <?PHP } ?>
298 </style>
299
300 <?PHP if ($this->Type == self::TYPE_DATE) { ?>
301 <?PHP print $this->Title; ?>
302 <div class="cw-chart" id="chart<?PHP print $ChartNumber; ?>"></div>
303 <?PHP } elseif ($this->Type == self::TYPE_DATE_BAR) { ?>
304 <div style="max-width: <?PHP print $this->Width; ?>px;">
305
306 <div>
307 <span style="float: right; margin-top: 3px; padding-right: <?PHP print $this->LabelChars + 1 ; ?>em; margin-right: <?PHP print $this->RightMargin; ?>px; ">
308 <span class="cw-chart-button" id="cw-chart-button<?PHP print $ChartNumber; ?>a"
309 <?PHP if ($this->Scale == self::DAILY) { ?> style="font-weight: bold;" <?PHP } ?>
310 >Daily</span>|
311 <span class="cw-chart-button" id="cw-chart-button<?PHP print $ChartNumber; ?>b"
312 <?PHP if ($this->Scale == self::WEEKLY) { ?> style="font-weight: bold;" <?PHP } ?>
313 >Weekly</span>|
314 <span class="cw-chart-button" id="cw-chart-button<?PHP print $ChartNumber; ?>c"
315 <?PHP if ($this->Scale == self::MONTHLY) { ?> style="font-weight: bold;" <?PHP } ?>
316 >Monthly</span>
317 </span>
318 <?PHP print $this->Title; ?>
319 </div>
320
321 <div id="chart<?PHP print $ChartNumber; ?>">
322 <div class="cw-chart" id="chart<?PHP print $ChartNumber; ?>a"
323 <?PHP if ($this->Scale != self::DAILY) { ?> style="display: none;" <?PHP } ?> ></div>
324 <div class="cw-chart" id="chart<?PHP print $ChartNumber; ?>b"
325 <?PHP if ($this->Scale != self::WEEKLY) { ?> style="display: none;" <?PHP } ?> ></div>
326 <div class="cw-chart" id="chart<?PHP print $ChartNumber; ?>c"
327 <?PHP if ($this->Scale != self::MONTHLY) { ?> style="display: none;" <?PHP } ?> ></div>
328 </div>
329 </div>
330 <script type="text/javascript">
331 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>a').click( function(){
332 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>a').css('font-weight', 'bold');
333 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>b').css('font-weight', 'normal');
334 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>c').css('font-weight', 'normal');
335 jQuery('#chart<?PHP print $ChartNumber; ?>a').show();
336 jQuery('#chart<?PHP print $ChartNumber; ?>b').hide();
337 jQuery('#chart<?PHP print $ChartNumber; ?>c').hide();
338 });
339 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>b').click( function(){
340 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>a').css('font-weight', 'normal');
341 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>b').css('font-weight', 'bold');
342 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>c').css('font-weight', 'normal');
343 jQuery('#chart<?PHP print $ChartNumber; ?>a').hide();
344 jQuery('#chart<?PHP print $ChartNumber; ?>b').show();
345 jQuery('#chart<?PHP print $ChartNumber; ?>c').hide();
346 });
347 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>c').click( function(){
348 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>a').css('font-weight', 'normal');
349 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>b').css('font-weight', 'normal');
350 jQuery('#cw-chart-button<?PHP print $ChartNumber; ?>c').css('font-weight', 'bold');
351 jQuery('#chart<?PHP print $ChartNumber; ?>a').hide();
352 jQuery('#chart<?PHP print $ChartNumber; ?>b').hide();
353 jQuery('#chart<?PHP print $ChartNumber; ?>c').show();
354 });
355 </script>
356 <?PHP } ?>
357
358 <script type="text/javascript">
359 <?PHP if ($this->Type == self::TYPE_DATE ) { ?>
360 jQuery(document).ready(function(){
361 new LineDateGraph(<?PHP print($ChartNumber); ?>,
362 <?PHP print(json_encode($this->Data)); ?>,
363 "<?PHP print($this->XLabel); ?>",
364 "<?PHP print($this->YLabel); ?>",
365 {top: <?PHP print $this->TopMargin; ?>, right: <?PHP print $this->RightMargin; ?>,
366 bottom: <?PHP print $this->BottomMargin; ?>, left: <?PHP print $this->LeftMargin; ?> },
367 <?PHP print($this->Width); ?>, <?PHP print($this->Height); ?>, <?PHP print(json_encode($this->Legend)); ?> ); });
368 <?PHP } else if ($this->Type == self::TYPE_DATE_BAR) { ?>
369 jQuery(document).ready(function(){
370 new BarDateGraph(
371 "<?PHP print($ChartNumber); ?>a",
372 <?PHP print(json_encode($this->Data["Daily"])); ?>,
373 "<?PHP print($this->XLabel); ?>",
374 "<?PHP print($this->YLabel); ?> (Daily)",
375 {top: <?PHP print $this->TopMargin; ?>, right: <?PHP print $this->RightMargin; ?>,
376 bottom: <?PHP print $this->BottomMargin; ?>, left: <?PHP print $this->LeftMargin; ?> },
377 <?PHP print($this->Width); ?>, <?PHP print($this->Height); ?>, <?PHP print(json_encode($this->Legend)); ?>,
378 <?PHP print(22*3600); ?>); });
379 jQuery(document).ready(function(){
380 new BarDateGraph(
381 "<?PHP print($ChartNumber); ?>b",
382 <?PHP print(json_encode($this->Data["Weekly"])); ?>,
383 "<?PHP print($this->XLabel); ?>",
384 "<?PHP print($this->YLabel); ?> (Weekly)",
385 {top: <?PHP print $this->TopMargin; ?>, right: <?PHP print $this->RightMargin; ?>,
386 bottom: <?PHP print $this->BottomMargin; ?>, left: <?PHP print $this->LeftMargin; ?> },
387 <?PHP print($this->Width); ?>, <?PHP print($this->Height); ?>, <?PHP print(json_encode($this->Legend)); ?>,
388 <?PHP print(7*86400); ?>); });
389 jQuery(document).ready(function(){
390 new BarDateGraph(
391 "<?PHP print($ChartNumber); ?>c",
392 <?PHP print(json_encode($this->Data["Monthly"])); ?>,
393 "<?PHP print($this->XLabel); ?>",
394 "<?PHP print($this->YLabel); ?> (Monthly)",
395 {top: <?PHP print $this->TopMargin; ?>, right: <?PHP print $this->RightMargin; ?>,
396 bottom: <?PHP print $this->BottomMargin; ?>, left: <?PHP print $this->LeftMargin; ?> },
397 <?PHP print($this->Width); ?>, <?PHP print($this->Height); ?>, <?PHP print(json_encode($this->Legend)); ?>,
398 <?PHP print(28*86400); ?>); });
399 <?PHP } ?>
400 </script>
401 <?PHP
402 // @codingStandardsIgnoreStart
403 }
404
405 private $Status;
406 private static $ChartNumber = 0;
407
408 protected $Data;
409 protected $Type;
410 protected $Height;
411 protected $Width;
412 protected $LabelChars;
413 protected $TopMargin;
414 protected $LeftMargin;
415 protected $BottomMargin;
416 protected $RightMargin;
417 protected $Legend;
418 protected $Scale;
419 protected $XLabel;
420 protected $YLabel;
421 protected $LabelFontSize;
422 protected $Title;
423
426 private function GetNumber()
427 {
428 return self::$ChartNumber++;
429 }
430
439 private function AddToArray(&$Array, $Key, $Value)
440 {
441 if (!isset($Array[$Key]))
442 {
443 $Array[$Key] = $Value;
444 }
445 else
446 {
447 $Array[$Key] = array_map( function($a,$b){ return $a+$b; },
448 $Array[$Key], $Value );
449 }
450 }
451
460 private function ToJsFormat($Data, $IsDate=TRUE)
461 {
462 $Result = array();
463 foreach ($Data as $Xval => $Yvals)
464 {
465 $DataRow = array();
466
467 if ($IsDate)
468 {
469 $DataRow["X"] = 1000 * $Xval;
470 }
471 else
472 {
473 $DataRow["X"] = $Xval;
474 }
475
476 $Count = 0;
477 foreach ($Yvals as $Yval)
478 {
479 $DataRow["Y".$Count++] = $Yval;
480 }
481
482 $Result[] = $DataRow;
483 }
484
485 return $Result;
486 }
487 }
PHP
PHP
Definition: RSSClient--Test.php:12