From 2f1193f0781b39dfebf29fee593a053c72db6488 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Sun, 1 Aug 2010 12:55:34 +0200 Subject: [PATCH] no more mode radio button; leases behave individually, and a new row of timeslot buttons allow to book/release all nodes at once in fact nodes are selectable as well (click the node) the logic sounds fine but needs to find nicer visuals to give hints on how to use this also needs to become scrollable in time still no real call to the API at this point --- planetlab/css/my_slice.css | 2 +- planetlab/slices/leases.js | 221 +++++++++++++++++++++++++------------ planetlab/slices/slice.php | 9 +- 3 files changed, 150 insertions(+), 82 deletions(-) diff --git a/planetlab/css/my_slice.css b/planetlab/css/my_slice.css index 15b5dd9..c79af1f 100644 --- a/planetlab/css/my_slice.css +++ b/planetlab/css/my_slice.css @@ -37,7 +37,7 @@ table#leases_data { /* upper section, with selection mode */ #leases_modes { padding: 10px; text-align: center; color: #333; } -#leases_buttons { padding: 10px; } +#leases_buttons { padding: 0px 10px 10px 10px; } #leases_clear { position: relative; left: 30%;} #leases_submit { position: relative; left: 60%; } diff --git a/planetlab/slices/leases.js b/planetlab/slices/leases.js index d34826d..a1eea8d 100644 --- a/planetlab/slices/leases.js +++ b/planetlab/slices/leases.js @@ -1,21 +1,32 @@ /* need to put some place else in CSS ? */ +// space for the nodenames +var x_nodelabel = 200; +// right space after the nodename - removed from the above +var x_sep=20; +// height for the (two) rows of timelabels +var y_header = 12; +// space between nodes +var y_sep = 10; + +// 1-grain leases attributes +var x_grain = 24; +var y_node = 15; +var radius= 6; + +var anim_delay=500; /* decorations / headers */ -var txt_nodename = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif', stroke: "none", fill: "#008"}; -var txt_timeslot = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif', stroke: "none", fill: "#008"}; +// vertical rules var attr_rules={'fill':"#888", 'stroke-dasharray':'- ', 'stroke-width':0.5}; -var x_nodename = 200; -var x_sep=10; -var y_header = 12 -var y_sep = 20 +var txt_timelabel = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif', stroke: "none", fill: "#008"}; +var txt_allnodes = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif', stroke: "none", fill: "#404"}; +var txt_nodelabel = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif', stroke: "none", fill: "#008"}; + +var attr_timebutton = {'fill': '#888','stroke-width':2}; /* lease dimensions and colors */ -var anim_delay=500; -var x_grain = 24; -var y_node = 15; -var radius= 6; /* lease was originally free and is still free */ var attr_lease_free_free={'fill':"#def", 'stroke-width':0.5, 'stroke-dasharray':''}; /* lease was originally free and is now set for our usage */ @@ -36,6 +47,7 @@ var txt_slice = {"font": '"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif' // the scheduler object function Scheduler (slicename, axisx, axisy, data) { + // the data only contain slice names, we need this to find our own leases (mine) this.slicename=slicename; this.axisx=axisx; this.axisy=axisy; @@ -50,46 +62,77 @@ function Scheduler (slicename, axisx, axisy, data) { // how many time slots this.nb_grains = function () { return axisx.length;} - this.init = function (id) { - this.total_width = x_nodename + this.nb_grains()*x_grain; - this.total_height = 2*y_header + this.axisy.length*(y_node+y_sep); - paper = Raphael (id, this.total_width, this.total_height); + this.init = function (canvas_id) { + this.total_width = x_nodelabel + this.nb_grains()*x_grain; + this.total_height = 2*y_header /* the timelabels */ + + 2*y_sep /* extra space */ + + y_node /* all-nodes & timebuttons row */ + + (this.axisy.length)*(y_node+y_sep); /* the regular nodes and preceding space */ + paper = Raphael (canvas_id, this.total_width+x_sep, this.total_height); + + // maintain the list of nodelabels for the 'all nodes' button + this.nodelabels=[]; - // create the time slots legend + ////////// create the time slots legend var top=0; - var left=x_nodename; + var left=x_nodelabel; var col=0; for (var i=0, len=axisx.length; i < len; ++i) { // pick the printable part - timeslot=axisx[i][1]; + timelabel=axisx[i][1]; var y = top+y_header; if (col%2 == 0) y += y_header; col +=1; - var timelabel=paper.text(left,y,timeslot).attr(txt_timeslot) + // display time label + var timelabel=paper.text(left,y,timelabel).attr(txt_timelabel) .attr({"font-size":y_header, "text-anchor":"middle"}); + // draw vertical line var path_spec="M"+left+" "+(y+y_header/2)+"L"+left+" "+this.total_height; var rule=paper.path(path_spec).attr(attr_rules); left+=x_grain; } - // move to the lines below: - top += 2*y_header+y_sep; - + this.granularity=axisx[1][0]-axisx[0][0]; + + ////////// the row with the timeslot buttons + // move two lines down + top += 2*y_header+2*y_sep; + left=x_nodelabel; + // all nodes buttons + var allnodes = paper.text (x_nodelabel-x_sep,top+y_node/2,"All nodes").attr(txt_allnodes) + .attr ({"font-size":y_node, "text-anchor":"end","baseline":"bottom"}); + allnodes.scheduler=this; + allnodes.click(allnodes_methods.click); + // timeslot buttons + for (var i=0, len=axisx.length; i < len; ++i) { + var timebutton = paper.rect(left,top,x_grain,y_node,radius).attr(attr_timebutton); + timebutton.from_time=axisx[i][0]; + timebutton.scheduler=this; + timebutton.click(timebutton_methods.click); + left+=x_grain; + } + + //////// the body of the scheduler: nodes + top += y_node+y_sep; var data_index=0; for (var i=0, len=axisy.length; i0) ? 1 : 0; + for (var i=0, len=scheduler.nodelabels.length; i=until_time) { + if (scan.current == "free") relevant_free.push(scan); + else if (scan.current == "mine") relevant_mine.push(scan); + } + } +// window.console.log("Found " + relevant_free.length + " free and " + relevant_mine.length + " mine"); + /* decide what to do, whether book or release */ + if (relevant_mine.length==0 && relevant_free.length==0) { + alert ("Nothing to do in this timeslot on the selected nodes"); + return; + } + // if at least one is free, let's book + if (relevant_free.length > 0) { + for (var i=0, len=relevant_free.length; i=this.until_time) - if (scan.current == "free") lease_methods.init_mine(scan,lease_methods.click_free); - } - } + lease_methods.init_mine(this,lease_methods.click_free); }, init_mine: function (lease, unclick) { @@ -216,30 +305,20 @@ var lease_methods = { var scheduler = this.scheduler; // this lease was originally free but is now marked for booking // we free just this lease - if (scheduler.mode=='node') { - lease_methods.init_free(this, lease_methods.click_mine); - } else { - for (var i=0, len=scheduler.leases.length; i=this.until_time) { - if (scan.current == "mine") lease_methods.init_free(scan,lease_methods.click_mine); - } - // the other ones just remain as they are - } - } + lease_methods.init_free(this, lease_methods.click_mine); }, init_other: function (lease, slicename) { lease.animate (attr_lease_other,anim_delay); /* a text obj to display the name of the slice that owns that lease */ - var slicelabel = paper.text (lease.attr("x")+lease.attr("width")/2, - lease.attr("y")+lease.attr("height")/2,slicename).attr(txt_slice); + var otherslicelabel = paper.text (lease.attr("x")+lease.attr("width")/2, + // xxx + lease.attr("y")+lease.attr("height")/2,slicename).attr(txt_slice); /* hide it right away */ - slicelabel.hide(); + otherslicelabel.hide(); /* record it */ - lease.label=slicelabel; + lease.label=otherslicelabel; lease.hover ( function (e) { this.label.toFront(); this.label.show(); }, function (e) { this.label.hide(); } ); }, @@ -251,7 +330,7 @@ function init_scheduler () { var table = $$("table#leases_data")[0]; // no reservable nodes - no data if ( ! table) return; - // the nodenames + // the nodelabels table.getElementsBySelector("tbody>tr>th").each(function (cell) { axisy.push(getInnerText(cell)); }); @@ -275,10 +354,6 @@ function init_scheduler () { var clear=$$("button#leases_clear")[0]; clear.onclick = function () { scheduler.clear(); } - var node_button=$$("input#leases_mode_node")[0]; - var timeslot_button=$$("input#leases_mode_timeslot")[0]; - scheduler.init_mode ('timeslot',node_button,timeslot_button); - } Event.observe(window, 'load', init_scheduler); diff --git a/planetlab/slices/slice.php b/planetlab/slices/slice.php index fb0faa1..74edc83 100644 --- a/planetlab/slices/slice.php +++ b/planetlab/slices/slice.php @@ -570,7 +570,7 @@ if ($count && $privileges) { if ($leases && ($leases[0]['nfrom']<=$counter)) { $lease=array_shift($leases); /* nicer display, merge two consecutive leases for the same slice - -*- tmp -*- avoid doing that for now, as it might makes things confusing */ + avoid doing that for now, as it might makes things confusing */ /* while ($leases && ($leases[0]['name']==$lease['name']) && ($leases[0]['nfrom']==$lease['nuntil'])) { $lease['nuntil']=$leases[0]['nuntil']; array_shift($leases); @@ -589,13 +589,6 @@ if ($count && $privileges) { // the general layout for the scheduler echo <<< EOF -
- Selection mode: - Node - Timeslot - -
-
-- 2.47.0