@* HeuristicLab
* Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*@
@helper AjaxDataRenderer()
{
}
@helper LineChartTime(string destinationTag, string url, string title = "", double? minY = null, double? maxY = null, string axisYFormat = null) {
}
@helper RefreshChart(string destinationTag, string url, string startDate, string endDate, double? minY=null, double? maxY=null) {
$.ajax({url: "@(new HtmlString(url))?start=" + @startDate + "&end=" + @endDate, datatype: "json", success: function(result) {
for (var i = 0; i < result.length; i++) {
@(destinationTag)Plot.series[i].data = result[i];
}
//Resets only the xaxis, still need to resize y with given min/max
@(destinationTag)Plot.replot({resetAxes:true});
@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 max Y was provided set the plot's max Y value
@:@(destinationTag)Plot.axes.yaxis.max = @maxY;
}
@(destinationTag)Plot.axes.yaxis.reset();
//A final replot to redraw possible new Y axis values
@(destinationTag)Plot.replot({resetAxes:['xaxis']});
@* @(destinationTag)Plot.replot({ resetAxes:true });*@
}});
}
@helper ResizeCharts()
{
function resizeCharts(caller) {
//If current plot is collapsed
if($(caller).css("display") == "none") {
//Display the contents of chartContainer
ResizeOpenClose($(caller).siblings(".collapse"));
//Reset barWidth for bar charts
$.each(window[caller.id].series, function(index, series) {
series.barWidth = undefined;
});
//Replot the chart with same name as element id
window[caller.id].replot({ resetAxes: false });
//Hide the contents of the current div
ResizeOpenClose($(caller).siblings(".collapse"));
}
//Current plot is expanded
else {
//Reset barWidth for bar charts
$.each(window[caller.id].series, function(index, series) {
series.barWidth = undefined;
});
//Replot the chart with same name as element id
window[caller.id].replot({ resetAxes: false });
}
}
$(window).resize(function() {
$("div.jqplot-target",".chartContainer").each(function() {
var potentialTab = $(this).parent().parent().parent();
//If the section is tabular and currently hidden
if(potentialTab.hasClass("tabSection") && potentialTab.css("display") == "none") {
ResizeOpenCloseTabular(potentialTab);
resizeCharts(this);
ResizeOpenCloseTabular(potentialTab);
}
else {
resizeCharts(this);
}
});
});
}
@helper NumberPages(string records, string limit, string container, string functionName, string currentPage = null)
{
if(@(records).length > @limit) {
$("#@container").append('')
var pages = Math.floor(@(records).length/@(limit)) + 1;
for(var i=0; i < pages; i++) {
$("#" + "@container").append('' + (i + 1) + '')
}
if(@currentPage != null) {
$("#@(container)Page" + @currentPage).css('color','#F7921D');
}
else {
$("#@(container)Page1").css('color','#F7921D');
}
$(".page").click(function () {
pageNumber = $(this).html();
@(functionName)();
});
if(@currentPage != null) {
@(records).splice(0,(@(currentPage)-1)*@(limit));
if (@(records).length > @(limit)) {
@(records).splice(@(limit), @(records).length - @(limit));
}
}
else {
@(records).splice(@(limit), @(records).length - @(limit));
}
}
}
@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)
{
var GetRequest = "?userName=" + @(userName);
@if (startDate != null)
{
@:if(@(startDate)!=null) {
@:GetRequest += "&start=" + @startDate;
@:}
}
@if (endDate != null)
{
@:if(@(endDate)!=null) {
@:GetRequest += "&end=" + @endDate;
@:}
}
@if (jobId != null)
{
@:if(@(jobId)!=null) {
@:GetRequest += "&jobId=" + @jobId;
@:}
}
@if (taskState != null)
{
@:if(@(taskState)!=null) {
@:GetRequest += "&taskState=" + @taskState;
@:}
}
$.ajax({
async: false, url: "@(new HtmlString(url))" + GetRequest, datatype: "json", success: function(result) {
if(@(userName) == null) {
$("#@(destinationTag)").append(
'' +
'
' + @userName + ' has no tasks for the specified filters!
' +
''
)
}
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');
//Set variable for tracking jobId and open first job grouping
var currentJob = result[0].JobId;
$("#@(destinationTag)").append('
' + result[0].JobName + '
');
//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('
' +
'' +
'' +
'' +
'More Info' +
''
)
//Re-enables the error display if any of the tasks on the page have Ids matching
//those of errors
$(".errorTask","#" + "@(destinationTag)").each(function() {
if($(this).html()==result[i].TaskId) {
$("#@(destinationTag)" + result[i].TaskId + "PlotTitle").css("color","red");
$("#@(destinationTag)" + result[i].TaskId + "PlotTitle").append(" - ERROR");
$(".errorContainer, .errorTitle, .underline","#@(destinationTag)").css('display','inline-block');
$(this).css('display','inline-block');
$(this).next().css('display','inline-block');
}
});
waitTime = [result[i].TotalWaiting];
transferTime = [result[i].TotalTransfer];
runTime = [result[i].TotalRuntime];
window["@(destinationTag)Plot" + i] = $.jqplot("@(destinationTag)Plot" + i, [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 */
$("#" + "@(destinationTag)Plot" + i).bind('jqplotDataClick', function (ev, seriesIndex, pointIndex, data) {
$(this).next("label").html(seriesDescriptions[seriesIndex] + ": " + data[1]);
});
CollapsedByDefault(document.getElementById("@(destinationTag)Plot" + i));
}
}
}});
}
@helper SetStreamingProperties(int refresh, int chartLength, int upperY)
{
//Refresh time (in millisec)
var refreshRate = @(refresh);
//Number of data points on chart
var chartSize = @(chartLength);
//Amount to add to max Y value
var upperYBuffer = @(upperY);
//Used to return a string containing the names of the series
//to be used in plot creation
function GetSeries(numberData,dataName){
var result = "[";
for(i=0; i < numberData; i++) {
if(i < numberData -1) {
result += dataName + i + ",";
}
else {
result += dataName + i + "]";
}
}
return result;
}
}
@helper CreateStreamChart(string dataName, string destinationTag, string url, string title, string format = null, double? maxY = null)
{
//Get current time, used to create initial values
var @(dataName)CurrentDate = (new Date()).getTime();
var @(dataName)Data = [];
var @(dataName)CurrentValue = [];
//Get the most recent value(s) from the given URL
$.ajax({
async: false, url: '@(url)', datatype: "json", success: function (result) {
for(i = 0; i < result.length; i++) {
@(dataName)CurrentValue[i] = result[i];
}
}
});
//Create a chartSize worth of data using CurrentDate and CurrentValue
//for each CurrentValue
for(i = 0; i < @(dataName)CurrentValue.length; i++) {
window["@(dataName)Data" + i] = [];
for (j = 0; j < chartSize; j++) {
window[ "@(dataName)Data" + i].push([@(dataName)CurrentDate - (chartSize - 1 - j) * refreshRate, @(dataName)CurrentValue[i]]);
}
}
//Options for the chart to be created
var @(destinationTag)PlotOptions = {
title: "@title",
axes: {
xaxis: {
numberTicks: 4,
renderer: $.jqplot.DateAxisRenderer,
tickOptions: { formatString: '%H:%M:%S' },
min: window["@(dataName)Data" + 0][0][0],
max: window["@(dataName)Data" + 0][window["@(dataName)Data" + 0].length - 1][0]
},
yaxis: {
@if (format != null)
{
tickOptions: {
formatString: "@format",
},
}
min: 0,
@if (maxY != null)
{
@:max: @maxY,
}
else
{
@:max: window["@(dataName)Data" + 0][window["@(dataName)Data" + 0].length - 1][1] + upperYBuffer,
}
numberTicks: 6
}
},
seriesDefaults: {
rendererOptions: { smooth: true },
markerOptions: {
show: false
}
}
};
//Declares the jqPlot variable, evals the string of series returned
//from getSeries which allows for any number of series
window[ "@(destinationTag)Plot"] = $.jqplot('@destinationTag', eval(GetSeries(@(dataName)CurrentValue.length,"@(dataName)Data")), @(destinationTag)PlotOptions);
}
@helper UpdateStreamChart(string dataName, string destinationTag, string url, string fixedY = null)
{
//If the data is beyond chartSize use shift to trim one off the end
for(i = 0; i < @(dataName)CurrentValue.length; i++) {
if (window["@(dataName)Data" + i].length > chartSize - 1) {
window["@(dataName)Data" + i].shift();
}
}
//Get the up-to-date data, each result assigned to it's own array
$.ajax({
async: false, url: '@(url)', datatype: "json", success: function (result) {
for(i = 0; i < result.length; i++) {
window[ "@(dataName)Data" + i].push([(new Date()).getTime(), result[i]]);
}
}
});
//If the plot exists currently destroy it
if ( @(destinationTag)Plot) {
@(destinationTag)Plot.destroy();
}
//Assign series
for(i = 0; i < @(dataName)CurrentValue.length; i++) {
@(destinationTag)Plot.series[i].data = window["@(dataName)Data" + i];
}
//Recalculate x and possibly y axis max and mins
@(destinationTag)PlotOptions.axes.xaxis.min = window["@(dataName)Data" + 0][0][0];
@(destinationTag)PlotOptions.axes.xaxis.max = window["@(dataName)Data" + 0][window["@(dataName)Data" + 0].length - 1][0];
@if (fixedY == null)
{
@:@(destinationTag)PlotOptions.axes.yaxis.max = window["@(dataName)Data" + 0][window["@(dataName)Data" + 0].length - 1][1] + upperYBuffer;
}
//Re-assigns the jqPlot variable, evals the string of series returned
//from getSeries which allows for any number of series
@(destinationTag)Plot = $.jqplot('@destinationTag', eval(GetSeries(@(dataName)CurrentValue.length,"@(dataName)Data")), @(destinationTag)PlotOptions);
}
@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)
{
var GetRequest = "";
@if (startDate != null)
{
@:if(@(startDate)!=null) {
@:if(GetRequest == "") {
@:GetRequest += "?start=" + @startDate;
@:}
@:else {
@:GetRequest += "&start=" + @startDate;
@:}
@:}
}
@if (endDate != null)
{
@:if(@(endDate)!=null) {
@:if(GetRequest == "") {
@:GetRequest += "?end=" + @endDate;
@:}
@:else {
@:GetRequest += "&end=" + @endDate;
@:}
@:}
}
@if (userName != null)
{
@:if(@(userName)!=null) {
@:if(GetRequest == "") {
@:GetRequest += "?userName=" + @userName;
@:}
@:else {
@:GetRequest += "&userName=" + @userName;
@:}
@:}
}
@if (slaveId != null)
{
@:if(@(slaveId)!=null) {
@:if(GetRequest == "") {
@:GetRequest += "?slaveId=" + @slaveId;
@:}
@:else {
@:GetRequest += "&slaveId=" + @slaveId;
@:}
@:}
}
$.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
var slaveChartNames = ["TotalUsedCores","TotalUsedMemory","CPUUtilization"];
var destTag = eval("@(destinationTag)");
if(typeof eval("@(destinationTag)") != "string") {
destTag = "@(destinationTag)";
}
if(result.length == 0) {
@if (!singleSlave) {
@:$('#' + destTag).html("");
}
$('#' + destTag).append(
'' +
'
No slave information for the specified filters!
' +
''
)
}
else {
var time = new Date();
@if (!singleSlave)
{
@:$('#' + 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++) {
var coreSeries = [];
coreSeries[0] = [];
coreSeries[1] = [];
var memorySeries = [];
memorySeries[0] = [];
memorySeries[1] = [];
var cpuSeries = [];
cpuSeries[0] = [];
$('#' + destTag).append(
'' +
'