You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2010/10/20 18:17:20 UTC
svn commit: r1025626 - in /incubator/vcl/trunk/web: .ht-inc/dashboard.php
.ht-inc/states.php .ht-inc/statistics.php .ht-inc/utils.php
css/dashboard.css js/code.js js/dashboard.js js/statistics.js
Author: jfthomps
Date: Wed Oct 20 16:17:19 2010
New Revision: 1025626
URL: http://svn.apache.org/viewvc?rev=1025626&view=rev
Log:
VCL-310 - remove jpgraph dependency
replaced all jpgraph code with dojox's charting api
VCL-399 - add a dashboard where admins can see current state of VCL system
added a new section to the site that is a page displaying various information about the site that gets updated with AJAX every n seconds; currently there are the following sections of information:
Current Status - some general info
Top 5 Images in Use
Top 5 Long Term Images in Use
Top Recent Computer Failures
Top Recent Image Failures
Block Allocation Status
Past 12 Hours of Active Reservations
statistics.php
-removed require_once code for jpgraph
-modified viewStatistics - when computing length of reservation, if $length ends up being < 0, set it to 0
-changed img references to jpgraphs to divs for dojox charts
-added AJgetStatData
-removed sendStatGraphDay
-modified getStatGraphDayData - removed labels from $data, added xlabels to $data, added maxy to $data
-removed statXaxisDayCallback
-removed sendStatGraphHour
-modified getStatGraphHourData - changed $data['points'] to be an array of data, added maxy to $data
-renamed statXaxisHourCallback to statHourFromatX
-removed sendStatGraphDayConUsers
-modified getStatGraphDayConUsersData - removed labels from $data, added xlabels to $data, added maxy to $data
-removed statXaxisDayConUsersCallback
-removed sendStatGraphConBladeUser
-modified getStatGraphConBladeUserData - removed labels from $data, added xlabels to $data, added maxy to $data
-removed statXaxisConBladeUserCallback
utils.php
-modified initGlobals - added dashboard to section that does require_once based on the mode
-modified getNavMenu - removed some old stuff left in there related to ecu $skin; added menu item for dashboard
-modified getDojoHTML - added sections for viewstats and dashboard modes
states.php
-added dashboard to entry actions
-added AJupdateDashboard and AJgetStatData to $noHTMLwrappers
-removed statgraphday, statgraphhour, statgraphdayconcuruser, and statgraphdayconcurblade
-added AJgetStatData
-added dashboard section with modes dashboard and AJupdateDashboard
js/code.js - modified errorHandler function reference - list of args were wrong; changed from 'type, error, data' to 'error, ioArgs'; changed args.dojoType to error.name (not sure if this is correct), changed alert to display better message
dashboard.php - initial add to source control
css/dashboard.css - initial add to source control
js/dashboard.js - initial add to source control
js/statistics.js - initial add to source control
Added:
incubator/vcl/trunk/web/.ht-inc/dashboard.php
incubator/vcl/trunk/web/css/dashboard.css
incubator/vcl/trunk/web/js/dashboard.js
incubator/vcl/trunk/web/js/statistics.js
Modified:
incubator/vcl/trunk/web/.ht-inc/states.php
incubator/vcl/trunk/web/.ht-inc/statistics.php
incubator/vcl/trunk/web/.ht-inc/utils.php
incubator/vcl/trunk/web/js/code.js
Added: incubator/vcl/trunk/web/.ht-inc/dashboard.php
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/dashboard.php?rev=1025626&view=auto
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/dashboard.php (added)
+++ incubator/vcl/trunk/web/.ht-inc/dashboard.php Wed Oct 20 16:17:19 2010
@@ -0,0 +1,422 @@
+<?php
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * \file
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn dashboard()
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function dashboard() {
+ print "<h2>VCL Dashboard</h2>\n";
+ print "<table summary=\"\">\n";
+ print "<tr>\n";
+
+ # -------- left column ---------
+ print "<td valign=\"top\">\n";
+ print addWidget('status', 'Current Status');
+ print addWidget('topimages', 'Top 5 Images in Use', '(Reservations < 24 hours long)');
+ print addWidget('toplongimages', 'Top 5 Long Term Images in Use', '(Reservations > 24 hours long)');
+ print addWidget('topfailedcomputers', 'Top Recent Computer Failures', '(Failed in the last 5 days)');
+ print "</td>\n";
+ # -------- end left column ---------
+
+ # ---------- right column ---------
+ print "<td valign=\"top\">\n";
+ print addWidget('topfailed', 'Top Recent Image Failures', '(Failed in the last 5 days)');
+ print addWidget('blockallocation', 'Block Allocation Status');
+ print addLineChart('reschart', 'Past 12 Hours of Active Reservations');
+ print "</td>\n";
+ # -------- end right column --------
+
+ print "</tr>\n";
+ print "</table>\n";
+ $cont = addContinuationsEntry('AJupdateDashboard', array('val' => 0), 60, 1, 0);
+ print "<input type=\"hidden\" id=\"updatecont\" value=\"$cont\">\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function AJupdateDashboard() {
+ $data = array();
+ $data['cont'] = addContinuationsEntry('AJupdateDashboard', array(), 60, 1, 0);
+ $data['status'] = getStatusData();
+ $data['topimages'] = getTopImageData();
+ $data['toplongimages'] = getTopLongImageData();
+ $data['topfailed'] = getTopFailedData();
+ $data['topfailedcomputers'] = getTopFailedComputersData();
+ $data['reschart'] = getActiveResChartData();
+ $data['blockallocation'] = getBlockAllocationData();
+ sendJSON($data);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn addWidget($id, $title)
+///
+/// \param
+///
+/// \return
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function addWidget($id, $title, $extra='') {
+ $txt = "<div class=\"dashwidget\">\n";
+ $txt .= "<h3>$title</h3>\n";
+ if($extra != '')
+ $txt .= "<div class=\"extra\">$extra</div>\n";
+ $txt .= "<div id=\"$id\"></div>\n";
+ $txt .= "</div>\n";
+ return $txt;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn addLineChart($id)
+///
+/// \param
+///
+/// \return
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function addLineChart($id, $title) {
+ $txt = "<div class=\"dashwidget\">\n";
+ $txt .= "<h3>$title</h3>\n";
+ $txt .= "<div dojoType=\"dojox.charting.widget.Chart2D\" id=\"$id\"\n";
+ $txt .= " theme=\"dojox.charting.themes.ThreeD\"\n";
+ $txt .= " style=\"width: 300px; height: 300px;\">\n";
+ $txt .= "<div class=\"axis\"\n";
+ $txt .= " name=\"x\"\n";
+ $txt .= " labelFunc=\"timestampToTime\"\n";
+ $txt .= " maxLabelSize=\"35\"\n";
+ $txt .= " rotation=\"-90\"\n";
+ $txt .= " majorTickStep=\"4\"\n";
+ $txt .= " minorTickStep=\"1\">\n";
+ $txt .= " </div>\n";
+ $txt .= "<div class=\"axis\" name=\"y\" vertical=\"true\" includeZero=\"true\"></div>\n";
+ $txt .= "<div class=\"plot\" name=\"default\" type=\"Lines\" markers=\"true\"></div>\n";
+ $txt .= "<div class=\"plot\" name=\"grid\" type=\"Grid\" vMajorLines=\"false\"></div>\n";
+ $txt .= "<div class=\"series\" name=\"Main\" data=\"0\"></div>\n";
+ $txt .= "<div class=\"action\" type=\"Tooltip\"></div>\n";
+ $txt .= "<div class=\"action\" type=\"Magnify\"></div>\n";
+ $txt .= "</div>\n";
+ $txt .= "</div>\n";
+ return $txt;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getStatusData()
+///
+/// \return
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function getStatusData() {
+ $data = array();
+ $data[] = array('key' => 'Active Reservations', 'val' => 0);
+ $data[] = array('key' => 'Online Computers', 'val' => 0, 'tooltip' => 'Computers in states available, reserved,<br>reloading, inuse, or timeout');
+ $data[] = array('key' => 'Failed Computers', 'val' => 0);
+ $reloadid = getUserlistID('vclreload@Local');
+ $query = "SELECT COUNT(id) "
+ . "FROM request "
+ . "WHERE userid != $reloadid AND "
+ . "stateid NOT IN (1, 5, 12) AND "
+ . "start < NOW() AND "
+ . "end > NOW()";
+ $qh = doQuery($query, 101);
+ if($row = mysql_fetch_row($qh))
+ $data[0]['val'] = $row[0];
+
+ $query = "SELECT COUNT(id) FROM computer WHERE stateid IN (2, 3, 6, 8, 11)";
+ $qh = doQuery($query, 101);
+ if($row = mysql_fetch_row($qh))
+ $data[1]['val'] = $row[0];
+
+ $query = "SELECT COUNT(id) FROM computer WHERE stateid = 5";
+ $qh = doQuery($query, 101);
+ if($row = mysql_fetch_row($qh))
+ $data[2]['val'] = $row[0];
+ return $data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn
+///
+/// \return
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function getTopImageData() {
+ $query = "SELECT COUNT(c.currentimageid) AS count, "
+ . "i.prettyname "
+ . "FROM computer c, "
+ . "image i "
+ . "WHERE c.currentimageid = i.id AND "
+ . "c.stateid = 8 "
+ . "GROUP BY c.currentimageid "
+ . "ORDER BY count DESC "
+ . "LIMIT 5";
+ $query = "SELECT COUNT(rs.imageid) AS count, "
+ . "i.prettyname "
+ . "FROM reservation rs, "
+ . "request rq, "
+ . "image i "
+ . "WHERE rs.imageid = i.id AND "
+ . "rq.stateid = 8 AND "
+ . "rs.requestid = rq.id AND "
+ . "TIMESTAMPDIFF(HOUR, rq.start, rq.end) <= 24 "
+ . "GROUP BY rs.imageid "
+ . "ORDER BY count DESC "
+ . "LIMIT 5";
+ $data = array();
+ $qh = doQuery($query, 101);
+ while($row = mysql_fetch_assoc($qh))
+ $data[] = $row;
+ return $data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn
+///
+/// \return
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function getTopLongImageData() {
+ $query = "SELECT COUNT(rs.imageid) AS count, "
+ . "i.prettyname, "
+ . "TIMESTAMPDIFF(HOUR, rq.start, rq.end) AS reslen "
+ . "FROM reservation rs, "
+ . "request rq, "
+ . "image i "
+ . "WHERE rs.imageid = i.id AND "
+ . "rq.stateid = 8 AND "
+ . "rs.requestid = rq.id "
+ . "GROUP BY rs.imageid "
+ . "HAVING reslen > 24 "
+ . "ORDER BY count DESC "
+ . "LIMIT 5";
+ $query = "SELECT COUNT(rs.imageid) AS count, "
+ . "i.prettyname "
+ . "FROM reservation rs, "
+ . "request rq, "
+ . "image i "
+ . "WHERE rs.imageid = i.id AND "
+ . "rq.stateid = 8 AND "
+ . "rs.requestid = rq.id AND "
+ . "TIMESTAMPDIFF(HOUR, rq.start, rq.end) > 24 "
+ . "GROUP BY rs.imageid "
+ . "ORDER BY count DESC "
+ . "LIMIT 5";
+ $data = array();
+ $qh = doQuery($query, 101);
+ while($row = mysql_fetch_assoc($qh))
+ $data[] = $row;
+ return $data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getTopFailedData()
+///
+/// \return
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function getTopFailedData() {
+ $query = "SELECT COUNT(l.imageid) AS count, "
+ . "i.prettyname "
+ . "FROM log l, "
+ . "image i "
+ . "WHERE l.imageid = i.id AND "
+ . "l.ending = 'failed' AND "
+ . "l.start > DATE_SUB(NOW(), INTERVAL 5 DAY) "
+ . "GROUP BY l.imageid "
+ . "ORDER BY count DESC "
+ . "LIMIT 5";
+ $data = array();
+ $qh = doQuery($query, 101);
+ while($row = mysql_fetch_assoc($qh))
+ $data[] = $row;
+ return $data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getTopFailedComputersData()
+///
+/// \return
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function getTopFailedComputersData() {
+ $query = "SELECT COUNT(s.computerid) AS count, "
+ . "c.hostname "
+ . "FROM log l, "
+ . "sublog s, "
+ . "computer c "
+ . "WHERE s.logid = l.id AND "
+ . "s.computerid = c.id AND "
+ . "l.ending = 'failed' AND "
+ . "l.start > DATE_SUB(NOW(), INTERVAL 5 DAY) "
+ . "GROUP BY s.computerid "
+ . "ORDER BY count DESC "
+ . "LIMIT 5";
+ $data = array();
+ $qh = doQuery($query, 101);
+ while($row = mysql_fetch_assoc($qh))
+ $data[] = $row;
+ return $data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getActiveResChartData()
+///
+/// \return
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function getActiveResChartData() {
+ $data = array();
+ $chartstart = unixFloor15(time() - (12 * 3600));
+ $chartend = $chartstart + (12 * 3600) + 900;
+ for($time = $chartstart, $i = 0; $time < $chartend; $time += 900, $i++) {
+ $fmttime = date('g:i a', $time);
+ $data["points"][$i] = array('x' => $i, 'y' => 0, 'value' => $i, 'text' => $fmttime);
+ }
+ $data['maxy'] = 0;
+ $reloadid = getUserlistID('vclreload@Local');
+ $query = "SELECT id, "
+ . "UNIX_TIMESTAMP(start) AS start, "
+ . "UNIX_TIMESTAMP(finalend) AS end "
+ . "FROM log "
+ . "WHERE start < NOW() AND "
+ . "finalend > DATE_SUB(NOW(), INTERVAL 12 HOUR) AND "
+ . "ending NOT IN ('failed', 'failedtest') AND "
+ . "wasavailable = 1 AND "
+ . "userid != $reloadid";
+ $qh = doQuery($query, 101);
+ while($row = mysql_fetch_assoc($qh)) {
+ for($binstart = $chartstart, $binend = $chartstart + 900, $binindex = 0;
+ $binend <= $chartend;
+ $binstart += 900, $binend += 900, $binindex++) {
+ if($binend <= $row['start'])
+ continue;
+ elseif($row['start'] < $binend &&
+ $row['end'] > $binstart) {
+ $data["points"][$binindex]['y']++;
+ }
+ elseif($binstart >= $row['end'])
+ break;
+ }
+ }
+ for($time = $chartstart, $i = 0; $time < $chartend; $time += 900, $i++) {
+ if($data["points"][$i]['y'] > $data['maxy'])
+ $data['maxy'] = $data['points'][$i]['y'];
+ $data["points"][$i]['tooltip'] = "{$data['points'][$i]['text']}: {$data['points'][$i]['y']}";
+ }
+ return $data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getBlockAllocationData()
+///
+/// \param
+///
+/// \return
+///
+/// \brief
+///
+////////////////////////////////////////////////////////////////////////////////
+function getBlockAllocationData() {
+ # active block allocation
+ $query = "SELECT COUNT(id) "
+ . "FROM blockTimes "
+ . "WHERE skip = 0 AND "
+ . "start < NOW() AND "
+ . "end > NOW()";
+ $qh = doQuery($query, 101);
+ $row = mysql_fetch_row($qh);
+ $blockcount = $row[0];
+ # computers in blockComputers for active allocations
+ $query = "SELECT bc.computerid, "
+ . "c.stateid "
+ . "FROM blockComputers bc "
+ . "LEFT JOIN computer c ON (c.id = bc.computerid) "
+ . "LEFT JOIN blockTimes bt ON (bt.id = bc.blockTimeid) "
+ . "WHERE c.stateid IN (2, 3, 6, 8, 19) AND "
+ . "bt.start < NOW() AND "
+ . "bt.end > NOW()";
+ $qh = doQuery($query, 101);
+ $total = 0;
+ $used = 0;
+ while($row = mysql_fetch_assoc($qh)) {
+ $total++;
+ if($row['stateid'] == 3 || $row['stateid'] == 8)
+ $used++;
+ }
+ if($total)
+ $compused = sprintf('%d / %d (%0.2f %%)', $used, $total, ($used / $total * 100));
+ else
+ $compused = 0;
+ # number of computers that should be allocated
+ $query = "SELECT br.numMachines "
+ . "FROM blockRequest br "
+ . "LEFT JOIN blockTimes bt ON (bt.blockRequestid = br.id) "
+ . "WHERE bt.start < NOW() AND "
+ . "bt.end > NOW() AND "
+ . "bt.skip = 0";
+ $alloc = 0;
+ $qh = doQuery($query, 101);
+ while($row = mysql_fetch_assoc($qh))
+ $alloc += $row['numMachines'];
+ if($alloc)
+ $failed = sprintf('%d / %d (%0.2f %%)', ($alloc - $total), $alloc, (($alloc - $total) / $alloc * 100));
+ else
+ $failed = 0;
+ $data = array();
+ $data[] = array('title' => 'Active Block Allocations', 'val' => $blockcount);
+ $data[] = array('title' => 'Block Computer Usage', 'val' => $compused);
+ $data[] = array('title' => 'Failed Block Computers', 'val' => $failed);
+ return $data;
+}
+?>
Modified: incubator/vcl/trunk/web/.ht-inc/states.php
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/states.php?rev=1025626&r1=1025625&r2=1025626&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/states.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/states.php Wed Oct 20 16:17:19 2010
@@ -55,6 +55,7 @@ $actions["entry"] = array('main',
'continuationsError',
'requestBlockAllocation',
'siteMaintenance',
+ 'dashboard',
);
$noHTMLwrappers = array('sendRDPfile',
@@ -142,6 +143,8 @@ $noHTMLwrappers = array('sendRDPfile',
'AJgetScheduleTimesData',
'AJsaveScheduleTimes',
'AJvalidateUserid',
+ 'AJupdateDashboard',
+ 'AJgetStatData',
);
# main
@@ -555,19 +558,12 @@ $actions['pages']['userLookup'] = "userL
$actions['pages']['submitUserLookup'] = "userLookup";
# statistics
-# TODO might need the statgraph modes to be entry modes
$actions['mode']['selectstats'] = "selectStatistics"; # entry
$actions['mode']['viewstats'] = "viewStatistics";
-$actions['mode']['statgraphday'] = "sendStatGraphDay";
-$actions['mode']['statgraphhour'] = "sendStatGraphHour";
-$actions['mode']['statgraphdayconcuruser'] = "sendStatGraphDayConUsers";
-$actions['mode']['statgraphdayconcurblade'] = "sendStatGraphConBladeUser";
+$actions['mode']['AJgetStatData'] = "AJgetStatData";
$actions['pages']['selectstats'] = "statistics";
$actions['pages']['viewstats'] = "statistics";
-$actions['pages']['statgraphday'] = "statistics";
-$actions['pages']['statgraphhour'] = "statistics";
-$actions['pages']['statgraphdayconcuruser'] = "statistics";
-$actions['pages']['statgraphdayconcurblade'] = "statistics";
+$actions['pages']['AJgetStatData'] = "statistics";
# help
$actions['mode']['helpform'] = "printHelpForm"; # entry
@@ -635,6 +631,12 @@ $actions['pages']['AJgetDelSiteMaintenan
$actions['pages']['AJeditSiteMaintenance'] = "sitemaintenance";
$actions['pages']['AJdeleteSiteMaintenance'] = "sitemaintenance";
+# dashboard
+$actions['mode']['dashboard'] = "dashboard";
+$actions['mode']['AJupdateDashboard'] = "AJupdateDashboard";
+$actions['pages']['dashboard'] = "dashboard";
+$actions['pages']['AJupdateDashboard'] = "dashboard";
+
# RPC
$actions['mode']['xmlrpccall'] = "xmlrpccall";
$actions['mode']['xmlrpcaffiliations'] = "xmlrpcgetaffiliations";
Modified: incubator/vcl/trunk/web/.ht-inc/statistics.php
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/statistics.php?rev=1025626&r1=1025625&r2=1025626&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/statistics.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/statistics.php Wed Oct 20 16:17:19 2010
@@ -16,21 +16,6 @@
limitations under the License.
*/
-if($phpVer == 5) {
- if(is_dir(".ht-inc/jpgraph")) {
- require_once(".ht-inc/jpgraph/jpgraph.php");
- require_once(".ht-inc/jpgraph/jpgraph_bar.php");
- require_once(".ht-inc/jpgraph/jpgraph_line.php");
- }
-}
-else {
- if(is_dir(".ht-inc/jpgraph.old")) {
- require_once(".ht-inc/jpgraph.old/jpgraph.php");
- require_once(".ht-inc/jpgraph.old/jpgraph_bar.php");
- require_once(".ht-inc/jpgraph.old/jpgraph_line.php");
- }
-}
-
/**
* \file
*/
@@ -289,6 +274,8 @@ function viewStatistics() {
# lengths
$length = $row["finalend"] - $row["start"];
+ if($length < 0)
+ $length = 0;
if($length <= 1800)
$lengths["30min"]++;
elseif($length <= 3600)
@@ -467,6 +454,7 @@ function viewStatistics() {
print " </TR>\n";
print "</TABLE>\n";
print "<br>\n";
+ print "</div>\n";
$unixstart = datetimeToUnix($start);
$unixend = datetimeToUnix($end);
@@ -476,30 +464,38 @@ function viewStatistics() {
'end' => $end,
'affilid' => $affilid);
print "<H2>Reservations by Day</H2>\n";
- $cont = addContinuationsEntry('statgraphday', $cdata);
- print "<img src=" . BASEURL . SCRIPT . "?continuation=$cont>";
+ print "<small>(Reservations with start time on given day)</small><br>\n";
+ $cdata['divid'] = 'resbyday';
+ $cont = addContinuationsEntry('AJgetStatData', $cdata);
+ print "<input type=hidden id=statdaycont value=\"$cont\">\n";
+ print "<div id=\"resbyday\" style=\"width: 400px; height: 310px;\">(Loading...)</div>\n";
print "<H2>Max Concurrent Reservations By Day</H2>\n";
if($unixend - $unixstart > SECINMONTH)
print "(this graph only available for up to a month of data)<br>\n";
else {
- $cont = addContinuationsEntry('statgraphdayconcuruser', $cdata);
- print "<img src=" . BASEURL . SCRIPT . "?continuation=$cont>";
+ $cdata['divid'] = 'maxconcurresday';
+ $cont = addContinuationsEntry('AJgetStatData', $cdata);
+ print "<input type=hidden id=statconcurrescont value=\"$cont\">\n";
+ print "<div id=\"maxconcurresday\" style=\"width: 400px; height: 310px;\">Loading graph data...</div>\n";
}
print "<H2>Max Concurrent Blade Reservations By Day</H2>\n";
if($unixend - $unixstart > SECINMONTH)
print "(this graph only available for up to a month of data)<br>\n";
else {
- $cont = addContinuationsEntry('statgraphdayconcurblade', $cdata);
- print "<img src=" . BASEURL . SCRIPT . "?continuation=$cont>";
+ $cdata['divid'] = 'maxconcurbladeday';
+ $cont = addContinuationsEntry('AJgetStatData', $cdata);
+ print "<input type=hidden id=statconcurbladecont value=\"$cont\">\n";
+ print "<div id=\"maxconcurbladeday\" style=\"width: 400px; height: 310px;\">Loading graph data...</div>\n";
}
print "<H2>Reservations by Hour</H2>\n";
- print "(Averaged over the time period)<br><br>\n";
- $cont = addContinuationsEntry('statgraphhour', $cdata);
- print "<img src=" . BASEURL . SCRIPT . "?continuation=$cont>";
- print "</div>\n";
+ print "<small>(Active reservations during given hour averaged over selected dates)</small><br><br>\n";
+ $cdata['divid'] = 'resbyhour';
+ $cont = addContinuationsEntry('AJgetStatData', $cdata);
+ print "<input type=hidden id=statreshourcont value=\"$cont\">\n";
+ print "<div id=\"resbyhour\" style=\"width: 400px; height: 310px;\">Loading graph data...</div>\n";
$endtime = microtime(1);
$end = $endtime - $timestart;
@@ -508,36 +504,26 @@ function viewStatistics() {
////////////////////////////////////////////////////////////////////////////////
///
-/// \fn sendStatGraphDay()
+/// \fn AJgetStatData()
///
-/// \brief sends a graph image
+/// \brief gets statistical data for a dojox chart and returns it in json format
///
////////////////////////////////////////////////////////////////////////////////
-function sendStatGraphDay() {
- global $xaxislabels, $inContinuation;
- if(! $inContinuation)
- return;
+function AJgetStatData() {
$start = getContinuationVar("start");
$end = getContinuationVar("end");
$affilid = getContinuationVar("affilid");
- $graphdata = getStatGraphDayData($start, $end, $affilid);
- $count = count($graphdata["labels"]);
- if($count < 8)
- $labelinterval = 1;
- else
- $labelinterval = $count / 7;
- $xaxislabels = $graphdata["labels"];
- $graph = new Graph(300, 300, "auto");
- $graph->SetScale("textlin");
- $plot = new BarPlot($graphdata["points"]);
- $graph->Add($plot);
- $graph->xaxis->SetLabelFormatCallback('statXaxisDayCallback');
- $graph->xaxis->SetLabelAngle(90);
- $graph->xaxis->SetTextLabelInterval($labelinterval);
- $graph->yaxis->SetTitle('Reservations with start time on given day',
- 'high');
- $graph->SetMargin(40,40,20,80);
- $graph->Stroke();
+ $divid = getContinuationVar('divid');
+ if($divid == 'resbyday')
+ $data = getStatGraphDayData($start, $end, $affilid);
+ elseif($divid == 'maxconcurresday')
+ $data = getStatGraphDayConUsersData($start, $end, $affilid);
+ elseif($divid == 'maxconcurbladeday')
+ $data = getStatGraphConBladeUserData($start, $end, $affilid);
+ elseif($divid == 'resbyhour')
+ $data = getStatGraphHourData($start, $end, $affilid);
+ $data['id'] = $divid;
+ sendJSON($data);
}
////////////////////////////////////////////////////////////////////////////////
@@ -548,9 +534,13 @@ function sendStatGraphDay() {
/// \param $end - ending day in YYYY-MM-DD format
/// \param $affilid - affiliationid of data to gather
///
-/// \return an array whose keys are the days (in YYYY-MM-DD format) between
-/// $start and $end, inclusive, and whose values are the number of reservations
-/// on each day
+/// \return an array with three keys:\n
+/// \b points - an array with y and tooltip keys that have the same value which
+/// is the y value at that point\n
+/// \b xlabels - an array with value and text keys, value's value is just an
+/// increasing integer starting from 1, text's value is the label
+/// to display on the x axis for the poing\n
+/// \b maxy - the max y value of the data
///
/// \brief queries the log table to get reservations between $start and $end
/// and creates an array with the number of reservations on each day
@@ -562,10 +552,12 @@ function getStatGraphDayData($start, $en
$data = array();
$data["points"] = array();
- $data["labels"] = array();
+ $data['xlabels'] = array();
+ $data['maxy'] = 0;
$reloadid = getUserlistID('vclreload@Local');
+ $cnt = 0;
for($i = $startunix; $i < $endunix; $i += SECINDAY) {
- array_push($data["labels"], date('Y-m-d', $i));
+ $cnt++;
$startdt = unixToDatetime($i);
$enddt = unixToDatetime($i + SECINDAY);
if($affilid != 0) {
@@ -589,69 +581,35 @@ function getStatGraphDayData($start, $en
}
$qh = doQuery($query, 295);
if($row = mysql_fetch_row($qh))
- array_push($data["points"], $row[0]);
+ $value = $row[0];
else
- array_push($data["points"], 0);
+ $value = 0;
+ $label = date('m/d/Y', $i);
+ $data['points'][] = array('y' => (int)$value, 'tooltip' => "$label: " . (int)$value);
+ if($value > $data['maxy'])
+ $data['maxy'] = (int)$value;
+ $data['xlabels'][] = array('value' => $cnt, 'text' => $label);
}
return($data);
}
////////////////////////////////////////////////////////////////////////////////
///
-/// \fn statXaxisDayCallback($val)
-///
-/// \param $val - value passed in by SetLabelFormatCallback
-///
-/// \return day of week
-///
-/// \brief formats $val into day of week
-///
-////////////////////////////////////////////////////////////////////////////////
-function statXaxisDayCallback($val) {
- global $xaxislabels;
- if(array_key_exists((int)$val, $xaxislabels)) {
- return date('n/d/Y', datetimeToUnix($xaxislabels[$val] . " 00:00:00")) . " ";
- }
- else {
- return $val;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \fn sendStatGraphHour()
-///
-/// \brief sends a graph image
-///
-////////////////////////////////////////////////////////////////////////////////
-function sendStatGraphHour() {
- global $xaxislabels, $inContinuation;
- if(! $inContinuation)
- return;
- $start = getContinuationVar("start");
- $end = getContinuationVar("end");
- $affilid = getContinuationVar("affilid");
- $graphdata = getStatGraphHourData($start, $end, $affilid);
- $graph = new Graph(300, 300, "auto");
- $graph->SetScale("textlin");
- $plot = new LinePlot($graphdata["points"]);
- $graph->Add($plot);
- $graph->xaxis->SetLabelFormatCallback('statXaxisHourCallback');
- $graph->xaxis->SetLabelAngle(90);
- $graph->xaxis->SetTextLabelInterval(2);
- $graph->yaxis->SetTitle('Active reservations during given hour', 'high');
- $graph->SetMargin(40,40,20,80);
- $graph->Stroke();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-///
/// \fn getStatGraphHourData($start, $end, $affilid)
///
/// \param $start - starting day in YYYY-MM-DD format
/// \param $end - ending day in YYYY-MM-DD format
/// \param $affilid - affiliationid of data to gather
///
+/// \return an array with two keys:\n
+/// \b points - an array with 5 keys:\n
+/// \t x - increasing integer starting from 1\n
+/// \t y - y value for the point\n
+/// \t value - same as x\n
+/// \t text - label for x axis for the point\n
+/// \t tooltip - tooltip to be displayed when point is hovered\n
+/// \b maxy - the max y value of the data
+///
/// \return an array whose keys are the days (in YYYY-MM-DD format) between
/// $start and $end, inclusive, and whose values are the number of reservations
/// on each day
@@ -671,8 +629,9 @@ function getStatGraphHourData($start, $e
$data = array();
$data["points"] = array();
for($i = 0; $i < 24; $i++) {
- $data["points"][$i] = 0;
+ $data["points"][$i] = array('x' => $i, 'y' => 0, 'value' => $i, 'text' => statHourFormatX($i), 'tooltip' => 0);
}
+ $data["maxy"] = 0;
$reloadid = getUserlistID('vclreload@Local');
if($affilid != 0) {
@@ -701,7 +660,6 @@ function getStatGraphHourData($start, $e
. "l.wasavailable = 1";
}
$qh = doQuery($query, 296);
- $count = 0;
while($row = mysql_fetch_assoc($qh)) {
$startmin = ($row['shour'] * 60) + $row['smin'];
$endmin = ($row['ehour'] * 60) + $row['emin'];
@@ -713,7 +671,7 @@ function getStatGraphHourData($start, $e
continue;
elseif($startmin < $binend &&
$endmin > $binstart) {
- $data["points"][$binindex]++;
+ $data["points"][$binindex]['y']++;
}
elseif($binstart >= $endmin)
break;
@@ -721,70 +679,39 @@ function getStatGraphHourData($start, $e
}
# comment this to change graph to be aggregate instead of average
- foreach($data["points"] as $key => $val)
- $data["points"][$key] = $val / $days;
+ foreach($data["points"] as $key => $val) {
+ $newval = $val['y'] / $days;
+ if($newval - (int)$newval != 0)
+ $newval = sprintf('%.2f', $newval);
+ $data['points'][$key]['y'] = $newval;
+ $data['points'][$key]['tooltip'] = $newval;
+ if($newval > $data['maxy'])
+ $data['maxy'] = $newval;
+ }
return($data);
}
////////////////////////////////////////////////////////////////////////////////
///
-/// \fn statXaxisHourCallback($val)
+/// \fn statHourFormatX($val)
///
-/// \param $val - value passed in by SetLabelFormatCallback
+/// \param $val - hour of day (0-23)
///
/// \return day of week
///
-/// \brief formats $val into day of week
+/// \brief formats $val into "hour am/pm"
///
////////////////////////////////////////////////////////////////////////////////
-function statXaxisHourCallback($val) {
- if($val == 0) {
+function statHourFormatX($val) {
+ if($val == 0)
return "12 am ";
- }
- elseif($val < 12) {
+ elseif($val < 12)
return "$val am ";
- }
- elseif($val == 12) {
+ elseif($val == 12)
return "$val pm ";
- }
- else {
- return $val - 12 . " pm ";
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \fn sendStatGraphDayConUsers()
-///
-/// \brief sends a graph image
-///
-////////////////////////////////////////////////////////////////////////////////
-function sendStatGraphDayConUsers() {
- global $xaxislabels, $inContinuation;
- if(! $inContinuation)
- return;
- $start = getContinuationVar("start");
- $end = getContinuationVar("end");
- $affilid = getContinuationVar("affilid");
- $graphdata = getStatGraphDayConUsersData($start, $end, $affilid);
- $count = count($graphdata["labels"]);
- if($count < 8)
- $labelinterval = 1;
else
- $labelinterval = $count / 7;
- $xaxislabels = $graphdata["labels"];
- $graph = new Graph(300, 300, "auto");
- $graph->SetScale("textlin");
- $plot = new BarPlot($graphdata["points"]);
- $graph->Add($plot);
- $graph->xaxis->SetLabelFormatCallback('statXaxisDayConUsersCallback');
- $graph->xaxis->SetLabelAngle(90);
- $graph->xaxis->SetTextLabelInterval($labelinterval);
- $graph->yaxis->SetTitle('Maximum concurrent reservations per day',
- 'high');
- $graph->SetMargin(40,40,20,80);
- $graph->Stroke();
+ return $val - 12 . " pm ";
}
////////////////////////////////////////////////////////////////////////////////
@@ -795,9 +722,13 @@ function sendStatGraphDayConUsers() {
/// \param $end - ending day in YYYY-MM-DD format
/// \param $affilid - affiliationid of data to gather
///
-/// \return an array whose keys are the days (in YYYY-MM-DD format) between
-/// $start and $end, inclusive, and whose values are the max concurrent users
-/// on each day
+/// \return an array with three keys:\n
+/// \b points - an array with y and tooltip keys that have the same value which
+/// is the y value at that point\n
+/// \b xlabels - an array with value and text keys, value's value is just an
+/// increasing integer starting from 1, text's value is the label
+/// to display on the x axis for the poing\n
+/// \b maxy - the max y value of the data
///
/// \brief queries the log table to get reservations between $start and $end
/// and creates an array with the max concurrent users per day
@@ -812,16 +743,17 @@ function getStatGraphDayConUsersData($st
$data = array();
$data["points"] = array();
- $data["labels"] = array();
+ $data["xlabels"] = array();
+ $data["maxy"] = 0;
$reloadid = getUserlistID('vclreload@Local');
+ $cnt = 0;
for($daystart = $startunix; $daystart < $endunix; $daystart += SECINDAY) {
- array_push($data["labels"], date('Y-m-d', $daystart));
+ $cnt++;
$count = array();
for($j = 0; $j < 24; $j++) {
$count[$j] = 0;
}
-
$startdt = unixToDatetime($daystart);
$enddt = unixToDatetime($daystart + SECINDAY);
if($affilid != 0) {
@@ -863,77 +795,30 @@ function getStatGraphDayConUsersData($st
}
}
rsort($count);
- array_push($data["points"], $count[0]);
+ $label = date('m/d/Y', $daystart);
+ $data["points"][] = array('y' => $count[0], 'tooltip' => "$label: {$count[0]}");
+ if($count[0] > $data['maxy'])
+ $data['maxy'] = $count[0];
+ $data['xlabels'][] = array('value' => $cnt, 'text' => $label);
}
return($data);
}
////////////////////////////////////////////////////////////////////////////////
///
-/// \fn statXaxisDayConUsersCallback($val)
-///
-/// \param $val - value passed in by SetLabelFormatCallback
-///
-/// \return day of week
-///
-/// \brief formats $val into day of week
-///
-////////////////////////////////////////////////////////////////////////////////
-function statXaxisDayConUsersCallback($val) {
- global $xaxislabels;
- if(array_key_exists((int)$val, $xaxislabels)) {
- return date('n/d/Y', datetimeToUnix($xaxislabels[$val] . " 00:00:00")) . " ";
- }
- else {
- return $val;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \fn sendStatGraphConBladeUser()
-///
-/// \brief sends a graph image of max concurrent users of blades per day
-///
-////////////////////////////////////////////////////////////////////////////////
-function sendStatGraphConBladeUser() {
- global $xaxislabels, $inContinuation;
- if(! $inContinuation)
- return;
- $start = getContinuationVar("start");
- $end = getContinuationVar("end");
- $affilid = getContinuationVar("affilid");
- $graphdata = getStatGraphConBladeUserData($start, $end, $affilid);
- $count = count($graphdata["labels"]);
- if($count < 8)
- $labelinterval = 1;
- else
- $labelinterval = $count / 7;
- $xaxislabels = $graphdata["labels"];
- $graph = new Graph(300, 300, "auto");
- $graph->SetScale("textlin");
- $plot = new BarPlot($graphdata["points"]);
- $graph->Add($plot);
- $graph->xaxis->SetLabelFormatCallback('statXaxisDayConUsersCallback');
- $graph->xaxis->SetLabelAngle(90);
- $graph->xaxis->SetTextLabelInterval($labelinterval);
- $graph->yaxis->SetTitle('Maximum concurrent reservations per day',
- 'high');
- $graph->SetMargin(40,40,20,80);
- $graph->Stroke();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-///
/// \fn getStatGraphConBladeUserData($start, $end, $affilid)
///
/// \param $start - starting day in YYYY-MM-DD format
/// \param $end - ending day in YYYY-MM-DD format
/// \param $affilid - affiliationid of data to gather
///
-/// \return an array whose keys are the days (in YYYY-MM-DD format) between
-/// $start and $end, inclusive, and whose values are the max concurrent users
-/// of blades on each day
+/// \return an array with three keys:\n
+/// \b points - an array with y and tooltip keys that have the same value which
+/// is the y value at that point\n
+/// \b xlabels - an array with value and text keys, value's value is just an
+/// increasing integer starting from 1, text's value is the label
+/// to display on the x axis for the poing\n
+/// \b maxy - the max y value of the data
///
/// \brief queries the log table to get reservations between $start and $end
/// and creates an array with the max concurrent users of blades per day
@@ -948,11 +833,13 @@ function getStatGraphConBladeUserData($s
$data = array();
$data["points"] = array();
- $data["labels"] = array();
+ $data["xlabels"] = array();
+ $data["maxy"] = 0;
$reloadid = getUserlistID('vclreload@Local');
+ $cnt = 0;
for($daystart = $startunix; $daystart < $endunix; $daystart += SECINDAY) {
- array_push($data["labels"], date('Y-m-d', $daystart));
+ $cnt++;
$count = array();
for($j = 0; $j < 24; $j++) {
$count[$j] = 0;
@@ -1010,29 +897,12 @@ function getStatGraphConBladeUserData($s
}
}
rsort($count);
- array_push($data["points"], $count[0]);
+ $label = date('m/d/Y', $daystart);
+ $data["points"][] = array('y' => $count[0], 'tooltip' => "$label: {$count[0]}");
+ if($count[0] > $data['maxy'])
+ $data['maxy'] = $count[0];
+ $data['xlabels'][] = array('value' => $cnt, 'text' => $label);
}
return($data);
}
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \fn statXaxisConBladeUserCallback($val)
-///
-/// \param $val - value passed in by SetLabelFormatCallback
-///
-/// \return day of week
-///
-/// \brief formats $val into day of week
-///
-////////////////////////////////////////////////////////////////////////////////
-function statXaxisConBladeUserCallback($val) {
- global $xaxislabels;
- if(array_key_exists((int)$val, $xaxislabels)) {
- return date('n/d/Y', datetimeToUnix($xaxislabels[$val] . " 00:00:00")) . " ";
- }
- else {
- return $val;
- }
-}
?>
Modified: incubator/vcl/trunk/web/.ht-inc/utils.php
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/utils.php?rev=1025626&r1=1025625&r2=1025626&view=diff
==============================================================================
--- incubator/vcl/trunk/web/.ht-inc/utils.php (original)
+++ incubator/vcl/trunk/web/.ht-inc/utils.php Wed Oct 20 16:17:19 2010
@@ -307,6 +307,9 @@ function initGlobals() {
case 'vm':
require_once(".ht-inc/vm.php");
break;
+ case 'dashboard':
+ require_once(".ht-inc/dashboard.php");
+ break;
default:
require_once(".ht-inc/requests.php");
}
@@ -8776,14 +8779,10 @@ function getNavMenu($inclogout, $inchome
$rt .= menulistLI('statistics');
$rt .= "<a href=\"" . BASEURL . SCRIPT . "?mode=selectstats\">";
$rt .= "Statistics</a></li>\n";
- if($skin != 'ecu') {
- $rt .= menulistLI('help');
- $rt .= "<a href=\"" . HELPURL . "\">Help</a></li>\n";
- }
- if($skin == 'ecu') {
- $rt .= "<li><a href=\"http://www.ecu.edu/cs-itcs/vcl/connect.cfm\">Requirements</a></li>\n";
- $rt .= "<li><a href=\"http://www.ecu.edu/cs-itcs/vcl/save.cfm\">File Saving</a></li>\n";
- $rt .= "<li><a href=\"http://www.ecu.edu/cs-itcs/vcl/faqs.cfm\">Help</a></li>\n";
+ if($viewmode == ADMIN_DEVELOPER) {
+ $rt .= menulistLI('dashboard');
+ $rt .= "<a href=\"" . BASEURL . SCRIPT . "?mode=dashboard\">";
+ $rt .= "Dashboard</a></li>\n";
}
if(in_array("userGrant", $user["privileges"]) ||
in_array("resourceGrant", $user["privileges"]) ||
@@ -8989,6 +8988,21 @@ function getDojoHTML($refresh) {
'dijit.Tooltip',
'dijit.Dialog');
break;
+ case 'viewstats':
+ $dojoRequires = array('dojo.parser',
+ 'dojox.charting.Chart2D',
+ 'dojox.charting.action2d.Tooltip',
+ 'dojox.charting.action2d.Magnify',
+ 'dojox.charting.themes.ThreeD');
+ break;
+ case 'dashboard':
+ $dojoRequires = array('dojo.parser',
+ 'dijit.Tooltip',
+ 'dojox.charting.widget.Chart2D',
+ 'dojox.charting.action2d.Tooltip',
+ 'dojox.charting.action2d.Magnify',
+ 'dojox.charting.themes.ThreeD');
+ break;
}
if(empty($dojoRequires))
return '';
@@ -9313,6 +9327,39 @@ function getDojoHTML($refresh) {
$rt .= " });\n";
$rt .= "</script>\n";
return $rt;
+ case "viewstats":
+ $rt .= "<style type=\"text/css\">\n";
+ $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n";
+ $rt .= "</style>\n";
+ $rt .= "<script type=\"text/javascript\" src=\"js/statistics.js\"></script>\n";
+ $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n";
+ $rt .= " djConfig=\"parseOnLoad: true\">\n";
+ $rt .= "</script>\n";
+ $rt .= "<script type=\"text/javascript\">\n";
+ $rt .= " dojo.addOnLoad(function() {\n";
+ foreach($dojoRequires as $req)
+ $rt .= " dojo.require(\"$req\");\n";
+ $rt .= " generateGraphs();\n";
+ $rt .= " });\n";
+ $rt .= "</script>\n";
+ return $rt;
+ case "dashboard":
+ $rt .= "<style type=\"text/css\">\n";
+ $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n";
+ $rt .= " @import \"css/dashboard.css\";\n";
+ $rt .= "</style>\n";
+ $rt .= "<script type=\"text/javascript\" src=\"js/dashboard.js\"></script>\n";
+ $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n";
+ $rt .= " djConfig=\"parseOnLoad: true, debug: true\">\n";
+ $rt .= "</script>\n";
+ $rt .= "<script type=\"text/javascript\">\n";
+ $rt .= " dojo.addOnLoad(function() {\n";
+ foreach($dojoRequires as $req)
+ $rt .= " dojo.require(\"$req\");\n";
+ $rt .= " updateDashboard();\n";
+ $rt .= " });\n";
+ $rt .= "</script>\n";
+ return $rt;
default:
$rt .= "<style type=\"text/css\">\n";
Added: incubator/vcl/trunk/web/css/dashboard.css
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/css/dashboard.css?rev=1025626&view=auto
==============================================================================
--- incubator/vcl/trunk/web/css/dashboard.css (added)
+++ incubator/vcl/trunk/web/css/dashboard.css Wed Oct 20 16:17:19 2010
@@ -0,0 +1,23 @@
+.dashwidget {
+ border: 1px solid;
+ text-align: center;
+ /*border-radius: 10px;
+ -moz-border-radius: 10px;*/
+ margin-bottom: 8px;
+}
+
+.dashwidget .extra {
+ margin-bottom: 5px;
+}
+
+.dashwidget table {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.dashwidget h3 {
+ background: #0053fb;
+ color: white;
+ margin-top: 0px;
+ margin-bottom: 2px;
+}
Modified: incubator/vcl/trunk/web/js/code.js
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/js/code.js?rev=1025626&r1=1025625&r2=1025626&view=diff
==============================================================================
--- incubator/vcl/trunk/web/js/code.js (original)
+++ incubator/vcl/trunk/web/js/code.js Wed Oct 20 16:17:19 2010
@@ -123,10 +123,10 @@ var genericCB = function(type, data, evt
eval(data);
}
-var errorHandler = function(type, error, data) {
- if(args.dojoType == 'cancel')
+var errorHandler = function(error, ioArgs) {
+ if(error.name == 'cancel')
return;
- alert('error occurred' + error.message + data.responseText);
+ alert('AJAX Error: ' + error.message + '\nLine ' + error.lineNumber + ' in ' + error.fileName);
}
function errorHandler(data, ioArgs) {
Added: incubator/vcl/trunk/web/js/dashboard.js
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/js/dashboard.js?rev=1025626&view=auto
==============================================================================
--- incubator/vcl/trunk/web/js/dashboard.js (added)
+++ incubator/vcl/trunk/web/js/dashboard.js Wed Oct 20 16:17:19 2010
@@ -0,0 +1,204 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+function RPCwrapper(data, CB, dojson) {
+ if(dojson) {
+ dojo.xhrPost({
+ url: 'index.php',
+ load: CB,
+ handleAs: "json",
+ error: errorHandler,
+ content: data,
+ timeout: 15000
+ });
+ }
+ else {
+ dojo.xhrPost({
+ url: 'index.php',
+ load: CB,
+ error: errorHandler,
+ content: data,
+ timeout: 15000
+ });
+ }
+}
+
+function generalReqCB(data, ioArgs) {
+ eval(data);
+ document.body.style.cursor = 'default';
+}
+
+function updateDashboard() {
+ var cont = dojo.byId('updatecont').value;
+ RPCwrapper({continuation: cont}, updateDashboardCB, 1);
+}
+
+function updateDashboardCB(data, ioArgs) {
+ dojo.byId('updatecont').value = data.items.cont;
+ updateStatus(data.items.status);
+ updateTopImages(data.items.topimages);
+ updateTopLongImages(data.items.toplongimages);
+ updateTopFailed(data.items.topfailed);
+ updateTopFailedComputers(data.items.topfailedcomputers);
+ updateResChart(data.items.reschart);
+ updateBlockAllocation(data.items.blockallocation);
+ setTimeout(updateDashboard, 15000);
+}
+
+function updateStatus(data) {
+ var obj = dojo.byId('status');
+ var txt = '<table>';
+ for(var i = 0; i < data.length; i++) {
+ txt += '<tr><th align="right">'
+ if(data[i].tooltip) {
+ txt += '<span id="status' + i + '">'
+ + data[i].key
+ + '</span>'
+ + '</th><td>'
+ + data[i].val
+ + '</td></tr>';
+ }
+ else {
+ txt += data[i].key
+ + '</th><td>'
+ + data[i].val
+ + '</td></tr>';
+ }
+ }
+ txt += '</table>';
+ obj.innerHTML = txt;
+ for(var i = 0; i < data.length; i++) {
+ if(data[i].tooltip) {
+ var tt = new dijit.Tooltip({
+ connectId: ['status' + i],
+ label: data[i].tooltip
+ });
+ }
+ }
+}
+
+function updateTopImages(data) {
+ var obj = dojo.byId('topimages');
+ if(data.length == 0) {
+ obj.innerHTML = 'No recent reservations';
+ return;
+ }
+ var txt = '<table>';
+ for(var i = 0; i < data.length; i++) {
+ txt += '<tr><th align="right">'
+ + data[i].prettyname
+ + '</th><td>'
+ + data[i].count
+ + '</td></tr>';
+ }
+ txt += '</table>';
+ obj.innerHTML = txt;
+}
+
+function updateTopLongImages(data) {
+ var obj = dojo.byId('toplongimages');
+ if(data.length == 0) {
+ obj.innerHTML = 'No recent reservations';
+ return;
+ }
+ var txt = '<table>';
+ for(var i = 0; i < data.length; i++) {
+ txt += '<tr><th align="right">'
+ + data[i].prettyname
+ + '</th><td>'
+ + data[i].count
+ + '</td></tr>';
+ }
+ txt += '</table>';
+ obj.innerHTML = txt;
+}
+
+function updateTopFailed(data) {
+ var obj = dojo.byId('topfailed');
+ if(data.length == 0) {
+ obj.innerHTML = 'No recent reservations';
+ return;
+ }
+ var txt = '<table>';
+ for(var i = 0; i < data.length; i++) {
+ txt += '<tr><th align="right">'
+ + data[i].prettyname
+ + '</th><td>'
+ + data[i].count
+ + '</td></tr>';
+ }
+ txt += '</table>';
+ obj.innerHTML = txt;
+}
+
+function updateTopFailedComputers(data) {
+ var obj = dojo.byId('topfailedcomputers');
+ if(data.length == 0) {
+ obj.innerHTML = 'No recent reservations';
+ return;
+ }
+ var txt = '<table>';
+ for(var i = 0; i < data.length; i++) {
+ txt += '<tr><th align="right">'
+ + data[i].hostname
+ + '</th><td>'
+ + data[i].count
+ + '</td></tr>';
+ }
+ txt += '</table>';
+ obj.innerHTML = txt;
+}
+
+function updateBlockAllocation(data) {
+ var obj = dojo.byId('blockallocation');
+ var txt = '<table>';
+ for(var i = 0; i < data.length; i++) {
+ txt += '<tr><th align="right">'
+ + data[i].title
+ + '</th><td>'
+ + data[i].val
+ + '</td></tr>';
+ }
+ txt += '</table>';
+ obj.innerHTML = txt;
+}
+
+function updateResChart(data) {
+ var graph = dijit.byId('reschart').chart;
+ graph.updateSeries('Main', data.points);
+ graph.labeldata = data.points;
+ graph.render();
+}
+
+function timestampToTime(val) {
+ if(! dijit.byId('reschart').chart.labeldata)
+ return '';
+ else
+ var data = dijit.byId('reschart').chart.labeldata;
+ return data[val]['text'];
+ var d = new Date();
+ d.setTime(val*1000);
+ var h = d.getHours();
+ if(h == 0)
+ return "12:" + d.getMinutes() + " am";
+ else if(h < 12)
+ return h + ":" + d.getMinutes() + " am";
+ else if(h == 12)
+ return "12:" + d.getMinutes() + " pm";
+ else
+ return (h - 12) + ":" + d.getMinutes() + "pm";
+}
Added: incubator/vcl/trunk/web/js/statistics.js
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/js/statistics.js?rev=1025626&view=auto
==============================================================================
--- incubator/vcl/trunk/web/js/statistics.js (added)
+++ incubator/vcl/trunk/web/js/statistics.js Wed Oct 20 16:17:19 2010
@@ -0,0 +1,144 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+function RPCwrapper(data, CB, dojson) {
+ if(dojson) {
+ dojo.xhrPost({
+ url: 'index.php',
+ load: CB,
+ handleAs: "json",
+ error: errorHandler,
+ content: data,
+ timeout: 300000
+ });
+ }
+ else {
+ dojo.xhrPost({
+ url: 'index.php',
+ load: CB,
+ error: errorHandler,
+ content: data,
+ timeout: 300000
+ });
+ }
+}
+
+function generalReqCB(data, ioArgs) {
+ eval(data);
+ document.body.style.cursor = 'default';
+}
+
+function generateGraphs() {
+ var cont = dojo.byId('statdaycont').value;
+ RPCwrapper({continuation: cont}, generateColGraphsCB, 1);
+ var cont = dojo.byId('statreshourcont').value;
+ RPCwrapper({continuation: cont}, generateHourGraphsCB, 1);
+ if(dojo.byId('statconcurrescont')) {
+ var cont = dojo.byId('statconcurrescont').value;
+ RPCwrapper({continuation: cont}, generateColGraphsCB, 1);
+ }
+ if(dojo.byId('statconcurbladecont')) {
+ var cont = dojo.byId('statconcurbladecont').value;
+ RPCwrapper({continuation: cont}, generateColGraphsCB, 1);
+ }
+}
+
+function generateColGraphsCB(data, ioArgs) {
+ dojo.byId(data.items.id).innerHTML = '';
+ var graph = new dojox.charting.Chart2D(data.items.id);
+ if(data.items.maxy <= 400)
+ var majortick = 50;
+ else if(data.items.maxy <= 600)
+ var majortick = 100;
+ else if(data.items.maxy <= 1000)
+ var majortick = 200;
+ else {
+ var majortick = data.items.maxy / 10;
+ majortick = (majortick - (majortick % 200)) || 200;
+ }
+ graph.setTheme(dojox.charting.themes.ThreeD);
+ if(data.items.points.length < 10)
+ var gap = 6;
+ else if(data.items.points.length < 20)
+ var gap = 3;
+ else if(data.items.points.length < 50)
+ var gap = 2;
+ else
+ var gap = 0;
+ var xtickstep = parseInt(data.items.xlabels.length / 10) || 1;
+ graph.addAxis("x", {
+ includeZero: false,
+ labels: data.items.xlabels,
+ rotation: -90,
+ minorTicks: false,
+ font: 'normal normal normal 11px verdana',
+ majorTickStep: xtickstep
+ });
+ graph.addAxis('y', {
+ vertical: true,
+ fixUpper: "major",
+ includeZero: true,
+ minorTicks: true,
+ minorLabels: false,
+ majorTickStep: majortick,
+ minorTickStep: majortick / 2,
+ });
+ graph.addPlot('default', {type: "Columns", gap: gap});
+ graph.addPlot('Grid', {type: 'Grid', hMajorLines: true, vMajorLines: false});
+ graph.addSeries("Main", data.items.points, {stroke: {width: 1}});
+ var a = new dojox.charting.action2d.Tooltip(graph);
+ graph.render();
+}
+
+function generateHourGraphsCB(data, ioArgs) {
+ dojo.byId(data.items.id).innerHTML = '';
+ var graph = new dojox.charting.Chart2D(data.items.id);
+ if(data.items.maxy <= 50)
+ var majortick = 5;
+ else if(data.items.maxy <= 100)
+ var majortick = 10;
+ else if(data.items.maxy <= 200)
+ var majortick = 20;
+ else {
+ var majortick = data.items.maxy / 10;
+ majortick = (majortick - (majortick % 100)) || 100;
+ }
+ graph.setTheme(dojox.charting.themes.ThreeD);
+ graph.addAxis("x", {
+ includeZero: true,
+ labels: data.items.points,
+ rotation: -90,
+ minorTicks: false,
+ font: 'normal normal normal 11px verdana',
+ majorTickStep: 2
+ });
+ graph.addAxis('y', {
+ vertical: true,
+ fixUpper: "major",
+ includeZero: true,
+ minorTicks: true,
+ minorLabels: false,
+ majorTickStep: majortick,
+ minorTickStep: majortick / 5,
+ });
+ graph.addPlot('default', {markers: true});
+ graph.addPlot('Grid', {type: 'Grid', hMajorLines: true, vMajorLines: false});
+ graph.addSeries("Main", data.items.points);
+ var a = new dojox.charting.action2d.Tooltip(graph);
+ var a = new dojox.charting.action2d.Magnify(graph);
+ graph.render();
+}