root/ui/web/htdocs/graph_panel.inc

Revision 291cb6c73899c30c7149bc6de596cf9db9693298, 20.1 kB (checked in by Umar Farooq <umar@omniti.com>, 5 years ago)

cleaning up streaming code

  • Property mode set to 100644
Line 
1 <script type="text/javascript">
2 <!--
3 var maingraph;
4 var current_graph_id = '';
5 var debug_graph_edit = false;
6 var graphinfo= {streaming: false}; //this streaming boolean keeps track of the graphpanel stream button
7 var displayinfo = { start : 14*86400, cnt: '', end: '' };
8 var color_pool = Array('#33aa33','#4a00dc','#caac00','#3377cc','#00acfa','#cc3333')
9 var color_sel = 0;
10 var locked = true;
11
12 function graph_locked(warning) {               
13   if(locked) {
14     modal_warning("Graph Locked!", warning);
15     return locked;
16   }
17   return locked;
18 }
19
20 function lock_forms() {
21         $("input[@name='math1']").attr("disabled", "true");
22         $("input[@name='math2']").attr("disabled", "true");
23         $("input[@name='view']").attr("disabled", "true");
24         $("input[@class='graphType']").attr("disabled", "true");
25         $("select[@name='derive']").attr("disabled", "true");
26         $("select[@class='av_stacks']").attr("disabled", "true");
27
28         $("h2#graphTitle").unbind();
29         $(".datatitle").unbind();
30 }
31
32 function unlock_forms() {
33
34         $("input[@name='math1']").removeAttr("disabled");
35         $("input[@name='math2']").removeAttr("disabled");
36         $("input[@name='view']").removeAttr("disabled");
37 //        $("input[@class='graphType']").removeAttr("disabled");
38         $("select[@name='derive']").removeAttr("disabled");
39         $("select[@class='av_stacks']").removeAttr("disabled");
40
41         $("h2#graphTitle").editable(function(value, settings) {
42            graphinfo.title = value;
43            update_current_graph(false);
44            return(value);
45            }, { });
46
47         $(".datatitle").editable(function(value, settings) {     
48            graphinfo.datapoints[$(".datatitle").index(this)].name = value;
49            update_current_graph(true);
50            return(value);
51         }, { });
52 }
53
54 function update_graph_permalink(id, start, end, gran){
55  $("#gpermalink a").attr("href", "drawing_board.php?otype=graph&id="+id+"&start="+start+"&end="+end+"&gran="+gran);
56 }
57
58 function stop_streaming_graph (){
59          graphinfo.streaming = false;
60          streaming = false;
61          $('#streambox').html('');
62          $(".streamData").html('Stream Data').fadeIn('slow');
63          $(".stream-log").attr("style", "display:none;");
64 }
65
66 function set_current_graph_id(id) {
67   $(".rememberGraph").fadeOut('fast');
68   if(id!='')  {
69     graphinfo.saved = true;
70     locked = true;
71     lock_forms();
72     $(".editGraph").html('Edit Graph').fadeIn('slow');   
73   }
74   else {       
75     locked = false;
76     unlock_forms();   
77     $(".editGraph").html('Editing!').fadeIn('slow');
78     $('#streambox').html('');
79     $(".streamData").html('Stream Data').fadeIn('slow');
80     $(".stream-log").attr("style", "display:none;");
81   }
82   current_graph_id = id;
83   update_graph_permalink(current_graph_id, "", "", "");
84   fetch_graph_info(current_graph_id);
85 }
86 var recurse = 0;
87 function update_current_graph(redraw, f) {
88   if(recurse > 0) return;
89   stop_streaming_graph();
90
91   var str = JSON.stringify(graphinfo);
92   if(debug_graph_edit) $("#payload").html(str);
93   $.post("json/graph/store",
94          {'json':str},
95          function(d) {
96            recurse++;
97            graphinfo.id = current_graph_id = d.id;
98            
99            if(d.error) $("#gtool-error").html(d.error).fadeIn('fast');
100            else $("#gtool-error").fadeOut('fast');     
101            if(graphinfo.id && graphinfo.saved != true &&
102               $(".rememberGraph:visible").length == 0) {
103               graphinfo.saved=false;
104              $(".rememberGraph").html('"Remember" this graph.').fadeIn('slow');
105              $(".rememberGraph").click(function() {
106                graphinfo.saved = true;
107                update_current_graph(false, function(r) {
108                  if(r.error) {
109                    graphinfo.saved = false;
110                     $("#gtool-error").html(r.error).fadeIn('fast');
111                  }
112                  else $(".rememberGraph").html('Remebered').fadeOut('slow');
113                });
114              });
115            }
116            if(redraw && maingraph) maingraph.ReconGraphRefresh({graphid: graphinfo.id, type: graphinfo.type});
117            if(f) f(d);
118            recurse--;
119          }, 'json');
120 }
121
122 function graph_add_datapoint(d) {
123   if(!graph_locked("Click 'Edit Graph' to unlock.")){
124     if(d.axis == undefined) { d.axis = 'l'; }
125     if(d.name == undefined) { d.name = d.target + '`' + d.metric_name; }
126     graphinfo.datapoints.push(d);
127     gtool_add_datapoint(d);
128     update_current_graph(true);
129   }
130 }
131 function gtool_add_guide() {
132   var d = {};
133   d.metric_type = 'guide';
134   graphinfo.datapoints.push(d);
135   gtool_add_datapoint(d);
136   update_current_graph(true);
137 }
138
139 function gtool_add_datapoint(d) {
140   var o;
141   if(d.metric_type == 'guide') {
142     o = $("#guideeditor").clone();
143   }
144   else {
145     o = $("#datapointeditor").clone();
146   }
147   recurse++;
148  
149   if(d.color == null) {
150     d.color = color_pool[color_sel];
151     color_sel = (color_sel + 1) % color_pool.length;
152   }
153   o.find('.colorPickerHolder').ColorPicker({
154     flat: true,
155     color: '#ffffff',
156     onSubmit: (function(dpo,dp) {
157       var cs = dpo.find('.colorSelector');
158       return function(hsb, hex, rgb) {
159         dp.color = '#' + hex;
160         cs.css('border', '1px solid ' + dp.color);
161         cs.find('div').css('backgroundColor', dp.color)
162                       .css('opacity', 0.2);
163         cs.parent().find('.colorPickerHolder').stop().animate({height:0},500);
164         update_current_graph(true);
165       }
166     })(o,d)
167   });
168   o.find('.colorPickerHolder > div').css('position', 'absolute');
169   o.find('.colorSelector').css('border', '1px solid ' + d.color);
170   o.find('.colorSelector div').css('backgroundColor', d.color)
171                               .css('opacity',
172                                    (d.opacity == null) ? 0.2 : d.opacity);
173   o.find('.colorSelector').bind('click', function() {
174     if(!locked){
175         var activecp = $(this).parent().find('.colorPickerHolder');
176         var h = activecp.height();
177         $("#gtool #dataPoints .colorPickerHolder").filter(function(index) {
178              return ($(this) != activecp);
179         }).stop().animate({height:0}, 0);;
180         $(this).parent().find('.colorPickerHolder').stop().animate({height: h != 0 ? 0 : 173}, 500);
181     }
182   });
183
184   o.find(d.axis == "l" ? ".axisl" : ".axisr").addClass("axison");
185   o.find("span.axis").click(function(){
186     if(!locked) {
187        $(this).siblings().removeClass("axison");
188        $(this).addClass("axison");
189        d.axis = $(this).hasClass("axisl") ? "l" : "r";
190        update_current_graph(true);
191     }
192   });
193
194   if(!d.hidden){o.find('input[@name="view"]').attr("checked","checked");}
195   o.find('input[@name="view"]').change(function(){
196     d.hidden = !($(this).attr("checked"));
197     update_current_graph(true);
198   }).change();
199
200   o.find('select[@id="datastack"]').change(function(){
201       var si = find_in_stacks($(".av_stacks").index(this));
202        if(si != -1) graphinfo.stacks[si.i].splice(si.j, 1);
203
204        if(graphinfo.stacks[ $(this).val() ]) {
205          graphinfo.stacks[ $(this).val()].push($(".av_stacks").index(this));
206          graphinfo.stacks[ $(this).val()].sort(function(a,b){return a - b});
207        }
208        update_current_graph(true);
209
210       $(".graphStacks").empty();
211
212       for(var i=0; i<graphinfo.stacks.length; i++) {
213         $(".graphStacks").append('<br>Stack '+i+': ');
214         for(var j=0; j<graphinfo.stacks[i].length; j++){
215             $(".graphStacks").append(graphinfo.datapoints[graphinfo.stacks[i][j]].name + ",");
216         }
217       }
218     }).change();
219
220
221   o.find('.deletedatapoint').click(function(){
222     if(!locked){
223        for(var i=0; i<graphinfo.datapoints.length; i++) {
224          if(graphinfo.datapoints[i] == d) {
225            graphinfo.datapoints.splice(i,1);
226            var si = find_in_stacks(i);
227            if(si != -1) graphinfo.stacks[si.i].splice(si.j, 1);
228            break;
229          }
230        }
231        update_current_graph(true);
232        refresh_graph_from_json(graphinfo);
233        }
234     return false;
235   });
236
237   if(d.metric_type == 'text') {
238     o.find('tr.mathbox').remove();
239     o.find('select[@name="derive"]').val('false');
240   }
241   else {
242     if(d.derive){
243       o.find('select[@name="derive"]').val(d.derive);
244     }
245     o.find('select[@name="derive"]').change(function(){
246       d.derive = $(this).find(":selected").val();
247       update_current_graph(true);
248     }).change();
249
250     o.find('input[@name="math1"]').val(d.math1);
251     o.find('input[@name="math1"]').change(function(){
252       d.math1 = $(this).val();
253       update_current_graph(true);
254     });
255     o.find('input[@name="math2"]').val(d.math2);
256     o.find('input[@name="math2"]').change(function(){
257       d.math2 = $(this).val();
258       update_current_graph(true);
259     });
260   }
261
262   d.mouse_title = ( (d.target!=undefined) ? d.target+"`": '') +
263                         ( (d.module!=undefined) ? d.module+"`": '') +
264                         ( (d.orig_name!=undefined)? d.orig_name+"`": '') +
265                         ( (d.metric_name!=undefined)? "`"+d.metric_name: '');
266
267   o.find(".datatitle").html(d.name);
268   o.find(".datatitle").attr("title", d.mouse_title);
269
270   if (!locked) {
271       o.find(".datatitle").editable(function(value, settings) {
272       graphinfo.datapoints[$(".datatitle").index(this)].name = value;
273       update_current_graph(true);
274       return(value);
275     }, { });
276  }
277
278   recurse--;
279   $("#gtool #dataPoints").append(o.children());
280 }
281
282 function find_in_stacks(dnum) {
283   for(var i=0; i<graphinfo.stacks.length; i++) {
284       for(var j=0; j<graphinfo.stacks[i].length; j++) {
285          if(graphinfo.stacks[i][j] == dnum) {           
286             var r = { i: i, j: j}; return r;
287          }       
288       }
289   }
290   return -1;
291 }
292 //this function works on the maingraph dom element, which is used througout in graph editing
293 function refresh_graph_from_json(j) {
294   graphinfo = j;
295   if(graphinfo.stacks == undefined) graphinfo.stacks = Array();
296   if(graphinfo.datapoints == undefined) graphinfo.datapoints = Array();
297   $("h2#graphTitle").html(graphinfo.title ? graphinfo.title : 'Graph Title (click to edit)');
298
299   $("input[@name='graphtype']:checked").removeAttr("checked");
300   $("input[@name='graphtype']")
301     .filter(function(i){return $(this).val() == graphinfo.type;})
302     .attr("checked","checked");
303   $("#dataPoints").empty();
304
305   for(var i=0; i<graphinfo.datapoints.length; i++) {
306     gtool_add_datapoint(graphinfo.datapoints[i]);
307   }
308
309   $(".graphStacks").empty();
310   $('.av_stacks').find('option').remove().end().append('<option value="-1">select </option>')
311
312   for(var i=0; i<graphinfo.stacks.length; i++) {
313     $(".graphStacks").append('<br>Stack '+i+': ');     
314     $('.av_stacks').append('<option value="'+i+'">Stack '+i+'</option>');
315
316     for(var j=0; j<graphinfo.stacks[i].length; j++){
317         $(".graphStacks").append(graphinfo.datapoints[graphinfo.stacks[i][j]].name + ",");
318     }
319   }
320
321   $('select[@id="datastack"]').each( function()  {   
322     var si = find_in_stacks($(".av_stacks").index(this));
323     if(si != -1) $(this).val(si.i);
324   });
325
326   if(maingraph) {
327     if(graphinfo.id)
328       maingraph.ReconGraphRefresh({graphid: graphinfo.id, type: graphinfo.type, stacks: graphinfo.stacks});
329     else
330       maingraph.ReconGraphReset();
331   }
332 }
333 function fetch_graph_info(id) {
334   graphinfo.id = id;
335   if(id) $.getJSON("json/graph/info/" + id, refresh_graph_from_json);
336   else refresh_graph_from_json({});
337 }
338 -->
339 </script>
340 <!--<p><a href="">username</a> / <a href="#">worksheet</a></p>-->
341 <p/>
342 <span class="rememberGraph"></span>
343 <span class="blankGraph">New Blank</span>
344 <span class="streamData ">Stream Data</span>
345 <span class="editGraph">Edit Graph</span>
346 <span class="permalink" id="gpermalink"><a href="">Link</a></span>
347
348 <h2 id="graphTitle"></h2>
349 <!-- date range box -->
350 <script type="text/javascript">
351 $(document).ready(function(){
352
353         lock_forms();
354
355         var time_windows = { '2d' : 86400*2,
356                               '1w' : 86400*7,
357                               '2w' : 86400*14,
358                               '4w' : 86400*28,
359                               '1y' : 86400*365,
360                             };
361         var state = false;
362
363         //only allow graph editing if not streaming
364         $(".editGraph").click(function() {     
365             if(!graphinfo.streaming){
366                 if(locked){
367                     locked = false;                 
368                     unlock_forms();
369                     $(".editGraph").html('Editing!').fadeIn('slow');
370                 }
371                 else if(!locked){
372                     locked = true;     
373                     lock_forms();
374                     $(".editGraph").html('Edit Graph').fadeIn('slow');
375                 }
376             }
377         });
378
379         $(".editStacks").click(function() {
380                if(!graph_locked("Unlock by clicking 'Edit Graph'.") && graphinfo.id) {                         
381                  graphinfo.stacks.push([]);
382                  var ns = graphinfo.stacks.length - 1;
383                  $(".graphStacks").append('<p>Stack '+ns+'</p>');
384                  $('.av_stacks').append('<option value="'+ns+'">Stack '+ns+'</option>');
385                  update_current_graph(true);
386                }
387        });                                             
388        
389         //only allow stream toggling if the graph is locked and saved
390         $(".streamData").click(function() {
391                if(locked && graphinfo.saved) {
392                     if(!graphinfo.streaming) {
393                         graphinfo.streaming = true;
394                         $(this).html('Streaming!').fadeIn('slow');
395                         $(".stream-log").removeAttr("style").html("stream log_");
396                         stream_data(graphinfo.id, maingraph, $('#streambox'));
397                     }
398                     else if(graphinfo.streaming) {
399                         stop_streaming_graph();
400                         update_current_graph(true);
401                     }
402               }
403         });
404         $("#graph_datetool .btn-slide").click(function(){
405                 $("#graph_widgetCalendar").stop().animate({
406                      height: state ? 0 :
407                        $('#graph_widgetCalendar div.datepicker').get(0).offsetHeight
408                   }, 500);
409                 state = !state;
410                 $(this).toggleClass("active");
411                 return false;
412         });
413         $("#graph_datetool .datechoice").click(function(){
414                 $("#graph_datetool .range a.btn-slide").html("YYYY/MM/DD - YYYY/MM/DD");
415                 $("#graph_widgetCalendar").slideUp("slow");
416                 $("#graph_datetool .datechoice").removeClass("selected");
417
418                 //start here will be in seconds
419                 displayinfo.start = time_windows[$(this).html()];
420                 displayinfo.end = '';
421                 $(this).addClass("selected");
422                 var cdate = new Date();
423                 update_graph_permalink(graphinfo.id, parseInt(cdate.getTime() - displayinfo.start*1000), "", "");
424                 maingraph.ReconGraphRefresh({graphid: graphinfo.id, start: time_windows[$(this).html()], end: '', type: graphinfo.type});
425                 return false;
426         });
427         $('#graph_widgetCalendar').DatePicker({
428                 flat: true,
429                 format: 'Y/m/d',
430                 date: [new Date(), new Date()],
431                 calendars: 3,
432                 mode: 'range',
433                 starts: 1,
434                 onChange: function(formated) {
435                         var dates;
436                         dates = formated[0].split('/');
437                         var start = new Date(dates[0], dates[1]-1, dates[2], 0, 0, 0);
438                         dates = formated[1].split('/');
439                         var end = new Date((new Date(dates[0], dates[1]-1, dates[2], 0, 0, 0)).getTime() + 86400000);
440                         displayinfo.start = start.toUTCString();
441                         displayinfo.end = end.toUTCString();
442                         update_graph_permalink(graphinfo.id, parseInt(start.getTime()), parseInt(end.getTime()), "");
443                         maingraph.ReconGraphRefresh({graphid: graphinfo.id, start: displayinfo.start, end: displayinfo.end, type: graphinfo.type});
444                         $('#graph_datetool .range a.btn-slide').get(0).innerHTML = formated.join(' - ');
445                 }
446         });
447         $(".graphType").change(function(){
448                 graphinfo.type = $(this).val();
449                 update_current_graph(true);
450         });
451         $("#gtool-error").click(function(){
452           $("#gtool-error").fadeOut("slow");
453         });
454         $(".addGuide").click(function() {
455           if(!locked){
456             gtool_add_guide();
457           }
458         });
459
460         $("span.blankGraph").click(function() {
461
462           stop_streaming_graph();
463
464           // current graph is saved, so just give a new one.
465           if(graphinfo.saved) set_current_graph_id('');
466
467           // otherwise make sure the user wants to move on, and if so, give a new graph and orphan the unsaved one.
468           else if(graphinfo.saved!=undefined && graphinfo.saved==false) {
469             confirm("I will forget the current graph.  Are you sure?", function() {
470               set_current_graph_id('');
471             });
472           }
473
474           return false;
475         });
476
477         set_current_graph_id('');
478         maingraph = $('<div></div>').attr("id", "maingraph").ReconGraph({graphid: graphinfo.id, width: 780, height: 400});
479         $("#maingraphHolder").append(maingraph);
480 });
481 </script>
482
483 <div id="graph_datetool">
484         <div class="zoom">
485                 <dl>
486                         <dt>Zoom:</dt>
487                         <dd><a href="#" class="first datechoice">2d</a></dd>
488                         <dd><a href="#" class="datechoice">1w</a></dd>
489                         <dd><a href="#" class="selected datechoice">2w</a></dd>
490                         <dd><a href="#" class="datechoice">4w</a></dd>
491                         <dd><a href="#" class="datechoice">1y</a></dd>
492                 </dl>
493         </div>
494         <div class="range">
495                 <dl>
496                         <dt>Date Range:</dt>
497                         <dd><a href="" class="btn-slide">YYYY/MM/DD - YYYY/MM/DD</a></dd>
498                 </dl>
499         </div>
500 <br/>
501         <div id="graph_widgetCalendar" class="widgetCalendar"></div>
502 </div>
503                        
504 <!-- confirm box -->
505 <div id="confirm" style="display:none">
506         <a href="#" title="Close" class="modalCloseX modalClose">x</a>
507         <div class="header"><span>Confirm</span></div>
508         <p class="message"></p>
509         <div class="buttons">
510                 <div class="no modalClose">No</div><div class="yes">Yes</div>
511         </div>
512 </div>
513
514 <div>
515         <div id="maingraphHolder">
516         </div>
517         <div class='stream-log' style='display:none'></div>
518         <form action="#" name="form4" id="form4" style="margin:1em 0;text-align:center;">
519         <fieldset>
520         <legend style="display:none;">View</legend>
521         <label for="std_view"><input class="graphType" type="radio" name="graphtype" id="std_view" value="standard"/> Standard View</label> &nbsp;&nbsp;&nbsp;
522         <label for="stacked_view"><input class="graphType" type="radio" name="graphtype" id="stacked_view" value="stacked" /> Stack Left Axis</label>
523         </fieldset>
524         </form>
525        
526 </div>
527 <span class="graphStacks"></span>
528 <div><span class="editStacks">Add Stack Set</span></div>
529 <div style="float:right"><span class="addGuide">Add Guide</span></div>
530 <br style="clear:right" />
531 <div class="error"><p class="error" id="gtool-error"></p></div>
532 <table id="gtool">
533         <tr>
534                 <th></th>
535                
536                 <th class="data">Data Points</th>
537                 <th>Stacking</th>
538                 <th>Color</th>
539                 <th>Derivative</th>
540                 <th>Axis</th>
541                 <th></th>
542                 <th></th>
543         </tr>
544         <tbody id="dataPoints">
545         </tbody>
546 </table>
547
548 <div style="display:none">
549 <form id="hiddeneditor">
550         <table>
551         <tbody id="guideeditor">
552         <tr>           
553                 <td><input name="view" type="checkbox" value="1" /></td>
554                 <td class="data datatitle"></td>
555                 <td><div class="colorPicker"><div class="colorSelector"><div style="background-color: #fff"></div></div><div class="colorPickerHolder"></div></div></td>
556                 <td></td>
557                 <td></td>
558                 <td><a href="#" class="deletedatapoint"><span>delete</span></a></td>
559                 <td class="math">math</td>
560         </tr>
561         <tr class="mathbox">
562                 <td colspan="7">
563                 <div>
564                         <label for="math">Display Math</label> <input name="math1" type="text" value="" style="width:380px;" />
565                 </div>
566                 <div>
567                         <label for="math">Percentile</label> <input name="math2" type="text" value="" style="width:380px;" />
568                 </div>
569                 </td>
570         </tr>
571         </tbody>
572         <tbody id="datapointeditor">
573         <tr>
574                 <td><input name="view" type="checkbox" value="1"/></td>
575                 <td class="data datatitle"></td>
576                 <td><select id="datastack" class="av_stacks"><option value='na'>select</option></select></td>
577                 <td><div class="colorPicker"><div class="colorSelector"><div style="background-color: #fff"></div></div><div class="colorPickerHolder"></div></div></td>
578                 <td><select name="derive"><option value="false">no</option><option value="derive">derive</option><option value="counter">counter</option></select></td>
579                 <td><span class="axis axisl"> L</span> <span class="axis axisr"> R</span></td>
580                 <td><a href="#" class="deletedatapoint"><span>delete</span></a></td>
581                 <td class="math">math</td>
582         </tr>
583         <tr class="mathbox">
584                 <td colspan="7">
585                 <div>
586                         <label for="math">Display Math</label> <input name="math1" type="text" value="" style="width:380px;" />
587                 </div>
588                 <div>   
589                         <label for="math">Source Math</label> <input name="math2" type="text" value="" style="width:380px;" />
590                 </div>
591                 </td>
592         </tr>
593         </tbody>
594         </table>
595 </form>
596 </div>
597
598 <div id="payload">
599 </div>
Note: See TracBrowser for help on using the browser.