A new version of the column configuration panel including the nodes page
[plewww.git] / plekit / php / columns.php
1 <?php
2
3 require_once 'tophat_api.php';
4
5 drupal_set_html_head('
6 <script type="text/javascript" src="/plekit/table/columns.js"></script>
7 ');
8
9 class PlekitColumns {
10
11 var $column_configuration = "";
12 var $reference_node = "";
13 var $first_time = false;
14
15 var $all_headers = array();
16 var $this_table_headers = array();
17 var $visible_headers = array();
18
19 var $fix_columns = array();
20 var $tag_columns = array();
21 var $extra_columns = array();
22
23 var $table_ids;
24
25 var $HopCount = array();
26
27   function PlekitColumns ($column_configuration, $fix_columns, $tag_columns, $extra_columns=NULL, $this_table_headers=NULL) {
28
29         $this->fix_columns = $fix_columns;
30         $this->tag_columns = $tag_columns;
31         $this->extra_columns = $extra_columns;
32
33         //print("<p>FIX<p>");
34         //print_r($this->fix_columns);
35         //print("<p>TAG<p>");
36         //print_r($this->tag_columns);
37         //print("<p>EXTRA<p>");
38         //print_r($this->extra_columns);
39
40         $this->prepare_headers();
41         $this->parse_configuration($column_configuration);
42
43         $this->visible_headers = $this->get_visible();
44
45         //print("<p>VISIBLE<p>");
46         //print_r($this->visible_headers);
47
48 }
49
50
51
52 /*
53
54 INFO
55
56 */
57
58 function prepare_headers() {
59
60 foreach ($this->fix_columns as $column) {
61 $this->all_headers[$column['header']]=array('header'=>$column['header'],'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['title'], 'description'=>$column['title'], 'label'=>$column['header'], 'fixed'=>true, 'visible'=>false);
62 }
63
64 $tmp_headers = array();
65 foreach ($this->tag_columns as $column) {
66
67 if ($column['headerId'] != "")
68         $headerId = $column['headerId'];
69 else
70         $headerId = $column['header'];
71
72 //$this->all_headers[$headerId]=array('header'=>$headerId,'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['title'], 'description'=>$column['title'], 'label'=>$column['header'],'visible'=>false);
73 $tmp_headers[$headerId]=array('header'=>$headerId,'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['title'], 'description'=>$column['title'], 'label'=>$column['header'],'visible'=>false);
74 }
75
76 if ($this->extra_columns)
77 foreach ($this->extra_columns as $column) {
78 //$this->all_headers[$column['header']]=array('header'=>$column['header'],'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['title'], 'description'=>$column['title'], 'label'=>$column['header'], 'fetched'=>$column['fetched'],'visible'=>false);
79 $tmp_headers[$column['header']]=array('header'=>$column['header'],'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['title'], 'description'=>$column['title'], 'label'=>$column['header'], 'fetched'=>$column['fetched'], 'visible'=>false);
80
81 usort ($tmp_headers, create_function('$col1,$col2','return strcmp($col1["label"],$col2["label"]);'));
82 }
83
84 foreach ($tmp_headers as $t) 
85 $this->all_headers[$t['header']] = $t;
86
87 //$this->all_headers = array_merge($this->all_headers, $tmp_headers);
88
89 //print($this->print_headers());
90
91 return $this->all_headers;
92
93 }
94
95
96 function get_headers() {
97
98 return $this->all_headers;
99
100 }
101
102 function get_selected_period($label) {
103
104 if ($this->all_headers[$label."w"]['visible'])
105         return "w";
106 else if ($this->all_headers[$label."m"]['visible'])
107         return "m";
108 else if ($this->all_headers[$label."y"]['visible'])
109         return "y";
110 else if ($this->all_headers[$label]['visible'])
111         return "";
112         
113 return "";
114 }
115
116 function node_tags() {
117
118         $fetched_tags = array('node_id');       
119
120         foreach ($this->all_headers as $h)
121         {
122                 if ($h['visible'] == true && $h['tagname'] != "" && !$h['fetched'])
123                         $fetched_tags[] = $h['tagname'];
124         }
125
126         return $fetched_tags;
127 }
128
129 function print_headers() {
130
131         $headers = "";  
132
133         foreach ($this->all_headers as $l => $h)
134         {
135                 $headers.="<br>[".$l."]=".$h['header'].":".$h['label'].":".$h['tagname'].":".$h['visible'];
136         }
137         return $headers;
138 }
139
140 function get_visible() {
141
142         $visibleHeaders = array();      
143
144         foreach ($this->all_headers as $h)
145         {
146                 if ($h['visible'] == true)
147                         $visibleHeaders[] = $h['header'];
148         }
149         return $visibleHeaders;
150 }
151
152 function headerIsVisible($header_name) {
153
154 $headersToShow = $this->visible_headers;
155
156 if (in_array($header_name, $headersToShow))
157         return true;
158
159 if ($this->inTypeC($header_name."w"))
160         return (in_array($header_name."w", $headersToShow) || in_array($header_name."m", $headersToShow) || in_array($header_name."y", $headersToShow));
161 }
162
163
164
165
166 /*
167
168 CONFIGURATION
169
170 */
171
172
173 function parse_configuration($column_configuration) {
174
175         $this->column_configuration = $column_configuration;
176         //$this->default_configuration = $default_configuration;
177
178         //print($this->print_headers());
179
180         $columns_conf = explode("|", $column_configuration);
181
182         foreach ($columns_conf as $c)
183         {
184                 $conf = explode(":",$c);
185
186                 if ($conf[0] == "default")
187                         continue;
188
189                 $this->all_headers[$conf[0]]['visible']=true;
190                 //print("<p>-".$conf[0]."-should be visible now - ".$this->all_headers[$conf[0]]['visible']);
191                 //print_r($this->all_headers[$conf[0]]);
192
193 /*
194                 if ($conf[1] == "f")
195                         continue;
196
197                 else if ($this->inTypeC($conf[0]))
198                 {
199                         $this->all_headers[$conf[0]]['duration']= substr($conf[0], strlen($conf[0])-1, strlen($conf[0]));
200                         $threshold = explode(",",$conf[1]);
201                         $this->all_headers[$conf[0]]['threshold']=$threshold;
202                 }
203                 else if ($this->inTypeD($conf[0]))
204                 {
205                         $this->reference_node = $conf[1];
206                         $this->reference_node = "planetlab-europe-07.ipv6.lip6.fr";
207                         $this->all_headers[$conf[0]]['refnode']=$this->reference_node;
208                         $threshold = explode(",",$conf[1]);
209                         $this->all_headers[$conf[0]]['threshold']=$threshold;
210                 }
211                 else if ($this->inTypeA($conf[0]))
212                 {
213                         $exclude_list = explode(",",$conf[1]);
214                         $this->all_headers[$conf[0]]['exclude_list']=$exclude_list;
215                 }
216                 else
217                 {
218                         $threshold = explode(",",$conf[1]);
219                         $this->all_headers[$conf[0]]['threshold']=$threshold;
220                 }
221 */
222         }
223 }
224
225
226                 
227
228
229 /*
230
231 CELLS
232
233 */
234
235 function getHopCount($ref_node, $planetlab_nodes)
236 {
237
238 $tophat_auth = array( 'AuthMethod' => 'password', 'Username' => 'guest', 'AuthString' => 'guest');
239 $tophat_api = new TopHatAPI($tophat_auth);
240
241 $traceroute = $tophat_api->Get('traceroute', 'latest', array('src_hostname' => $ref_node, 'dst_hostname' => $planetlab_nodes), array('dst_hostname', 'hop_count') );
242
243 $hopcount = array();
244
245 if ($traceroute) foreach ($traceroute as $t)
246 $hopcount[$t['dst_hostname']]=$t['hop_count'];
247 return $hopcount;
248 }
249
250
251 //Depending on the columns selected more data might need to be fetched from
252 //external sources
253
254 function fetch_data($nodes) {
255
256 //TopHat pairwise data
257
258         if ($this->reference_node != "")
259         {
260                 $dd = array();
261
262                 if ($nodes) foreach ($nodes as $n)
263                         $dd[] = $n['hostname'];
264
265                 if ($potential_nodes) foreach ($potential_nodes as $n)
266                         $dd[] = $n['hostname'];
267
268                 print("Calling tophat api for reference node = ".$this->reference_node);
269                 $st = time() + microtime();
270                 $HopCount = $this->getHopCount($this->reference_node, $dd);
271                 printf(" (%.2f ms)<br/>", (time() + microtime()-$st)*100);
272                 //print_r($HopCount);
273         }
274
275 }
276
277
278 function excludeItems($value, $exclude_list, $hh) {
279
280         if ($value == "")
281                 $value = "n/a";
282
283         if ($exclude_list)
284         if (in_array($value, $exclude_list))
285                 return array($value, array('name'=>$hh, 'display'=>'table-cell'));
286         else
287                 return array($value, array('name'=>$hh, 'display'=>'table-cell'));
288
289         return array($value, array('name'=>$hh, 'display'=>'table-cell'));
290 }
291
292
293 function checkThreshold($value, $threshold, $hh) {
294
295         if ($value == "")
296                 return array("n/a", array('name'=>$hh, 'display'=>'table-cell'));
297
298         if ($threshold)
299         if ((float) $value >= (float) $threshold[0] && (float) $value <= (float) $threshold[1])
300                 return array(round($value,1), array('name'=>$hh, 'display'=>'table-cell'));
301         else
302                 return array(round($value,1), array('name'=>$hh, 'display'=>'table-cell'));
303
304         return array(round($value,1), array('name'=>$hh, 'display'=>'table-cell'));
305 }
306
307
308 function cells($table, $node) {
309
310 $this->fetch_data($node);
311
312 foreach ($this->all_headers as $h)
313 {
314 if (!$h['fixed']) { 
315
316 if ($h['visible'] != "")
317 {
318 if ($this->inTypeC($h['header']))
319 {
320         $tagname = $h['tagname'];
321         $value = $node[$tagname];
322         $v = $this->checkThreshold($value, $h['threshold'], $h['header']);
323         $table->cell($v[0],$v[1]);
324 }
325 else if ($this->inTypeB($h['header']))
326 {
327         $value = $node[$h['tagname']];
328         $v = $this->checkThreshold($value, $h['threshold'], $h['header']);
329         $table->cell($v[0],$v[1]);
330 }
331 else if ($this->inTypeD($h['header']))
332 {
333         $value = $this->HopCount[$node['hostname']];
334         $v = $this->excludeItems($value, $h['threshold'], $h['header']);
335         $table->cell($v[0],$v[1]);
336 }
337 else if ($this->inTypeA($h['header']))
338 {
339         $value = $node[$h['tagname']];
340         $v = $this->excludeItems($value, $h['exclude_list'], $h['header']);
341         $table->cell($v[0],$v[1]);
342 }
343 else
344 {
345         $value = $node[$h['tagname']];
346         $table->cell($value,array('name'=>$h['header'], 'display'=>'table-cell'));
347 }
348 }
349 else 
350         if ($node[$h['tagname']])
351                 $table->cell($node[$h['tagname']], array('name'=>$h['header'], 'display'=>'none'));
352         else
353                 $table->cell("??", array('name'=>$h['header'], 'display'=>'none'));
354 }
355 }
356
357 }
358
359
360 /*
361
362 HTML
363
364 */
365
366
367 function javascript_init() {
368
369 print("<input type='hidden' id='reference_node' value='".$this->reference_node."' />");
370
371 print("<script type='text/javascript'>");
372 print("highlightOption('AU');");
373 print("overrideTitles();");
374 print("</script>");
375
376 }
377
378
379
380 function quickselect_html() {
381
382 //return '<p>This link uses the onclick event handler.<br><a href="#" onclick="setVisible(\'quicklist\');return false" target="_self">Open popup</a></p>';
383
384
385 $quickselection = "<select id='quicklist' multiple size=10 onChange=changeSelectStatus(this.value)><option value''>Add/remove columns</option>";
386 $prev_label="";
387 $optionclass = "out";
388 foreach ($this->all_headers as $h)
389 {
390         if ($h['header'] == "hostname" || $h['header'] == "ID")
391                 continue;
392
393         if ($h['fixed'])
394                 $disabled = "disabled=true";
395         else
396                 $disabled = "";
397
398         if ($this->headerIsVisible($h['label']))
399         {
400                 $optionclass = "in";
401                 //$selected = "selected=selected";
402         }
403         else
404         {
405                 $optionclass = "out";
406                 //$selected = "";
407         }
408
409         if ($prev_label == $h['label'])
410                 continue;
411
412         $prev_label = $h['label'];
413
414
415 $quickselection.="<option id='option'".$h['label']." class='".$optionclass."' '".$selected."' value='".$h['label']."'>".$h['label'].":&nbsp;".$h['title']."</option>";
416 }
417
418
419 $quickselection.="</select>";
420 $quickselection.="&nbsp;<input type='button' id='fetchbutton' onclick='fetchData()' value='Fetch data' disabled=true />";
421
422 return $quickselection;
423
424 }
425
426
427 function quickselect_popup_html() {
428
429 print('<div id="quickdiv">');
430 print ("<select size='12' id='quicklist' onChange=changeSelectStatus(this.value)>");
431
432 $prev_label="";
433 $optionclass = "out";
434 foreach ($this->all_headers as $h)
435 {
436         if ($h['header'] == "hostname")
437                 continue;
438
439         if ($h['fixed'])
440                 $disabled = "disabled=true";
441         else
442                 $disabled = "";
443
444         if ($this->headerIsVisible($h['label']))
445         {
446                 $optionclass = "in";
447                 //$selected = "selected=selected";
448         }
449         else
450         {
451                 $optionclass = "out";
452                 //$selected = "";
453         }
454
455         if ($prev_label == $h['label'])
456                 continue;
457
458         $prev_label = $h['label'];
459
460
461         print ("<option id='option'".$h['label']." class='".$optionclass."' '".$selected."' value='".$h['label']."'>".$h['label'].":&nbsp;".$h['title']."</option>");
462 }
463
464
465 print("</select></div>");
466 print("&nbsp;<input type='button' id='fetchbutton' onclick='fetchData()' value='Fetch data' disabled=true />");
467
468 }
469
470 function configuration_panel_html($showDescription) {
471
472
473 if ($showDescription)
474         $table_width = 700;
475 else
476         $table_width = 350;
477
478 print("<table align=center cellpadding=10 width=".$table_width.">");
479 print("<tr><th>Add/remove columns</th>");
480
481 if ($showDescription)
482         print("<th>Column description and configuration</th>");
483
484 print("</tr><tr><td valign=top width=300>");
485
486         print('<div id="scrolldiv" style="border : solid 2px grey; padding:4px; width:300px; height:180px; overflow:auto;">');
487 print ("<table>");
488         $prev_label="";
489         $optionclass = "out";
490         foreach ($this->all_headers as $h)
491         {
492                 if ($h['header'] == "hostname" || $h['header'] == "ID")
493                         continue;
494
495                 if ($h['fixed'])
496                         $disabled = "disabled=true";
497                 else
498                         $disabled = "";
499
500                 if ($this->headerIsVisible($h['label']))
501                 {
502                         $selected = "checked=true";
503                         $fetch = "true";
504                         //print("header ".$h['label']." checked!");
505                 }
506                 else
507                 {
508                         $selected = "";
509                         if ($h['fetched'])
510                                 $fetch = "true";
511                         else
512                                 $fetch = "false";
513                 }
514
515                 print("<input type='hidden' id='tagname".$h['header']."' value='".$h['tagname']."'></input>");
516
517                 if ($prev_label == $h['label'])
518                         continue;
519
520                 $prev_label = $h['label'];
521                 $period = $this->get_selected_period($h['label']);
522
523 //<input type='hidden' id='fdesc".$h['label']."' value='".$h['description']."'></input>
524                 print ("<tr><td>
525 <input type='hidden' id='fetched".$h['label']."' value=',".$period.",".$fetch."'></input>
526 <input type='hidden' id='period".$h['label']."' value='".$period."'></input>
527                 <div id='".$h['label']."' name='columnlist' class='".$optionclass."' onclick='highlightOption(this.id)'>
528 <table width=280 id='table".$h['label']."'><tr>
529 <td bgcolor=#CAE8EA align=center width=30><b><span style='color:#3399CC'>".$h['label']."</span></b></td> 
530 <td align=left>&nbsp;<span style='height:10px' id ='htitle".$h['label']."'>".$h['title']."</span>&nbsp;</td>
531 <td align=right width=20>&nbsp;<span style='height:10px' id ='loading".$h['label']."'></span>&nbsp;</td>
532 <td align=right width=20><input id='check".$h['label']."' name='".$h['tagname']."' type='checkbox' ".$selected." ".$disabled." autocomplete='off' value='".$h['label']."' onclick='changeCheckStatus(this.id)'></input></td>
533 </tr></table></div></td></tr>");
534         }
535
536         print("</table> </div></td>");
537
538 if ($showDescription)
539 {
540         print("<td valign=top width=400>");
541         print("<div class='myslice' id='selectdescr'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div></td>");
542 }
543
544 print("</tr>");
545 //print("<tr><td align=center>");
546 //print("<input type='button' value='Reset' onclick=resetCols('previousConf') />");
547 //print("<input type='button' value='Default' onclick=saveConfiguration('defaultConf') />");
548 //print("<input type='button' value='Reset table' onclick=\"resetConfiguration()\" />");
549 //print("</td>");
550 //print("&nbsp;<input type='button' value='Save configuration' onclick=saveConfiguration('column_configuration') />");
551 //print("&nbsp;<input type='button' id='fetchbutton' onclick='fetchData()' value='Fetch data' disabled=true /> </td>");
552
553 if ($showDescription)
554         print("<td></td>");
555
556 print(" </tr> </table>");
557 }
558
559
560
561 function column_filter () {
562
563 echo <<< EOF
564
565 Highlight <select onChange="filterByType(this.value)">
566 <option value="none">None</option>
567 <option value="capabilities">Capabilities</option>
568 <option value="statistics">Statistics</option>
569 <option value="network">Network</option>
570 <option value="pairwise">Pairwise</option>
571 <option value="other">Other</option>
572 </select>
573 <p>
574
575 EOF;
576 }
577
578   function column_html ($colHeader, $colName, $colId, $fulldesc, $visible) {
579
580         if ($visible) 
581                 $display = 'display:table-cell';
582         else 
583                 $display = 'color:red;display:none';
584
585     return "
586         <th class='sample plekit_table' name='confheader".$colHeader."' id='testid' style='".$display."'>
587         <div id=\"".$colId."\" onclick=\"showDescription('".$colHeader."')\" onmouseover=\"showDescription('".$colHeader."')\">$colHeader</div>
588         </th>
589         ";
590   }
591
592   function column_fix_html ($colHeader, $colName, $colId) {
593
594         $display = 'display:table-cell';
595
596         $res="<th name='confheader".$colHeader."' class='fix plekit_table' style='$display'>";
597                 $res.= "<div id='$colId' onmouseover=\"showDescription('".$colHeader."')\">$colHeader</div></th>";
598
599         return $res;
600   }
601
602
603 function graph_html($colHeader) {
604
605         return "<p><img src='/planetlab/slices/graph.png' width='20' align='BOTTOM'><input type='checkbox' id='graph".$colHeader."'></input> Show details on mouse over";
606
607         }
608
609 function threshold_html($colHeader) {
610
611         $updatecall = "updateColumnThreshold('".$colHeader."',window.document.getElementById('min".$colHeader."').value,window.document.getElementById('max".$colHeader."').value);";
612
613         $bubble="<b>Grey-out values between</b>  <input type='text' id='min".$colHeader."' size='2' value='5'> (low) and <input type='text' id='max".$colHeader."' size='2' value='90'> (high) <input type='submit' value='Update' onclick=".$updatecall.">&nbsp;</input>"; 
614
615         return $bublle;
616 }
617
618
619 /*
620
621 UTILS
622
623 */
624
625 //simple strings
626 function inTypeA($header_name) {
627         $typeA = array('ST','SN','RES','OS','NRR','NTP','NSR','NSF','NDS','NTH','NEC','LRN','LCY','LPR','LCN','LAT','LON','IP','ASN','AST');
628         return in_array($header_name, $typeA);
629 }
630
631 //integers
632 function inTypeB($header_name) {
633         $typeB = array('BW','DS','MS','CC','CR','AS','DU','CN');
634         return in_array($header_name, $typeB);
635 }
636
637 //statistical values
638 function inTypeC($header_name) {
639         $typeC = array('Rw','Rm','Ry','Lw','Lm','Ly','Sw','Sm','Sy','CFw','CFm','CFy','BUw','BUm','BUy','MUw','MUm','MUy','SSHw','SSHm','SSHy');
640         return in_array($header_name, $typeC);
641 }
642
643 //tophat
644 function inTypeD($header_name) {
645         $typeD = array('HC');
646         return in_array($header_name, $typeD);
647 }
648
649
650 function removeDuration($header)
651 {
652         if ($this->inTypeC($header))
653                 return substr($header, 0, strlen($header)-1);
654         else
655                 return $header;
656 }
657
658 }
659
660 ?>
661
662