Changeset 11020


Ignore:
Timestamp:
06/16/14 10:37:22 (5 years ago)
Author:
mroscoe
Message:

First check-in for Matt Roscoe. Major revision, multiple new files created and multiple files changed.

Location:
branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3
Files:
12 added
7 edited

Legend:

Unmodified
Added
Removed
  • branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/App_Code/ChartHelper.cshtml

    r9662 r11020  
    1818 *@
    1919
    20 @helper AjaxDataRenderer() {
     20@helper AjaxDataRenderer()
     21{
    2122    <script>
    2223        var ajaxDataRenderer = function (url, plot, options) {
     
    3536}
    3637
    37 @helper LineChartTime(string destinationTag, string url, string title = "", double? minY = null, double? maxY = null, string axisYFormat = null) {
     38@helper LineChartTime(string destinationTag, string url, string title = "", double? minY = null, double? maxY = null, string axisYFormat = null)
     39{
    3840    <script>
    3941        var @(destinationTag)Plot = $.jqplot("@destinationTag", "@url", {
     
    5355                },
    5456                yaxis: {
    55                     @if (axisYFormat != null) {<text>
     57                    @if (axisYFormat != null)
     58                    {<text>
    5659                    tickOptions: {
    5760                        formatString: "@axisYFormat",
     
    6063                    autoscale: true,
    6164                    pad: 0,
    62                     @if (minY != null) {
     65                    @if (minY != null)
     66                    {
    6367                        @:min: @minY,
    6468                    }
    65                     @if (maxY != null) {
     69                    @if (maxY != null)
     70                    {
    6671                        @:max: @maxY,
    6772                    }
     
    9398}
    9499
    95 @helper RefreshChart(string destinationTag, string url, string startDateVar, string endDateVar) {
    96     <text>
    97     $.ajax({url: "@(new HtmlString(url))?start=" + @startDateVar + "&end=" + @endDateVar, datatype: "json", success: function(result) {
    98         for (var i = 0; i < result.length; i++) {
    99             @(destinationTag)Plot.series[i].data = result[i];
     100@helper RefreshChart(string destinationTag, string url, string startDateVar, string endDateVar)
     101{
     102  <text>
     103  $.ajax({url: "@(new HtmlString(url))?start=" + @startDateVar + "&end=" + @endDateVar, datatype: "json", success: function(result) {
     104    for (var i = 0; i < result.length; i++) {
     105      @(destinationTag)Plot.series[i].data = result[i];
     106    }
     107    @(destinationTag)Plot.replot({ resetAxes: true })
     108  }});
     109  </text>
     110}
     111
     112@helper TasksForUser(string container, string destinationTag, string url, string userName, string startDate = null, string endDate = null)
     113{
     114  <text>
     115    $.ajax({url: "@(new HtmlString(url))?userName=" + @(userName) + "&start=" + @startDate + "&end=" + @endDate, datatype: "json", success: function(result) {
     116      $("#@container").html("");
     117      if(result[0].length==0) {
     118        $("#@container").append(
     119          '<section class="chartContainer"><h1 class="title">' + @userName + ' has no tasks for the given time period!</h1></section>'
     120        )
     121      }
     122      var waitTime;
     123      var transferTime;
     124      var runTime;
     125      var seriesDescriptions = ["Time waiting","Time transferring","Time calculating"];
     126
     127      //Globally accesible, for use when resizing, eliminates extra DB request
     128      window["numberTasks"] = result[0].length;
     129
     130      //For each result create a seperate collapsable section with a chart and info label
     131      for(var i = 0; i < result[0].length; i++){
     132        $("#" + "@container").append(
     133          '<section class="chartContainer"><h1 class="title">Task ' + (i + 1) +
     134          '</h1><button class="collapse" onclick="collapseSection(this)">-</button><div id="@(destinationTag)' + i +
     135          '"></div><label id="@(destinationTag)' + i + 'Info"></label></section>'
     136        )
     137        waitTime = [result[0][i]];
     138        transferTime = [result[1][i]];
     139        runTime = [result[2][i]];
     140        window["@(destinationTag)Plot" + i] = $.jqplot("@destinationTag" + i, [waitTime,transferTime,runTime], {
     141          //stackSeries: true,
     142          seriesDefaults:{
     143            renderer:$.jqplot.BarRenderer,
     144            shadowAngle: 135,
     145            //rendererOptions: {
     146            //  barDirection: 'horizontal'
     147            //},
     148            pointLabels: {show: true, formatString: '%.3f'}
     149          },
     150          series:[
     151            {label:'Waiting'},
     152            {label:'Transferring'},
     153            {label:'Calculating'}
     154          ],
     155          legend: {
     156            show: true,
     157            location: 'e',
     158            placement: 'outside'
     159          },
     160          axes: {
     161            xaxis: {
     162              renderer: $.jqplot.CategoryAxisRenderer,
     163              showLabel: false,
     164              pad: 0
     165            },
     166            yaxis: {
     167              pad: 0
     168            }
     169          },
     170          cursor: {
     171            showTooltip: false
     172          }
     173        });
     174        /* Bind a datalistener to each chart and display details of clicked
     175          upon data in the label below the chart */
     176        $("#" + "@(destinationTag)" + i).bind('jqplotDataClick', function (ev, seriesIndex, pointIndex, data) {
     177          $("#" + $(this).attr('id') + "Info").html(seriesDescriptions[seriesIndex] + ': ' + data[1]);
     178        });
     179      }
     180    }});
     181  </text>
     182}
     183
     184@helper ResizeTasks(string destinationTag)
     185{
     186  <text>
     187  $(window).resize(function() {
     188    for(var i = 0; i < numberTasks; i++) {
     189      window[ "@(destinationTag)Plot" + i].replot({ resetAxes: true });
     190    }
     191  });
     192  </text>
     193}
     194
     195@* OLD SMOOTHIE CHART FUNCTIONS *@
     196@*@helper CreateSmoothieChart(string destinationTag, string stroke, string fill, string label)
     197{
     198  <text>
     199    var @(destinationTag)Smoothie = new SmoothieChart({
     200      grid: {
     201        strokeStyle: '@stroke', fillStyle: '@fill',
     202        lineWidth: 1, millisPerLine: 450, verticalSections: 4,
     203      },
     204      labels: {
     205        fillStyle: '@label'
     206      }
     207    });
     208
     209    var @(destinationTag)TimeSeries = new Array()
     210  </text>
     211}
     212
     213@helper SetSmoothieCanvas(string destinationTag, string delay)
     214{
     215  <text>
     216  @(destinationTag)Smoothie.streamTo(document.getElementById("@destinationTag"), @delay);
     217  </text>
     218}
     219
     220@helper AssignTimeSeries(string seriesName, string destinationTag, string stroke, string fill)
     221{
     222  <text>
     223  var @(seriesName)TS = new TimeSeries();
     224  @(destinationTag)Smoothie.addTimeSeries(@(seriesName)TS, { strokeStyle: '@stroke', fillStyle: '@fill', lineWidth: 3 });
     225  @(destinationTag)TimeSeries.push(@(seriesName)TS);
     226  </text>
     227}
     228
     229@helper UpdateChartData(string destinationTag, string url)
     230{
     231  <text>
     232  $.ajax({
     233    url: '@(url)', datatype: "json", success: function (result) {
     234      var i
     235      for (i = 0; i < @(destinationTag)TimeSeries.length; i++) {
     236        @(destinationTag)TimeSeries[i].append(new Date().getTime(), result[i]);
     237      }
     238    }
     239  });
     240  </text>
     241}*@
     242
     243@helper SetStreamingProperties(int refresh, int chartLength, int upperY) {
     244  <text>
     245  //Refresh time (in millisec)
     246  var refreshRate = @(refresh);
     247  //Number of data points on chart
     248  var chartSize = @(chartLength);
     249  //Amount to add to max Y value
     250  var upperYBuffer = @(upperY);
     251
     252  //Used to return a string containing the names of the series
     253  //to be used in plot creation
     254  function getSeries(numberData,dataName){
     255    var result = "[";
     256    for(i=0; i < numberData; i++) {
     257      if(i < numberData -1) {
     258        result += dataName + i + ",";
     259      }
     260      else {
     261        result += dataName + i + "]";
     262      }
     263    }
     264    return result;
     265  }
     266  </text>
     267}
     268
     269@helper CreateStreamChart(string dataName, string destinationTag, string url, string title, string format = null, double? maxY = null) {
     270  <text>
     271  //Get current time, used to create initial values
     272  var @(dataName)CurrentDate = (new Date()).getTime();
     273
     274  var @(dataName)Data = [];
     275  var @(dataName)CurrentValue = [];
     276
     277  //Get the most recent value(s) from the given URL
     278  $.ajax({
     279    async: false, url: '@(url)', datatype: "json", success: function (result) {
     280      for(i = 0; i < result.length; i++) {
     281        @(dataName)CurrentValue[i] = result[i];
     282      }
     283    }
     284  });
     285 
     286  //Create a chartSize worth of data using CurrentDate and CurrentValue
     287  //for each CurrentValue
     288  for(i = 0; i < @(dataName)CurrentValue.length; i++) {
     289    window["@(dataName)Data" + i] = [];
     290    for (j = 0; j < chartSize; j++) {
     291      window[ "@(dataName)Data" + i].push([@(dataName)CurrentDate - (chartSize - 1 - j) * refreshRate, @(dataName)CurrentValue[i]]);
     292    }
     293  }
     294
     295  //Options for the chart to be created
     296  var @(destinationTag)PlotOptions = {
     297    title: "@title",
     298    axes: {
     299      xaxis: {
     300        numberTicks: 4,
     301        renderer: $.jqplot.DateAxisRenderer,
     302        tickOptions: { formatString: '%H:%M:%S' },
     303        min: window["@(dataName)Data" + 0][0][0],
     304        max: window["@(dataName)Data" + 0][window["@(dataName)Data" + 0].length - 1][0]
     305      },
     306      yaxis: {
     307        @if (format != null)
     308        {<text>
     309        tickOptions: {
     310            formatString: "@format",
     311        },
     312        </text>}
     313        min: 0,
     314        @if (maxY != null) {
     315          @:max: @maxY,
    100316        }
    101         @(destinationTag)Plot.replot({ resetAxes: true })
    102     }});
    103     </text>
    104 }
     317        else{
     318          @:max: window["@(dataName)Data" + 0][window["@(dataName)Data" + 0].length - 1][1] + upperYBuffer,
     319        }
     320        numberTicks: 6
     321      }
     322    },
     323    seriesDefaults: {
     324      rendererOptions: { smooth: true },
     325      markerOptions: {
     326        show: false
     327      }
     328    }
     329  };
     330
     331  //Declares the jqPlot variable, evals the string of series returned
     332  //from getSeries which allows for any number of series
     333  window[ "@(destinationTag)Plot"] = $.jqplot('@destinationTag', eval(getSeries(@(dataName)CurrentValue.length,"@(dataName)Data")), @(destinationTag)PlotOptions);
     334  </text>
     335}
     336
     337@helper UpdateStreamChart(string dataName, string destinationTag, string url, string fixedY = null)
     338{
     339  <text>
     340  //If the data is beyond chartSize use shift to trim one off the end
     341  for(i = 0; i < @(dataName)CurrentValue.length; i++) {
     342    if (window["@(dataName)Data" + i].length > chartSize - 1) {
     343      window["@(dataName)Data" + i].shift();
     344    }
     345  }
     346
     347  //Get the up-to-date data, each result assigned to it's own array
     348  $.ajax({
     349    async: false, url: '@(url)', datatype: "json", success: function (result) {
     350      for(i = 0; i < result.length; i++) {
     351        window[ "@(dataName)Data" + i].push([(new Date()).getTime(), result[i]]);
     352      }
     353    }
     354  });
     355
     356  //If the plot exists currently destroy it
     357  if ( @(destinationTag)Plot) {
     358    @(destinationTag)Plot.destroy();
     359  }
     360
     361  //Assign series
     362  for(i = 0; i < @(dataName)CurrentValue.length; i++) {
     363    @(destinationTag)Plot.series[i].data = window["@(dataName)Data" + i];
     364  }
     365
     366  //Recalculate x and possibly y axis max and mins
     367  @(destinationTag)PlotOptions.axes.xaxis.min = window["@(dataName)Data" + 0][0][0];
     368  @(destinationTag)PlotOptions.axes.xaxis.max = window["@(dataName)Data" + 0][window["@(dataName)Data" + 0].length - 1][0];
     369  @if (fixedY == null) {
     370    @:@(destinationTag)PlotOptions.axes.yaxis.max = window["@(dataName)Data" + 0][window["@(dataName)Data" + 0].length - 1][1] + upperYBuffer;
     371  }
     372
     373  //Re-assigns the jqPlot variable, evals the string of series returned
     374  //from getSeries which allows for any number of series
     375  @(destinationTag)Plot = $.jqplot('@destinationTag', eval(getSeries(@(dataName)CurrentValue.length,"@(dataName)Data")), @(destinationTag)PlotOptions);
     376  </text>
     377}
     378
     379@helper MakeCollapsable()
     380{
     381  <text>
     382  $(document).ready(function() {
     383    $(".collapse").click(function () {
     384      if ($(this).html() == "-") {
     385        $(this).parent().children("canvas, div, fieldset, label").fadeOut();
     386        $(this).html("+");
     387      }
     388      else {
     389        $(this).parent().children("canvas, div, fieldset, label").fadeIn();
     390        $(this).html("-");
     391      }
     392    });
     393  });
     394  </text>
     395}
  • branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/Content/Site.css

    r9646 r11020  
    6161}
    6262
     63/* Progress bar styles */
     64.barLabel {
     65  margin: 2% 0% 0% 10%;
     66  font-size: 1.1em;
     67  font-family: inherit;
     68  color: #6B6B6B;
     69  display: block;
     70}
     71
     72.outerBar {
     73  height: 25px;
     74  width: 80%;
     75  margin-left: 10%;
     76  border: 2px outset grey;
     77}
     78
     79.outerBar:last-of-type {
     80  margin-bottom: 2%;
     81}
     82
     83.innerBar {
     84  height: 100%;
     85  vertical-align: middle;
     86  background: rgb(32,122,2); /* Old browsers */
     87  /* IE9 SVG, needs conditional override of 'filter' to 'none' */
     88  background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzIwN2EwMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iIzQwZDgwNCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDZkMDciIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
     89  background: -moz-linear-gradient(top,  rgba(32,122,2,1) 0%, rgba(64,216,4,1) 50%, rgba(0,109,7,1) 100%); /* FF3.6+ */
     90  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(32,122,2,1)), color-stop(50%,rgba(64,216,4,1)), color-stop(100%,rgba(0,109,7,1))); /* Chrome,Safari4+ */
     91  background: -webkit-linear-gradient(top,  rgba(32,122,2,1) 0%,rgba(64,216,4,1) 50%,rgba(0,109,7,1) 100%); /* Chrome10+,Safari5.1+ */
     92  background: -o-linear-gradient(top,  rgba(32,122,2,1) 0%,rgba(64,216,4,1) 50%,rgba(0,109,7,1) 100%); /* Opera 11.10+ */
     93  background: -ms-linear-gradient(top,  rgba(32,122,2,1) 0%,rgba(64,216,4,1) 50%,rgba(0,109,7,1) 100%); /* IE10+ */
     94  background: linear-gradient(to bottom,  rgba(32,122,2,1) 0%,rgba(64,216,4,1) 50%,rgba(0,109,7,1) 100%); /* W3C */
     95  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#207a02', endColorstr='#006d07',GradientType=0 ); /* IE6-8 */
     96  display: inline-block;
     97}
     98
     99.innerBarText, .outerBarText {
     100  height: auto;
     101  margin: 0%;
     102  margin-left: 1%;
     103  font-family: inherit;
     104  font-size: 1.4em;
     105  text-shadow: 0px 0px 6px #D9FCE4;
     106  color: #000000;
     107  display: inline-block;
     108}
     109
     110.outerBarText {
     111  text-align: right;
     112}
     113
     114/* Login Page Styles*/
    63115#login {
    64116  display: block;
     
    89141}
    90142
    91 
    92143#login form {
    93144  display: inline;
     145}
     146
     147#loginForm ol {
     148  list-style: none;
    94149}
    95150
     
    160215}
    161216
     217input[type="text"], input[type="password"] {
     218  border: 1px solid #CCC;
     219}
     220
     221/*Index Page Styles*/
    162222fieldset {
    163223  margin: 1em 0;
     224  margin-bottom: 2em;
    164225  padding: 1em;
    165226  padding-top: 0;
    166   border: 1px solid #CCC;
    167 }
    168 
    169 fieldset ol {
    170   padding: 0;
    171 }
    172 
    173 fieldset li {
    174   list-style: none;
    175   margin: 0.5em 0;
     227  -webkit-border-radius: 3px;
     228  -moz-border-radius: 3px;
     229  border-radius: 3px;
     230  border: 1px solid #8297F5;
    176231}
    177232
     
    180235  font-weight: 600;
    181236  padding: 2px 4px 8px 4px;
    182 }
    183 
    184 input[type="text"], input[type="password"] {
    185   border: 1px solid #CCC;
    186 }
    187 
    188 .charts {
     237  color: #6B6B6B;
     238}
     239
     240fieldset > label, fieldset > input {
     241  font-size: 1.1em;
     242  font-weight: 600;
     243  color: #6B6B6B;
     244  display: block;
     245}
     246
     247fieldset > input {
     248  margin-bottom: 2%;
     249}
     250
     251.charts, .chartContainer, .collapse {
    189252  font-size: 1.5em;
    190253}
    191254
    192 .charts > div {
    193   height: 300px;
    194   margin-top: 15px;
    195   margin-bottom: 5px;
    196   margin-left: 10px;
    197   margin-right: 20px;
    198 }
     255.chartContainer {
     256  width: 90%;
     257  padding: 3%;
     258  margin: 3% 0% 3% 2%;
     259  -webkit-border-radius: 15px;
     260  -moz-border-radius: 15px;
     261  border-radius: 15px;
     262  -webkit-box-shadow: 5px 5px 3px #A3A3A2;
     263  box-shadow: 5px 5px 3px #A3A3A2;
     264  border: 3px solid #8297F5;
     265}
     266
     267.chartContainer > .title {
     268  width: 95%;
     269  border-bottom: none;
     270  display:inline-block;
     271}
     272
     273.chartContainer canvas {
     274  margin: 0% 0% 2% 6%;
     275}
     276
     277.chartContainer > div {
     278  width: 90%;
     279  height: 180px;
     280  margin-left: 3%;
     281}
     282
     283.chartContainer > .smoothieHolder {
     284  width: auto;
     285  height: auto;
     286  margin: 0%;
     287}
     288
     289.chartContainer .smoothieLabel {
     290  width: 100%;
     291  margin: 10px;
     292  display: block;
     293  text-align: center;
     294  font-family: inherit;
     295  font-size: 13pt;
     296  color: #707070;
     297}
     298
     299.collapse {
     300  width: 3%;
     301  min-width: 20px;
     302  margin: 0px;
     303  background: none;
     304  color: #F7921D;
     305  -webkit-border-radius: 3px;
     306  -moz-border-radius: 3px;
     307  border-radius: 3px;
     308  border: 2px solid #F7921D;
     309  text-align: center;
     310  font-size: 1em;
     311  display: inline-block;
     312}
     313
     314.collapse:hover {
     315  background-color: rgba(247,146,29,0.42);
     316}
     317/* User Page Styles*/
     318#tasksContainer div[id^="Task"] {
     319  margin: 2% 0%;
     320}
     321
     322#tasksContainer .jqplot-xaxis {
     323  display: none;
     324}
     325
     326label[id$="Info"] {
     327  font-family: inherit;
     328  font-size: 13pt;
     329  color: #707070;
     330}
     331
     332#filters {
     333  margin: 2% 2% 3% 2%;
     334}
     335
     336#filters legend, #filters label, #filters input {
     337  font-size: 1.6em;
     338}
     339
     340/* Admin Page Styles */
     341[id$="OverviewButton"] {
     342  margin: 3% 0% 0% 0%;
     343  background: none;
     344  color: #707070;
     345  font-size: 1.4em;
     346  -webkit-border-radius: 0 3px 0 0;
     347  border-radius: 0 5px 0 0;
     348  border: 1px solid #8297F5;
     349  text-align: center;
     350  z-index: 3;
     351}
     352
     353#UserOverviewButton {
     354  border-bottom: 1px solid #E0E6FF;
     355  background-color: #E0E6FF;
     356  margin-left: 3%;
     357}
     358
     359[id$="OverviewButton"]:hover {
     360  background-color: #D1D9FF;
     361}
     362
     363[id$="OverviewButton"]:focus {
     364  -webkit-border-radius: 0 3px 0 0;
     365  border-radius: 0 5px 0 0;
     366  border-bottom: 1px solid #FAFAFA;
     367}
     368
     369[id$="OverviewTab"] {
     370  width: 90%;
     371  padding: 1%;
     372  margin: 0% 0% 3% 3%;
     373  -webkit-border-radius: 0 15px 15px 15px;
     374  border-radius: 0 15px 15px 15px;
     375  -webkit-box-shadow: 5px 5px 3px #A3A3A2;
     376  box-shadow: 5px 5px 3px #A3A3A2;
     377  border: 1px solid #8297F5;
     378  display: none;
     379}
     380
     381#UserOverviewTab {
     382  display: block;
     383}
     384
     385.usersField {
     386  width: 20%;
     387  padding: 1% 2% 2% 2%;
     388  margin: 1% 0% 2% 2%;
     389  font-size: 1.4em;
     390  vertical-align: top;
     391  display: inline-block;
     392}
     393
     394.usersList {
     395  width: 100%;
     396  font-family: inherit;
     397  font-size: 10pt;
     398  color: #707070;
     399}
     400
     401.usersField label {
     402  margin-top: 1em;
     403}
     404
     405.adminDataContainer {
     406  width: 70%;
     407  padding-left: 1%;
     408  display: inline-block;
     409}
  • branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/Controllers/ChartDataController.cs

    r9662 r11020  
    2424using System.Linq;
    2525using System.Web.Mvc;
     26using System.Web.Script.Serialization;
    2627using HeuristicLab.Services.Hive.DataAccess;
    2728
     
    3334    public JsonResult AverageCpuUtilization(DateTime? start = null, DateTime? end = null) {
    3435      using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) {
     36        //If no given start date, get date of most recent record
     37        if (start == null) {
     38          start = GetRecentDate(db);
     39        }
    3540        var data =
    3641          from facts in GetClientFacts(db, start, end)
     
    4853    public JsonResult UsedCores(DateTime? start = null, DateTime? end = null) {
    4954      using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) {
     55        //If no given start date, get date of most recent record
     56        if (start == null) {
     57          start = GetRecentDate(db);
     58        }
    5059        var data =
    5160          from facts in GetClientFacts(db, start, end)
     
    6473    public JsonResult UsedMemory(DateTime? start = null, DateTime? end = null) {
    6574      using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString)) {
     75        //If no given start date, get date of most recent record
     76        if (start == null) {
     77          start = GetRecentDate(db);
     78        }
    6679        var data =
    6780          from facts in GetClientFacts(db, start, end)
     
    7689          CreateSeriesData(data.ToList(), x => x.Time, x => x.UsedMemory / 1000, x => x.TotalMemory / 1000),
    7790          JsonRequestBehavior.AllowGet);
     91      }
     92    }
     93
     94    public JsonResult CurrentCores()
     95    {
     96      using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString))
     97      {
     98        var currentCores = (from client in db.FactClientInfos
     99                            select new { client.NumTotalCores, client.NumUsedCores })
     100                            .ToList();
     101
     102        List<int> result = new List<int>();
     103        result.Add(currentCores.Sum(c => c.NumTotalCores));
     104        result.Add(currentCores.Sum(s => s.NumUsedCores));
     105
     106        return Json(result, JsonRequestBehavior.AllowGet);
     107      }
     108    }
     109
     110    public JsonResult CurrentCpuUtilization()
     111    {
     112      using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString))
     113      {
     114        var currentCpuUtil = (from client in db.FactClientInfos
     115                            select new { client.CpuUtilization })
     116                            .ToList();
     117
     118        List<double> result = new List<double>();
     119        result.Add(Math.Round(currentCpuUtil.Average(s => s.CpuUtilization), 2));
     120
     121        return Json(result, JsonRequestBehavior.AllowGet);
     122      }
     123    }
     124
     125    public JsonResult CurrentMemory()
     126    {
     127      using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString))
     128      {
     129        var currentMemory = (from client in db.FactClientInfos
     130                            select new { client.TotalMemory, client.UsedMemory })
     131                            .ToList();
     132
     133        List<int> result = new List<int>();
     134        result.Add(currentMemory.Sum(c => c.TotalMemory)/1000);
     135        result.Add(currentMemory.Sum(s => s.UsedMemory)/1000);
     136
     137        return Json(result, JsonRequestBehavior.AllowGet);
     138      }
     139    }
     140
     141    public JsonResult GetUserTask(string userName, DateTime? start = null, DateTime? end = null)
     142    {
     143      start = start ?? DateTime.Now - DefaultDuration;
     144      end = end ?? DateTime.Now;
     145      using (var db = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString))
     146      {
     147        var data =
     148          (from tasks in db.FactTasks
     149          join jobs in db.DimJobs
     150            on tasks.JobId equals jobs.JobId
     151          where jobs.UserName == userName &&
     152          tasks.StartTime >= start &&
     153          tasks.EndTime < end
     154          select new
     155          {
     156            TotalWaiting = tasks.TotalWaitingTime,
     157            TotalTransfer = tasks.TotalTransferTime,
     158            TotalRuntime = tasks.TotalRuntime
     159          }).ToList();
     160
     161        List<List<double>> overallResult = new List<List<double>>();
     162        List<double> wait = new List<double>();
     163        List<double> transfer = new List<double>();
     164        List<double> run = new List<double>();
     165        data.ForEach(w => wait.Add(w.TotalWaiting));
     166        data.ForEach(t => transfer.Add(t.TotalTransfer));
     167        data.ForEach(r => run.Add(r.TotalRuntime));
     168        overallResult.Add(wait);
     169        overallResult.Add(transfer);
     170        overallResult.Add(run);
     171
     172        return Json(overallResult,JsonRequestBehavior.AllowGet);
    78173      }
    79174    }
     
    98193      );
    99194    }
     195
     196    private static DateTime GetRecentDate(HiveDataContext db)
     197    {
     198      var mostRecent = from dates in db.FactClientInfos
     199        group dates by dates.Time into startDate
     200        select startDate.OrderByDescending(t=>t.Time).FirstOrDefault();
     201      return mostRecent.Max(t=>t.Time);
     202    }
    100203  }
    101204
  • branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/HeuristicLab.Services.Hive.Statistics-3.3.csproj

    r9628 r11020  
    108108    <Compile Include="App_Start\RouteConfig.cs" />
    109109    <Compile Include="Controllers\AccountController.cs" />
     110    <Compile Include="Controllers\AdminDataController.cs" />
    110111    <Compile Include="Controllers\ChartDataController.cs" />
    111112    <Compile Include="Controllers\HomeController.cs" />
     113    <Compile Include="Controllers\LoginRequiredController.cs" />
     114    <Compile Include="Models\AdminModel.cs" />
    112115    <Compile Include="Models\OverallStatistics.cs" />
    113116    <Compile Include="Global.asax.cs">
     
    116119    <Compile Include="Helper\HtmMenulHelper.cs" />
    117120    <Compile Include="Models\AccountModels.cs" />
     121    <Compile Include="Models\UserModel.cs" />
    118122    <Compile Include="Properties\AssemblyInfo.cs" />
    119123    <Content Include="App_Code\ChartHelper.cshtml" />
     124    <Content Include="App_Code\AdminHelper.cshtml" />
    120125    <None Include="Properties\AssemblyInfo.cs.frame" />
     126    <Content Include="Scripts\CollapsingSection.js" />
     127    <Content Include="Scripts\SmoothieChartResize.js" />
     128    <Content Include="Views\LoginRequired\UserTask.cshtml" />
     129    <Content Include="Views\LoginRequired\Admin.cshtml" />
    121130  </ItemGroup>
    122131  <ItemGroup>
     
    177186    <Content Include="Content\hl-logo.png" />
    178187    <Content Include="Global.asax" />
     188    <None Include="Properties\PublishProfiles\HiveStatistics-3.3.pubxml" />
    179189    <None Include="Scripts\jquery-1.8.2.intellisense.js" />
    180190    <Content Include="HeuristicLab.ico" />
     
    266276    <Content Include="Scripts\jquery.validate.unobtrusive.min.js" />
    267277    <Content Include="Scripts\modernizr-2.6.2.js" />
     278    <Content Include="Scripts\smoothie.js" />
    268279    <Content Include="Web.config" />
    269280    <Content Include="Web.Debug.config">
     
    283294    <Content Include="Views\Shared\_LoginPartial.cshtml" />
    284295    <Content Include="Views\Shared\_Layout.cshtml" />
    285     <Content Include="Views\Web.config" />
     296    <Content Include="Views\Web.config">
     297      <SubType>Designer</SubType>
     298    </Content>
    286299  </ItemGroup>
    287300  <ItemGroup>
     
    316329      <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
    317330        <WebProjectProperties>
    318           <UseIIS>True</UseIIS>
     331          <UseIIS>False</UseIIS>
    319332          <AutoAssignPort>True</AutoAssignPort>
    320           <DevelopmentServerPort>0</DevelopmentServerPort>
     333          <DevelopmentServerPort>4496</DevelopmentServerPort>
    321334          <DevelopmentServerVPath>/</DevelopmentServerVPath>
    322           <IISUrl>http://localhost:2088/</IISUrl>
     335          <IISUrl>
     336          </IISUrl>
    323337          <NTLMAuthentication>False</NTLMAuthentication>
    324338          <UseCustomServer>False</UseCustomServer>
  • branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/Views/Home/Index.cshtml

    r9662 r11020  
    22
    33@{
    4     ViewBag.Title = "Status Monitor";
     4  ViewBag.Title = "Status Monitor";
    55}
    66
    77<h1>Current Status</h1>
    88
     9@*
     10Original code
    911<section>
    10     <table>
    11         <tr>
    12             <td>Overall Available Cores</td>
    13             <td>@Model.OverallCurrentlyAvailableCores</td>
    14         </tr>
    15         <tr>
    16             <td>Availabe Cores (real)</td>
    17             <td>@Model.CurrentlyAvailableCores</td>
    18         </tr>
    19         <tr>
    20             <td>Used Cores</td>
    21             <td>@Model.CurrentlyUsedCores</td>
    22         </tr>
    23         <tr>
    24             <td>System-Wide Waiting Tasks</td>
    25             <td>@Model.CurrentlyJobsWaiting</td>
    26         </tr>
    27         <tr>
    28             <td>Overall Avg. CPU Utilization</td>
    29             <td>@Model.OverallCpuUtilization</td>
    30         </tr>
    31         <tr>
    32             <td>Available Avg. CPU Utilization</td>
    33             <td>@Model.AvailableCpuUtilization</td>
    34         </tr>
    35     </table>
     12  <table>
     13    <tr>
     14      <td>Overall Available Cores</td>
     15      <td>@Model.OverallCurrentlyAvailableCores</td>
     16    </tr>
     17    <tr>
     18      <td>Availabe Cores (real)</td>
     19      <td>@Model.CurrentlyAvailableCores</td>
     20    </tr>
     21    <tr>
     22      <td>Used Cores</td>
     23      <td>@Model.CurrentlyUsedCores</td>
     24    </tr>
     25    <tr>
     26      <td>System-Wide Waiting Tasks</td>
     27      <td>@Model.CurrentlyJobsWaiting</td>
     28    </tr>
     29    <tr>
     30      <td>Overall Avg. CPU Utilization</td>
     31      <td>@Model.OverallCpuUtilization</td>
     32    </tr>
     33    <tr>
     34      <td>Available Avg. CPU Utilization</td>
     35      <td>@Model.AvailableCpuUtilization</td>
     36    </tr>
     37  </table>
     38</section>*@
     39
     40<section class="chartContainer">
     41  <h1 class="title">Current Hive Status</h1>
     42  <button class="collapse">-</button>
     43@*  <label id="lblCurrentCPUUtilization" class="smoothieLabel">Current CPU Utilization</label>
     44  <div class="smoothieHolder">
     45    <canvas id="CurrentCPUUtilization" class="smoothieChart"></canvas>
     46  </div>
     47  <label id="lblCurrentTotalUsedCores" class="smoothieLabel">Current Total and Used Cores</label>
     48  <div class="smoothieHolder">
     49    <canvas id="CurrentTotalUsedCores" class="smoothieChart"></canvas>
     50  </div>
     51  <label id="lblCurrentTotalUsedMemory" class="smoothieLabel">Current Total and Used Memory</label>
     52  <div class="smoothieHolder">
     53    <canvas id="CurrentTotalUsedMemory" class="smoothieChart"></canvas>
     54  </div>*@
     55  <div id="CurrentCPUUtilization"></div>
     56  <div id="CurrentTotalUsedCores"></div>
     57  <div id="CurrentTotalUsedMemory"></div>
    3658</section>
    3759
    38 <fieldset>
    39         <legend>Range</legend>
    40         <ol>
    41             <li>Start</li>
    42             <li>
    43                 @Html.TextBox("Start", (DateTime.Now - new TimeSpan(1, 0, 0, 0)).ToString("yyyy-MM-dd"), new { @class = "date" })
    44             </li>
    45             <li>End</li>
    46             <li>
    47                 @Html.TextBox("End", (DateTime.Now + new TimeSpan(1, 0, 0, 0)).ToString("yyyy-MM-dd"), new { @class = "date" })
    48             </li>
    49         </ol>
    50         <button id="refresh">Refresh</button>
    51     </fieldset>
    52 
    53 <section class="charts">
    54     <div id="AverageCpuUtilization"></div>
    55     <div id="UsedCores"></div>
    56     <div id="UsedMemory"></div>
     60<section class="chartContainer">
     61  <h1 class="title">Historic Hive Status</h1>
     62  <button class="collapse">-</button>
     63  <fieldset>
     64    <legend>Range</legend>
     65    <label>Start</label>
     66    @Html.TextBox("Start", (DateTime.Now - new TimeSpan(1, 0, 0, 0)).ToString("yyyy-MM-dd"), new { @class = "date" })
     67    <label>End</label>
     68    @Html.TextBox("End", (DateTime.Now + new TimeSpan(1, 0, 0, 0)).ToString("yyyy-MM-dd"), new { @class = "date" })
     69    <button id="Refresh">Refresh</button>
     70  </fieldset>
     71  <div id="AverageCpuUtilization"></div>
     72  <div id="UsedCores"></div>
     73  <div id="UsedMemory"></div>
    5774</section>
    5875
    5976@section Styles {
    60     @Styles.Render("~/Styles/jqPlot/jquery.jqplot")
    61     @Styles.Render("~/Content/themes/base/css")
     77  @Styles.Render("~/Styles/jqPlot/jquery.jqplot")
     78  @Styles.Render("~/Content/themes/base/css")
    6279}
    6380
    6481@section Scripts {
    65     @Scripts.Render("~/bundles/jqueryui")
    66     <script>
    67     $("#refresh").button({
    68         icons: {
    69             primary: "ui-icon-refresh"
    70         }
     82  @Scripts.Render("~/bundles/jqueryui")
     83  @Scripts.Render("~/Scripts/smoothie.js")
     84  @Scripts.Render("~/Scripts/SmoothieChartResize.js")
     85  @Scripts.Render("~/Scripts/CollapsingSection.js")
     86  <script>
     87    $("#Refresh").button({
     88      icons: {
     89        primary: "ui-icon-refresh"
     90      }
    7191    });
    72     </script>
     92  </script>
    7393
    74     @Scripts.Render("~/Scripts/jqPlot/jquery.jqplot")
    75     @ChartHelper.AjaxDataRenderer()
     94  @Scripts.Render("~/Scripts/jqPlot/jquery.jqplot")
     95  @ChartHelper.AjaxDataRenderer()
    7696
    77     @ChartHelper.LineChartTime(
     97  @ChartHelper.LineChartTime(
    7898        "AverageCpuUtilization",
    7999        Url.Action("AverageCpuUtilization", "ChartData"),
     
    82102        minY: 0, maxY: 100)
    83103
    84     @ChartHelper.LineChartTime(
     104  @ChartHelper.LineChartTime(
    85105        "UsedCores",
    86106        Url.Action("UsedCores", "ChartData"),
     
    88108        minY: 0)
    89109
    90     @ChartHelper.LineChartTime(
     110  @ChartHelper.LineChartTime(
    91111        "UsedMemory",
    92112        Url.Action("UsedMemory", "ChartData"),
     
    94114        minY: 0)
    95115
    96     <script>
    97         $(document).ready(function () {
    98             $(".date").datepicker({
    99                 dateFormat: "yy-mm-dd",
    100                 onSelect: function () { refreshCharts(); }
    101             });
     116  <script>
     117    $(document).ready(function () {
     118      $(".date").datepicker({
     119        dateFormat: "yy-mm-dd",
     120        onSelect: function () { refreshCharts(); }
     121      });
    102122
    103             $("#refresh").click(function() {
    104                 refreshCharts();
    105             });
     123      $("#Refresh").click(function () {
     124        refreshCharts();
     125      });
    106126
    107            
    108         });
    109        
    110         function refreshCharts() {
    111             var startDate = $('#Start').val();
    112             var endDate = $('#End').val();
     127      //resizeSmoothie();
     128      //createSmoothie();
     129    });
    113130
    114             @ChartHelper.RefreshChart("AverageCpuUtilization", Url.Action("AverageCpuUtilization", "ChartData"), "startDate", "endDate")
    115             @ChartHelper.RefreshChart("UsedCores", Url.Action("UsedCores", "ChartData"), "startDate", "endDate")
    116             @ChartHelper.RefreshChart("UsedMemory", Url.Action("UsedMemory", "ChartData"), "startDate", "endDate")
    117         }
    118     </script>
     131    function refreshCharts() {
     132      var startDate = $('#Start').val();
     133      var endDate = $('#End').val();
     134
     135      @ChartHelper.RefreshChart("AverageCpuUtilization", Url.Action("AverageCpuUtilization", "ChartData"), "startDate", "endDate")
     136      @ChartHelper.RefreshChart("UsedCores", Url.Action("UsedCores", "ChartData"), "startDate", "endDate")
     137      @ChartHelper.RefreshChart("UsedMemory", Url.Action("UsedMemory", "ChartData"), "startDate", "endDate")
     138    }
     139
     140@*    function createSmoothie() {
     141      //Create new SmoothieChart(s)
     142      @ChartHelper.CreateSmoothieChart("CurrentCPUUtilization","rgb(179, 179, 179)","rgb(242, 242, 242)","rgb(0, 22, 84)")
     143      @ChartHelper.CreateSmoothieChart("CurrentTotalUsedCores","rgb(179, 179, 179)","rgb(242, 242, 242)","rgb(0, 22, 84)")
     144      @ChartHelper.CreateSmoothieChart("CurrentTotalUsedMemory","rgb(179, 179, 179)","rgb(242, 242, 242)","rgb(0, 22, 84)")
     145
     146      //Second argument is delay in chart display, used to make drawing smooth,
     147      //Should be matched to interval time below
     148      @ChartHelper.SetSmoothieCanvas("CurrentCPUUtilization","5000")
     149      @ChartHelper.SetSmoothieCanvas("CurrentTotalUsedCores","5000")
     150      @ChartHelper.SetSmoothieCanvas("CurrentTotalUsedMemory","5000")
     151
     152      //Set interval to run ajax and get new values
     153      @ChartHelper.AssignTimeSeries("averageUsage", "CurrentCPUUtilization", "rgb(0, 255, 0)", "rgba(0, 255, 0, 0.4)")
     154      @ChartHelper.AssignTimeSeries("overallCore", "CurrentTotalUsedCores", "rgb(0, 255, 0)", "rgba(0, 255, 0, 0.4)")
     155      @ChartHelper.AssignTimeSeries("usedCore", "CurrentTotalUsedCores", "rgb(242, 182, 70)", "rgba(255, 199, 94, 0.4)")
     156      @ChartHelper.AssignTimeSeries("overallMemory", "CurrentTotalUsedMemory", "rgb(0, 255, 0)", "rgba(0, 255, 0, 0.4)")
     157      @ChartHelper.AssignTimeSeries("usedMemory", "CurrentTotalUsedMemory", "rgb(242, 182, 70)", "rgba(255, 199, 94, 0.4)")
     158
     159      setInterval(function () { getChartUpdate() }, 5000);
     160
     161      //Hit by interval, jQuery ajax request to get new data from db
     162      function getChartUpdate() {
     163        @ChartHelper.UpdateChartData("CurrentCPUUtilization", Url.Action("CurrentCpuUtilization","ChartData"))
     164        @ChartHelper.UpdateChartData("CurrentTotalUsedCores", Url.Action("CurrentCores","ChartData"))
     165        @ChartHelper.UpdateChartData("CurrentTotalUsedMemory", Url.Action("CurrentMemory","ChartData"))
     166      }
     167    }*@
     168
     169    $(document).ready(function () {
     170      @ChartHelper.SetStreamingProperties(1000,20,10)
     171
     172      @ChartHelper.CreateStreamChart("CurrentCPU", "CurrentCPUUtilization",Url.Action("CurrentCpuUtilization","ChartData"),"Current CPU Utilization","%.2f%%",100.00)
     173      @ChartHelper.CreateStreamChart("CurrentCores", "CurrentTotalUsedCores",Url.Action("CurrentCores","ChartData"),"Current Total vs. Used Cores")
     174      @ChartHelper.CreateStreamChart("CurrentMemory", "CurrentTotalUsedMemory",Url.Action("CurrentMemory","ChartData"),"Current Total vs. Used Memory")
     175
     176      function doUpdate() {
     177        @ChartHelper.UpdateStreamChart("CurrentCPU","CurrentCPUUtilization", Url.Action("CurrentCpuUtilization","ChartData"),"FixedY")
     178        @ChartHelper.UpdateStreamChart("CurrentCores","CurrentTotalUsedCores", Url.Action("CurrentCores","ChartData"))
     179        @ChartHelper.UpdateStreamChart("CurrentMemory","CurrentTotalUsedMemory", Url.Action("CurrentMemory","ChartData"))
     180        setTimeout(doUpdate, refreshRate);
     181      }
     182
     183      doUpdate();
     184
     185    });
     186  </script>
    119187}
  • branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/Views/Shared/_Layout.cshtml

    r9617 r11020  
    2222            <ul>
    2323                <li>@Html.MenuItem("Home", "Index", "Home")</li>
     24                <li>@Html.MenuItem("User", "UserTask", "LoginRequired")</li>
     25                <li>@Html.MenuItem("Admin", "Admin", "LoginRequired")</li>
    2426                <li>@Html.MenuItem("About", "About", "Home")</li>
    2527                <li>@Html.MenuItem("Contact", "Contact", "Home")</li>
  • branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Statistics/3.3/Web.config

    r9604 r11020  
    1 <?xml version="1.0" encoding="utf-8"?>
     1<?xml version="1.0"?>
    22<!--
    33  For more information on how to configure your ASP.NET application, please visit
     
    66<configuration>
    77  <connectionStrings>
    8     <add name="HeuristicLab.Authentication" connectionString="data source=localhost;Integrated Security=SSPI;Initial Catalog=HeuristicLab.Authentication" />
    9     <!--<add name="HeuristicLab.Services.Hive.DataAccess.Settings.HeuristicLab_Hive_LinqConnectionString" connectionString="Data Source=localhost;Initial Catalog=HeuristicLab.Hive-3.3;Integrated Security=True;" providerName="System.Data.SqlClient" />-->
     8    <add name="HeuristicLab.Authentication" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=HeuristicLab.Authentication"/>
     9    <add name="HeuristicLab.Services.Hive.DataAccess.Settings.HeuristicLab_Hive_LinqConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=HeuristicLab.Hive-3.3;Integrated Security=True;" providerName="System.Data.SqlClient"/>
    1010  </connectionStrings>
    1111  <appSettings>
    12     <add key="webpages:Version" value="2.0.0.0" />
    13     <add key="webpages:Enabled" value="false" />
    14     <add key="PreserveLoginUrl" value="true" />
    15     <add key="ClientValidationEnabled" value="true" />
    16     <add key="UnobtrusiveJavaScriptEnabled" value="true" />
     12    <add key="webpages:Version" value="2.0.0.0"/>
     13    <add key="webpages:Enabled" value="false"/>
     14    <add key="PreserveLoginUrl" value="true"/>
     15    <add key="ClientValidationEnabled" value="true"/>
     16    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
    1717  </appSettings>
    1818  <system.web>
    19     <compilation debug="true" targetFramework="4.0" />
     19    <compilation targetFramework="4.0" debug="true"/>
    2020    <authentication mode="Forms">
    21       <forms loginUrl="~/Account/Login" timeout="2880" />
     21      <forms loginUrl="~/Account/Login" timeout="2880"/>
    2222    </authentication>
    2323    <membership>
    2424      <providers>
    25         <clear />
    26         <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="HeuristicLab.Authentication" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="HeuristicLab.Authentication" />
     25        <clear/>
     26        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="HeuristicLab.Authentication" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="HeuristicLab.Authentication"/>
    2727      </providers>
    2828    </membership>
    2929    <roleManager enabled="true">
    3030      <providers>
    31         <clear />
    32         <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="HeuristicLab.Authentication" applicationName="HeuristicLab.Authentication" />
     31        <clear/>
     32        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="HeuristicLab.Authentication" applicationName="HeuristicLab.Authentication"/>
    3333      </providers>
    3434    </roleManager>
    3535    <pages>
    3636      <namespaces>
    37         <add namespace="System.Web.Helpers" />
    38         <add namespace="System.Web.Mvc" />
    39         <add namespace="System.Web.Mvc.Ajax" />
    40         <add namespace="System.Web.Mvc.Html" />
    41         <add namespace="System.Web.Optimization" />
    42         <add namespace="System.Web.Routing" />
    43         <add namespace="System.Web.WebPages" />
     37        <add namespace="System.Web.Helpers"/>
     38        <add namespace="System.Web.Mvc"/>
     39        <add namespace="System.Web.Mvc.Ajax"/>
     40        <add namespace="System.Web.Mvc.Html"/>
     41        <add namespace="System.Web.Optimization"/>
     42        <add namespace="System.Web.Routing"/>
     43        <add namespace="System.Web.WebPages"/>
    4444      </namespaces>
    4545    </pages>
    4646  </system.web>
    4747  <system.webServer>
    48     <validation validateIntegratedModeConfiguration="false" />
    49     <modules runAllManagedModulesForAllRequests="true" />
     48    <validation validateIntegratedModeConfiguration="false"/>
     49    <modules runAllManagedModulesForAllRequests="true"/>
    5050  </system.webServer>
    5151  <runtime>
    5252    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    5353      <dependentAssembly>
    54         <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
    55         <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
     54        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
     55        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0"/>
    5656      </dependentAssembly>
    5757      <dependentAssembly>
    58         <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
    59         <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
     58        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
     59        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
    6060      </dependentAssembly>
    6161      <dependentAssembly>
    62         <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
    63         <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
     62        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
     63        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0"/>
    6464      </dependentAssembly>
    6565      <dependentAssembly>
    66         <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
    67         <bindingRedirect oldVersion="0.0.0.0-1.3.0.0" newVersion="1.3.0.0" />
     66        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35"/>
     67        <bindingRedirect oldVersion="0.0.0.0-1.3.0.0" newVersion="1.3.0.0"/>
    6868      </dependentAssembly>
    6969    </assemblyBinding>
Note: See TracChangeset for help on using the changeset viewer.