Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/App_Code/AdminHelper.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/App_Code/AdminHelper.cshtml	(revision 11222)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/App_Code/AdminHelper.cshtml	(revision 11246)
@@ -50,7 +50,24 @@
             url: "@(new HtmlString(url))?start=" + @start + "&end=" + @end + "&userName=" + @userName, datatype: "json", success: function (userResult) {
               $("#" + "@destinationTag").html("");
+              var appendUnits;
               for (var i = 0; i < userResult.length; i++) {
+                if(userResult[i].Key == "Total Waiting Time" || userResult[i].Key == "Total Transfer Time" || userResult[i].Key == "Total Runtime") {
+                  appendUnits = " seconds";
+                }
+                else if (userResult[i].Key == "Memory Required") {
+                  appendUnits = " KB";
+                }
+                else {
+                  appendUnits = "";
+                }
                 $("#" + "@destinationTag").append('<label class="barLabel">' + userResult[i].Key + '</label>');
-                $("#" + "@destinationTag").append('<div class="outerBar"><div class="innerBar" id="InnerBar' + i + '"><label class="innerBarText">' + +userResult[i].Value.toFixed(4) + '</label></div></div><label class="outerBarText" id="OuterText' + i + '">' + +overallResult[i].Value.toFixed(4) + '</label>');
+                $("#" + "@destinationTag").append(
+                  '<div class="outerBar">' +
+                    '<div class="innerBar" id="InnerBar' + i + '">' +
+                      '<label class="innerBarText">' + +userResult[i].Value.toFixed(2) + appendUnits + '</label>' +
+                    '</div>' +
+                  '</div>' +
+                  '<label class="outerBarText" id="OuterText' + i + '">' + +overallResult[i].Value.toFixed(2) + appendUnits + '</label>'
+                );
                 $("#InnerBar" + i).css('width',((userResult[i].Value/overallResult[i].Value)*100).toFixed(2) + '%');
               }
@@ -71,11 +88,18 @@
         $.ajax({
           url: "@(new HtmlString(url))?taskId=" + taskId, datatype: "json", success: function (result) {
+            var appendUnits;
             var appendString = '<table class="moreInfoTable"><tr>';
             for (var i = 0; i < result.length; i++) {
+              if (result[i].Key == "Memory Required") {
+                appendUnits = " KB";
+              }
+              else {
+                appendUnits = "";
+              }
               if(i % 2 == 0 && i != 0) {
                 appendString += '</tr><tr>';
               }
               appendString += '<td class="taskInfoCell"><label class="taskInfoKey">' + result[i].Key + '</label>';
-              appendString += '<label class="taskInfoValue">' + +result[i].Value.toFixed(4) + '</label></td>';
+              appendString += '<label class="taskInfoValue">' + +result[i].Value.toFixed(2) + appendUnits + '</label></td>';
             }
             appendString += '</tr></table>'
@@ -93,12 +117,24 @@
 }
 
-@helper MoreSlaveInfo(string url)
+@helper MoreSlaveInfo(string url, string startDate, string endDate)
 {
   <text>
     function MoreSlaveInfo(caller) {
+      CheckFilters();
       if($(caller).siblings('.moreInfoTable').length == 0) {
         var slaveId = $(caller).attr('id');
+        var GetRequest = "?slaveId=" + slaveId;
+        @if (startDate != null) {
+          @:if(@(startDate)!=null) {
+            @:GetRequest += "&start=" + @startDate;
+          @:}
+        }
+        @if (endDate != null) {
+          @:if(@(endDate)!=null) {
+            @:GetRequest += "&end=" + @endDate;
+          @:}
+        }
         $.ajax({
-          url: "@(new HtmlString(url))?slaveId=" + slaveId, datatype: "json", success: function (result) {
+          url: "@(new HtmlString(url))" + GetRequest, datatype: "json", success: function (result) {
             var appendString = '<table class="moreInfoTable"><tr>';
             for (var i = 0; i < result[0].length; i++) {
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/App_Code/ChartHelper.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/App_Code/ChartHelper.cshtml	(revision 11222)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/App_Code/ChartHelper.cshtml	(revision 11246)
@@ -36,5 +36,6 @@
 }
 
-@helper LineChartTime(string destinationTag, string url, string title = "", double? minY = null, double? maxY = null, string axisYFormat = null) {
+@helper LineChartTime(string destinationTag, string url, string title = "", double? minY = null, double? maxY = null, string axisYFormat = null)
+{
   <script>
     var @(destinationTag)Plot = $.jqplot("@destinationTag", "@url", {
@@ -89,5 +90,6 @@
 }
 
-@helper RefreshChart(string destinationTag, string url, string startDate, string endDate, double? minY=null, double? maxY=null) {
+@helper RefreshChart(string destinationTag, string url, string startDate, string endDate, double? minY = null, double? maxY = null)
+{
   <text>
   $.ajax({url: "@(new HtmlString(url))?start=" + @startDate + "&end=" + @endDate, datatype: "json", success: function(result) {
@@ -97,9 +99,11 @@
     //Resets only the xaxis, still need to resize y with given min/max
     @(destinationTag)Plot.replot({resetAxes:true});
-    @if(minY != null) {
+    @if (minY != null)
+    {
       //If min Y was provided set the plot's min Y value
       @:@(destinationTag)Plot.axes.yaxis.min = @minY;
     }
-    @if(maxY != null) {
+    @if (maxY != null)
+    {
       //If max Y was provided set the plot's max Y value
       @:@(destinationTag)Plot.axes.yaxis.max = @maxY;
@@ -162,9 +166,11 @@
   <text>
     if(@(records).length > @limit) {
-      $("#@container").append('<label class="pageTitle">Page: </label>')
+      var appendPages = '<section class="pageContainer"><label class="pageTitle">Page: </label>';
       var pages = Math.floor(@(records).length/@(limit)) + 1;
       for(var i=0; i < pages; i++) {
-        $("#" + "@container").append('<a id="@(container)Page' + (i + 1) + '" class="page">' + (i + 1) + '</a>')
-      }
+        appendPages += '<a id="@(container)Page' + (i + 1) + '" class="page">' + (i + 1) + '</a>';
+      }
+      appendPages += '</section>';
+      $("#@container").append(appendPages);
       if(@currentPage != null) {
         $("#@(container)Page" + @currentPage).css('color','#F7921D');
@@ -190,5 +196,5 @@
 }
 
-@helper TasksForUser(string destinationTag, string url, string functionName, string userName, string limit, string startDate = null, string endDate = null, string jobId = null, string taskState = null, string pageNumber = null)
+@helper TaskContainers(string destinationTag, string url, string functionName, string userName, string limit, string startDate = null, string endDate = null, string jobId = null, string taskState = null, string pageNumber = null)
 {
   <text>
@@ -235,16 +241,8 @@
       }
       else {
-        var waitTime;
-        var transferTime;
-        var runTime;
-        var seriesDescriptions = ["Time waiting","Time transferring","Time calculating"];
-
         //Checks if multipage display, if it is then trims results to
         //the results for the page to be displayed
         @ChartHelper.NumberPages("result", limit, destinationTag, functionName, pageNumber)
 
-        //Globally accesible, for use when resizing, eliminates extra DB request
-        window["numberTasks"] = result.length;
-
         //Set display of all errors to none, errors matching the tasks will be reset below
         $("#@(destinationTag)").find(".errorContainer, .errorTitle, .errorTask, .errorMessage").css('display','none');
@@ -252,10 +250,20 @@
         //Set variable for tracking jobId and open first job grouping
         var currentJob = result[0].JobId;
-        $("#@(destinationTag)").append('<section class="jobTaskGroup" id="' + result[0].JobId + '"><h1>' + result[0].JobName + '</h1></section>');
 
         //For each result create a seperate collapsable section with a chart and info label
         for(var i = 0; i < result.length; i++){
-          if(currentJob != result[i].JobId) {
-            $("#@(destinationTag)").append('<section class="jobTaskGroup" id="' + result[i].JobId + '"><h1>' + result[i].JobName + '</h1></section>');
+          if(currentJob != result[i].JobId || i == 0) {
+            $("#@(destinationTag)").append(
+              '<section class="jobTaskGroup" id="' + result[i].JobId + '">' +
+                '<h1>' + result[i].JobName + '</h1>' +
+                '<section class="chartContainer">' + 
+                  '<h1 class="title" id="@(destinationTag)' + result[i].JobId + 'PlotTitle">Job Overview - ' + result[i].JobName + '</h1>' + 
+                  '<button class="collapse" onclick="LoadJob(this)">+</button>' + 
+                  '<div id="@(destinationTag)JobOverviewPlot' + i + '"></div>' +
+                  '<label id="@(destinationTag)JobOverviewPlotInfo' + i + '"></label>' + 
+                '</section>' +
+              '</section>'
+            );
+            CollapsedByDefault(document.getElementById("@(destinationTag)JobOverviewPlot" + i));
             currentJob = result[i].JobId;
           }
@@ -263,10 +271,10 @@
             '<section class="chartContainer">' + 
               '<h1 class="title" id="@(destinationTag)' + result[i].TaskId + 'PlotTitle">Task ' + result[i].TaskId + '</h1>' + 
-              '<button class="collapse" onclick="CollapseSection(this)">+</button>' + 
+              '<button class="collapse" onclick="LoadTask(this)">+</button>' + 
               '<div id="@(destinationTag)Plot' + i + '"></div>' + 
               '<label id="@(destinationTag)PlotInfo' + i + '"></label>' + 
               '<a id="' + result[i].TaskId + '" class="moreInfo" onclick="MoreTaskInfo(this)">More Info</a>' +
             '</section>'
-          )
+          );
           //Re-enables the error display if any of the tasks on the page have Ids matching
           //those of errors
@@ -280,17 +288,37 @@
             }
           });
-          waitTime = [result[i].TotalWaiting];
-          transferTime = [result[i].TotalTransfer];
-          runTime = [result[i].TotalRuntime];
-          window["@(destinationTag)Plot" + i] = $.jqplot("@(destinationTag)Plot" + i, [waitTime,transferTime,runTime], {
+          CollapsedByDefault(document.getElementById("@(destinationTag)Plot" + i));
+        }
+      }
+    }});
+  </text>
+}
+
+@helper LoadJob(string url)
+{
+  <text>
+    function LoadJob(caller) {
+      CheckFilters();
+      if($(caller).next().html()=="") {
+        var plotName = $(caller).next().attr('id');
+        //Set current job id
+        var jobId = $(caller).parent().parent().attr('id');
+        var GetRequest = "?jobId=" + jobId;
+
+        $.ajax({ async: false, url: "@(new HtmlString(url))" + GetRequest, datatype: "json", success: function(result) {
+          CollapseSection(caller);
+          var seriesDescription = ['Waiting','Transferring','Calculating','Finished','Error'];
+          window[plotName] = $.jqplot(plotName, [[result.Wait],[result.Transfer],[result.Calculate],[result.Finish],[result.Error]], {
             seriesDefaults:{
               renderer:$.jqplot.BarRenderer,
               shadowAngle: 135,
-              pointLabels: {show: true, formatString: '%.3f'}
+              pointLabels: {show: true, formatString: '%.0f'}
             },
             series:[
-              {label:'Waiting'},
-              {label:'Transferring'},
-              {label:'Calculating'}
+              {label:seriesDescription[0]},
+              {label:seriesDescription[1]},
+              {label:seriesDescription[2]},
+              {label:seriesDescription[3]},
+              {label:seriesDescription[4]}
             ],
             legend: {
@@ -306,5 +334,5 @@
               },
               yaxis: {
-                pad: 0
+                padMax: 1.5
               }
             },
@@ -315,12 +343,79 @@
           /* Bind a datalistener to each chart and display details of clicked
             upon data in the label below the chart */
-          $("#" + "@(destinationTag)Plot" + i).bind('jqplotDataClick', function (ev, seriesIndex, pointIndex, data) {
-            $(this).next("label").html(seriesDescriptions[seriesIndex] + ": " + data[1]);
+          $("#" + plotName).bind('jqplotDataClick', function (ev, seriesIndex, pointIndex, data) {
+            $(this).next("label").html("Tasks " + seriesDescription[seriesIndex] + ": " + data[1]);
           });
-
-          CollapsedByDefault(document.getElementById("@(destinationTag)Plot" + i));
-        }
-      }
-    }});
+        }});
+      }
+      else {
+        CollapseSection(caller);
+      }
+    }
+  </text>
+}
+
+@helper LoadTask(string url)
+{
+  <text>
+    function LoadTask(caller) {
+      CheckFilters();
+      if($(caller).next().html()=="") {
+        var plotName = $(caller).next().attr('id');
+        //Set current slave id
+        var currentTask = $(caller).siblings('a.moreInfo').attr('id');
+        var GetRequest = "?taskId=" + currentTask;
+
+        $.ajax({ async: false, url: "@(new HtmlString(url))" + GetRequest, datatype: "json", success: function(result) {
+          var waitTime;
+          var transferTime;
+          var runTime;
+          var seriesDescriptions = ["Time waiting","Time transferring","Time calculating"];
+          CollapseSection(caller);
+          for(i = 0; i < result.length; i++) {
+            waitTime = [result[i].TotalWaiting];
+            transferTime = [result[i].TotalTransfer];
+            runTime = [result[i].TotalRuntime];
+            window[plotName] = $.jqplot(plotName, [waitTime,transferTime,runTime], {
+              seriesDefaults:{
+                renderer:$.jqplot.BarRenderer,
+                shadowAngle: 135,
+                pointLabels: {show: true, formatString: '%.3f'}
+              },
+              series:[
+                {label:'Waiting'},
+                {label:'Transferring'},
+                {label:'Calculating'}
+              ],
+              legend: {
+                show: true,
+                location: 'e',
+                placement: 'outside'
+              },
+              axes: {
+                xaxis: {
+                  renderer: $.jqplot.CategoryAxisRenderer,
+                  showLabel: false,
+                  pad: 0
+                },
+                yaxis: {
+                  pad: 0
+                }
+              },
+              cursor: {
+                showTooltip: false
+              }
+            });
+            /* Bind a datalistener to each chart and display details of clicked
+              upon data in the label below the chart */
+            $("#" + plotName).bind('jqplotDataClick', function (ev, seriesIndex, pointIndex, data) {
+              $(this).next("label").html(seriesDescriptions[seriesIndex] + ": " + data[1].toFixed(4) + " seconds");
+            });
+          }
+        }});
+      }
+      else {
+        CollapseSection(caller);
+      }
+    }
   </text>
 }
@@ -467,5 +562,5 @@
 }
 
-@helper SlaveInfoChart(string destinationTag, string url, string limit, bool singleSlave, string startDate = null, string endDate = null, string userName = null, string functionName = null, string pageNumber = null, string slaveId = null)
+@helper SlaveContainers(string destinationTag, string url, string limit, bool singleSlave, string startDate = null, string endDate = null, string userName = null, string functionName = null, string pageNumber = null, string slaveId = null)
 {
   <text>
@@ -515,18 +610,25 @@
     @:}
   }
-  $.ajax({
-    async: false, url: "@(new HtmlString(url))" + GetRequest, datatype: "json", success: function(result) {
-
-    //Set chart names for use in creation below, must be set identically in
-    //ResizeSlaves
+  $.ajax({ async: false, url: "@(new HtmlString(url))" + GetRequest, datatype: "json", success: function(result) {
+    //Set chart names for use in creation below, must be set identically in LoadSlave and ResizeSlaves
     var slaveChartNames = ["TotalUsedCores","TotalUsedMemory","CPUUtilization"];
 
-    var destTag = eval("@(destinationTag)");
-    if(typeof eval("@(destinationTag)") != "string") {
-      destTag = "@(destinationTag)";
+    @if (!singleSlave) {
+      @:$('#@(destinationTag)').html("");
+
+      //Checks if multipage display, if it is then trims results to
+      //the results for the page to be displayed
+      @ChartHelper.NumberPages("result", limit, destinationTag, functionName, pageNumber)
+
+      
+      @:var destTag = "@(destinationTag)";
+    }
+    else {
+      @:var destTag = @(destinationTag);
     }
 
     if(result.length == 0) {
-      @if (!singleSlave) {
+      @if (!singleSlave)
+      {
         @:$('#' + destTag).html("");
       }
@@ -537,17 +639,55 @@
       )
     }
-    else {
-      var time = new Date();
-
-      @if (!singleSlave)
+
+    for(i = 0; i < result.length; i++) {
+      $('#' + destTag).append(
+        '<section class="chartContainer">' + 
+          '<h1 class="title" id="' + destTag + result[i][0].SlaveID + 'PlotTitle">Slave ' + result[i][0].ClientName + '</h1>' + 
+          '<button class="collapse" onclick="LoadSlave(this)">+</button>' + 
+          '<div id="' + destTag + slaveChartNames[0] + 'Plot' + result[i][0].SlaveID + '"></div>' + 
+          '<div id="' + destTag + slaveChartNames[1] + 'Plot' + result[i][0].SlaveID + '"></div>' + 
+          '<div id="' + destTag + slaveChartNames[2] + 'Plot' + result[i][0].SlaveID + '"></div>' + 
+          '<a id="' + result[i][0].SlaveID + '" class="moreInfo" onclick="MoreSlaveInfo(this)">More Info</a>' +
+        '</section>');
+      for(k = 0; k < slaveChartNames.length; k++) {
+        CollapsedByDefault(document.getElementById(destTag + slaveChartNames[k] + "Plot" + result[i][0].SlaveID));
+      }
+    }
+  }});
+  </text>
+}
+
+@helper LoadSlave(string url, string limit, string startDate = null, string endDate = null, string userName = null, string pageNumber = null) {
+  <text>
+  function LoadSlave(caller) {
+    CheckFilters();
+    if($(caller).next().html()=="") {
+      var destTag = $(caller).parent().parent().attr('id');
+      //Set current slave id
+      var currentSlave = $(caller).siblings('a.moreInfo').attr('id');
+      var GetRequest = "?slaveId=" + currentSlave;
+      @if (startDate != null)
       {
-        @:$('#' + destTag).html("");
-
-        //Checks if multipage display, if it is then trims results to
-        //the results for the page to be displayed
-        @ChartHelper.NumberPages("result", limit, destinationTag, functionName, pageNumber)
-      }
-
-      for(i = 0; i < result.length; i++) {
+        @:if(@(startDate)!=null) {
+          @:GetRequest += "&start=" + @startDate;
+        @:}
+      }
+      @if (endDate != null)
+      {
+        @:if(@(endDate)!=null) {
+          @:GetRequest += "&end=" + @endDate;
+        @:}
+      }
+      @if (userName != null)
+      {
+        @:if(@(userName)!=null) {
+          @:GetRequest += "&userName=" + @userName;
+        @:}
+      }
+      $.ajax({ async: false, url: "@(new HtmlString(url))" + GetRequest, datatype: "json", success: function(result) {
+        //Set chart names for use in creation below, must be set identically in SlaveContainers and ResizeSlaves
+        var slaveChartNames = ["TotalUsedCores","TotalUsedMemory","CPUUtilization"];
+        CollapseSection(caller);
+        var time = new Date();
         var coreSeries = [];
         coreSeries[0] = [];
@@ -558,37 +698,28 @@
         var cpuSeries = [];
         cpuSeries[0] = [];
-        $('#' + destTag).append(
-          '<section class="chartContainer">' + 
-            '<h1 class="title" id="' + destTag + result[i][0].SlaveID + 'PlotTitle">Slave ' + result[i][0].ClientName + '</h1>' + 
-            '<button class="collapse" onclick="CollapseSection(this)">+</button>' + 
-            '<div id="' + destTag + slaveChartNames[0] + 'Plot' + i + '"></div>' + 
-            '<div id="' + destTag + slaveChartNames[1] + 'Plot' + i + '"></div>' + 
-            '<div id="' + destTag + slaveChartNames[2] + 'Plot' + i + '"></div>' + 
-            '<a id="' + result[i][0].SlaveID + '" class="moreInfo" onclick="MoreSlaveInfo(this)">More Info</a>' +
-          '</section>');
-        for(j = 0; j < result[i].length; j++) {
-          time.setTime(result[i][j].Time.replace(/\D/g,''));
-          coreSeries[0].push([time.toUTCString(),result[i][j].TotalCores]);
-          coreSeries[1].push([time.toUTCString(),result[i][j].UsedCores]);
-          memorySeries[0].push([time.toUTCString(),(result[i][j].TotalMemory / 1000)]);
-          memorySeries[1].push([time.toUTCString(),(result[i][j].UsedMemory / 1000)]);
-          cpuSeries[0].push([time.toUTCString(),result[i][j].CPUUtilization]);
-        }
-        if(result[i].length > 1) {
-          @ChartHelper.LineChartGivenSeries("destTag + slaveChartNames[0]", "i", "coreSeries", "Total/Used Cores")
-          @ChartHelper.LineChartGivenSeries("destTag + slaveChartNames[1]", "i", "memorySeries", "Total/Used Memory", 0)
-          @ChartHelper.LineChartGivenSeries("destTag + slaveChartNames[2]", "i", "cpuSeries", "CPU Utilization", 0, 100, "%.1f%%")
+        for(i = 0; i < result.length; i++) {
+          time.setTime(result[i].Time.replace(/\D/g,''));
+          coreSeries[0].push([time.toUTCString(),result[i].TotalCores]);
+          coreSeries[1].push([time.toUTCString(),result[i].UsedCores]);
+          memorySeries[0].push([time.toUTCString(),(result[i].TotalMemory / 1000)]);
+          memorySeries[1].push([time.toUTCString(),(result[i].UsedMemory / 1000)]);
+          cpuSeries[0].push([time.toUTCString(),result[i].CPUUtilization]);
+        }
+        if(result.length > 1) {
+          @ChartHelper.LineChartGivenSeries("destTag + slaveChartNames[0]", "currentSlave", "coreSeries", "Total/Used Cores")
+          @ChartHelper.LineChartGivenSeries("destTag + slaveChartNames[1]", "currentSlave", "memorySeries", "Total/Used Memory", 0)
+          @ChartHelper.LineChartGivenSeries("destTag + slaveChartNames[2]", "currentSlave", "cpuSeries", "CPU Utilization", 0, 100, "%.1f%%")
         }
         else {
-          @ChartHelper.BarChartGivenSeries("destTag + slaveChartNames[0]", "i", "coreSeries", "Total/Used Cores")
-          @ChartHelper.BarChartGivenSeries("destTag + slaveChartNames[1]", "i", "memorySeries", "Total/Used Memory", 0)
-          @ChartHelper.BarChartGivenSeries("destTag + slaveChartNames[2]", "i", "cpuSeries", "CPU Utilization", 0, 100, "%.1f%%")
-        }
-        for(k = 0; k < slaveChartNames.length; k++) {
-          CollapsedByDefault(document.getElementById(destTag + slaveChartNames[k] + "Plot" + i));
-        }
-      }
-    }
-  }});
+          @ChartHelper.BarChartGivenSeries("destTag + slaveChartNames[0]", "currentSlave", "coreSeries", "Total/Used Cores")
+          @ChartHelper.BarChartGivenSeries("destTag + slaveChartNames[1]", "currentSlave", "memorySeries", "Total/Used Memory", 0)
+          @ChartHelper.BarChartGivenSeries("destTag + slaveChartNames[2]", "currentSlave", "cpuSeries", "CPU Utilization", 0, 100, "%.1f%%")
+        }
+      }});
+    }
+    else {
+      CollapseSection(caller);
+    }
+  }
   </text>
 }
@@ -686,2 +817,60 @@
   </text>
 }
+
+@helper UserTasks(string url, string insertAfter, string taskState) {
+  <text>
+    var GetRequest = "?taskState=@(taskState)";
+
+    $.ajax({ async: false, url: "@(new HtmlString(url))" + GetRequest, datatype: "json", success: function(result) {
+      if(result.length==0) {
+        $("@(insertAfter)").after(
+          '<section class="chartContainer">' + 
+            '<h1 class="title">No users currently have any tasks ' + @(taskState) + '!</h1>' + 
+          '</section>'
+        )
+      }
+      else {
+        $("@(insertAfter)").after(
+          '<section class="chartContainer">' + 
+            '<h1 class="title" id="UserTask@(taskState)PlotTitle">@(taskState) Tasks</h1>' + 
+            '<button class="collapse" onclick="CollapseSection(this)">-</button>' + 
+            '<div id="UserTask@(taskState)Plot" class="noXTicks"></div>' +
+          '</section>'
+        );
+      }
+      var userTasks = [];
+      var userNames = [];
+      for (i=0; i < result.length; i++) {
+        userTasks[i] = [result[i].Value];
+        userNames[i] = { label: result[i].Key };
+      }
+      window["UserTask@(taskState)Plot"] = $.jqplot("UserTask@(taskState)Plot", userTasks, {
+        title: "Users with @(taskState) Tasks",
+        seriesDefaults:{
+          renderer:$.jqplot.BarRenderer,
+          shadowAngle: 135,
+          pointLabels: {show: true, formatString: '%.3f'}
+        },
+        series: userNames,
+        legend: {
+          show: true,
+          location: 'e',
+          placement: 'outside'
+        },
+        axes: {
+          xaxis: {
+            renderer: $.jqplot.CategoryAxisRenderer,
+            showTicks: false,
+            pad: 0
+          },
+          yaxis: {
+            padMax: 1.5
+          }
+        },
+        cursor: {
+          showTooltip: false
+        }
+      });
+    }});
+  </text>
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/App_Code/ExceptionHelper.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/App_Code/ExceptionHelper.cshtml	(revision 11222)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/App_Code/ExceptionHelper.cshtml	(revision 11246)
@@ -18,5 +18,5 @@
  *@
 
-@helper UserExceptions(string destinationTag, string url, string limit, string userName = null, string startDate = null, string endDate = null, string jobId = null, string taskState = null, string slaveId=null)
+@helper UserExceptions(string destinationTag, string url, string userName = null, string startDate = null, string endDate = null, string jobId = null, string taskState = null, string slaveId=null)
 {
   <text>
@@ -88,5 +88,10 @@
   }
 
-  $.ajax({async: false, url: "@(new HtmlString(url))" + GetRequest, datatype: "json", success: function(result) {
+  $.ajax({async: false, url: "@(new HtmlString(url))" + GetRequest, datatype: "json",
+    error: function(xhr,err) {
+      alert("readyState: "+xhr.readyState+"\nstatus: "+xhr.status);
+      alert("responseText: "+xhr.responseText);
+    },
+    success: function(result) {
       $("#" + "@destinationTag").html("");
       if(result.Key.length > 0) {
@@ -96,6 +101,12 @@
                           '<label class="errorMessage underline">Error</label>';
         for (var i = 0; i < result.Key.length; i++) {
-          ErrorHTML += '<a class="errorTask" onclick="ScrollTo(this)">' + result.Key[i] + '</a>' + 
-                        '<label class="errorMessage">' + result.Value[i] + '</label>';
+          ErrorHTML += '<a class="errorTask" onclick="ScrollTo(this)">' + result.Key[i] + '</a>';
+          if(result.Value[i].length > 100) {
+            ErrorHTML += '<a class="errorMessage shortVerison" onclick="ShowFullError(this)">Click to show full message</a>';
+            ErrorHTML += '<label class="errorMessage longVersion">' + result.Value[i] + '</label>';
+          }
+          else {
+            ErrorHTML += '<label class="errorMessage">' + result.Value[i] + '</label>';
+          }
         }
         ErrorHTML += '</section>';
@@ -118,5 +129,5 @@
     function ScrollTo(caller) {
       var taskErrorId = $(caller).parent().parent().attr('id') + $(caller).html() + "PlotTitle";
-      OpenOnError(document.getElementById(taskErrorId));
+      $("#" + taskErrorId).parent().find("button").click();
       $('html, body').animate({
           scrollTop: $("#" + taskErrorId).parent().offset().top
@@ -238,6 +249,8 @@
   function ShowSlaveInfo(caller) {
     var taskSlaveId = $(caller).attr('id');
+    CheckFilters();
     if($(caller).parent().parent().children(".chartContainer").length == 0) {
-      @ChartHelper.SlaveInfoChart("caller.parentNode.parentNode.id",url,limit,true,startDate,endDate,null,null,null,"taskSlaveId")
+      var destinationTag = $(caller).parent().parent().attr('id');
+      @ChartHelper.SlaveContainers("destinationTag",url,limit,true,startDate,endDate,null,null,null,"taskSlaveId")
     }
     else {
@@ -247,2 +260,11 @@
   </text>
 }
+
+@helper ShowFullError() {
+  <text>
+  function ShowFullError(caller) {
+    $(caller).css('display','none');
+    $(caller).next().css('display','inline-block');
+  }
+  </text>
+}
