- Timestamp:
- 03/11/13 14:40:04 (12 years ago)
- Location:
- branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/Index.cshtml
r9215 r9305 60 60 @section submenu { 61 61 <ul> 62 <li class="selected">@Html.ActionLink("Build", " Index")</li>63 <li>@Html.ActionLink("Edit", " Edit")</li>62 <li class="selected">@Html.ActionLink("Build", "New")</li> 63 <li>@Html.ActionLink("Edit", "NewEdit")</li> 64 64 <li>@Html.ActionLink("Status", "Index", "Status")</li> 65 65 </ul> -
branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/New.cshtml
r9227 r9305 1 1 @model HeuristicLab.Services.Optimization.Web.Models.ExperimentViewModel 2 @{ 3 ViewBag.Title = "Index.cshtml"; 4 } 5 2 <script type="text/template" id="node_template"> 3 <li><%= title%></li> 4 </script> 5 6 <script type="text/template" id="tree_template"> 7 <div id="<%= id %>" class="treeStyle"> 8 <ul> 9 </ul> 10 </div> 11 </script> 12 13 <script type="text/template" id="draggable_template"> 14 <div id="<%= nodeId %>" data-isExperiment="<%= isExperiment%>" data-name="<%= title%>" class="dragables"><p><%= title %></p></div> 15 </script> 16 17 <script type="text/template" id="stepwizard_template"> 18 <input style="margin-top:5px;" class="remove-button" name="RemoveNode" type="button" value="Remove" disabled="disabled" /> 19 <input style="margin-top:5px;" class="variate-button" name="VariateNode" type="button" value="Variate" disabled="disabled" /> 20 </script> 21 22 <script type="text/template" id="parameter_template"> 23 <div> 24 <div class="leftEntry"><%= Name %>:</div> 25 <div class="rightEntry"></div> 26 </div> 27 </script> 28 29 <script type="text/template" id="validationhints_template"> 30 <div class="validator" title="<%= header %>"> 31 <p><span class="ui-icon ui-icon-alert" style="float: left; margin: 0 7px 20px 0;"></span> 32 <%= text %> 33 </p> 34 </div> 35 </script> 36 37 <script type="text/template" id="variationdialog_template"> 38 <div class="variationDialog" title="Variate algorithm"> 39 <h1>Select parameter</h1> 40 <select class="variationDialogContent"> 41 </select> 42 <input type="checkbox" name="active" /> Active 43 <div class="variationDetails"> 44 </div> 45 </div> 46 </script> 47 48 <script type="text/template" id="variationentry_template"> 49 <option data-index='<%= Index %>'><%= Name %></option> 50 </script> 51 52 <script type="text/template" id="variationcontent_template"> 53 <div> 54 55 56 </div> 57 </script> 58 59 <script type="text/template" id="variation_boolean_template"> 60 <p>Boolean paramter: True / False</p> 61 </script> 62 63 <script type="text/template" id="variation_number_template"> 64 <div> 65 <input type="button" name="generate" value="Generate..."/> 66 <div></div> 67 </div> 68 </script> 69 70 <script type="text/template" id="checkbox_template"> 71 <div> 72 <input type="checkbox" name="<%=name%>"/><%=text%><br/> 73 </div> 74 </script> 75 76 <script type="text/template" id="variation_generator_template"> 77 <div title="Generate Values"> 78 <div class="leftEntry">Minimum:</div> 79 <div class="rightEntry"><input type="text" name="minimum" value="0"/></div> 80 <div class="leftEntry">Maximum:</div> 81 <div class="rightEntry"><input type="text" name="maximum" value="2"/></div> 82 <div class="leftEntry">Step:</div> 83 <div class="rightEntry"><input type="text" name="step" value="1"/></div> 84 </div> 85 </script> 86 87 <script type="text/template" id="loading_template"> 88 <div> 89 <p>Loading ... </p> 90 <img src="@Url.Content("~/Content/ajax-loader.gif")" alt="Loading animation" class="loader" /> 91 </div> 92 </script> 6 93 7 94 <script type="text/javascript"> 8 function Experiment() { 9 this.algorithms = []; 10 this.nodeMapping = {}; 11 this.name = "My Experiment" 12 } 13 14 Experiment.prototype.buildAndStore = function(node, index, tree, ctx) { 15 var result = this.build(node, index, tree, 'Experiment'); 16 this.algorithms = result.algorithms; 17 this.nodeMapping = result.mapping; 18 } 19 20 Experiment.prototype.build = function(node, index, tree, ctx) { 21 var stack = new Array(); 22 var root = {name : node.title, children: [], context: ctx}; 23 var nodeMapping = {}; 24 this.fetchNode(root, node, index, tree); 25 if (node.title != 'Experiment') 26 nodeMapping[node.key] = root; 27 28 if (node.children) 29 for (var i=0; i < node.children.length; i++) { 30 stack.push({parent: root, child: node.children[node.children.length - 1 - i], index: node.children.length - 1 - i}); 31 } 32 while(stack.length > 0) { 33 var tmp = stack.pop(); 34 var parent = tmp.parent; 35 var child = tmp.child; 36 var newChild = { name : child.title, children: [], context: ctx} 37 // fetch the nodes from the server 38 this.fetchNode(newChild, child, tmp.index, tree); 39 nodeMapping[tmp.child.key] = newChild; 40 parent.children.push(newChild); 41 if (child.children) 42 for (var i=0; i < child.children.length; i++) { 43 stack.push({parent: newChild, child: child.children[child.children.length - 1 - i], index: child.children.length - 1 - i}); 44 } 45 } 46 return {algorithms: root, mapping: nodeMapping}; 47 } 48 49 Experiment.prototype.fetchNode = function(modelNode, dynaNode, index, tree) { 50 if (modelNode.name == 'Experiment') 51 return; 52 var self = this; 53 var node = tree.getNodeByKey(dynaNode.key); 54 $.ajax({ 55 type: "GET", 56 url: '/Experiment/GetParameters', 57 data: { scenario: modelNode.name, context: modelNode.context, index: index }, 58 contentType: "application/json; charset=utf-8", 59 dataType: "json", 60 success: function (result) { 61 if (result.Type == "Complex") { 62 // extend the tree element 63 node.removeChildren(); 64 var parent = self.nodeMapping[node.data.key]; 65 for (var i=0; i < result.Subnames.length; i++) { 66 // add node to dynatree 67 var childNode = node.addChild({title: result.Subnames[i]}); 68 var internalResult = self.build(childNode.toDict(true), i, tree, modelNode.name); 69 parent.children.push(internalResult.algorithms); 70 for (var attrname in internalResult.mapping) { self.nodeMapping[attrname] = internalResult.mapping[attrname]; } 71 } 72 } else if (result.Type == "Basic") { 73 // replace the wizard 74 previousWizards[node.data.key] = replaceWizard(result); 75 saveParameters(previousWizards[node.data.key], node); 76 } 77 } 95 var controller = new ExperimentPageController(); 96 $(document).ready(function () { 97 controller.create(); 78 98 }); 79 } 80 81 Experiment.prototype.pushNode = function(parentKey, nodeKey, entryName, ctx) { 82 var entry = {name: entryName, children: [], context: ctx}; 83 this.nodeMapping[parentKey].children.push(entry); 84 this.nodeMapping[nodeKey] = entry; 85 } 86 87 var experiment = new Experiment(); 88 var previousWizards = {}; 89 90 function saveExperiment() { 91 $('.buttonFinish').attr('disabled', 'disabled'); 92 experiment["name"] = $('#name').val(); 93 experiment["run"] = $('#runImmediately').attr('checked') == 'checked'; 94 experiment["repititions"] = $('#repititions').val(); 95 experiment["group"] = $('#group').val(); 96 97 $.ajax({ type: "POST", 98 url: '/Experiment/SaveExperiment', 99 data: JSON.stringify(experiment), 100 contentType: "application/json; charset=utf-8", 101 dataType: "json", 102 success: function (result) { 103 $('#status-dialog').dialog("open"); 104 }, 105 error: function (result) { 106 } 107 }); 108 } 109 110 function treeIndexOf(sibling) { 111 var i = 0; 112 var prev = sibling.getPrevSibling() 113 while (prev != null) { 114 i++; 115 prev = prev.getPrevSibling() 116 } 117 return i; 118 } 119 120 function saveParameters(wiz, node) { 121 var wiz = typeof wiz !== 'undefined' ? $(wiz) : $('.wizard', '#parameter-dialog-content'); 122 var id = wiz.attr('id'); 123 var node = typeof node !== 'undefined' ? node : $('#container2').dynatree("getActiveNode"); 124 var data = {}; 125 126 for (var i = 1; i < 3; i++) { 127 var stepId = '#' + id + '_' + i; 128 var step = $(stepId); 129 if (step.length == 0) { 130 break; 131 } 132 var stepDesc = $('a[href="' + stepId + '"] span', wiz).contents()[0].data; 133 var dataEntries = $('input, select', step); 134 var entry = { }; 135 var mapper = new DatatypeMapper(); 136 for (var j = 0; j < dataEntries.length; j++) { 137 entry[dataEntries[j].name] = mapper.mapString(dataEntries[j].value); 138 } 139 data[stepDesc] = entry; 140 } 141 142 // aggregate tables: 143 var mapper = new DatatypeMapper(); 144 mapper.aggregateTables(data); 145 146 var experimentEntry = experiment.nodeMapping[node.data.key]; 147 // we are at the node, update data 148 experimentEntry["data"] = data; 149 // Close dialog 150 $('#params').dialog("close"); 151 } 152 153 function createParamterDiv(name, parameters) { 154 var mapper = new DatatypeMapper(); 155 // get algorithm parameters 156 var paramsDiv = $('<div />').data("name", name); 157 for (var i=0; i < parameters.length; i++) { 158 var property = parameters[i]; 159 var content = mapper.mapHtml(property.Value); 160 161 // add to canvas 162 $('<h2/>').text(property.Value.Name).appendTo(paramsDiv); 163 content.appendTo(paramsDiv); 164 $('<div />').addClass('clearer').appendTo(paramsDiv); 165 } 166 return paramsDiv; 167 } 168 169 function createWizard(name, steps) { 170 var wizard = $('<div />', { id: name }).addClass('wizard swMain'); 171 var stepMenu = $('<ul />'); 172 var prefix = name + '_'; 173 for (var i = 0; i < steps.length; i++) { 174 var step = steps[i]; 175 var a = $('<a></a>', {href: '#' + prefix + (i + 1)}); 176 $('<label />').addClass("stepNumber").text((i + 1)).appendTo(a); 177 $('<span />').addClass("stepDesc").html(step.heading + '<br /><small>' + step.description + '</small>').appendTo(a); 178 var li = $('<li />').append(a); 179 li.appendTo(stepMenu); 180 } 181 stepMenu.appendTo(wizard); 182 for (var i = 0; i < steps.length; i++) { 183 var div = $('<div />', { id: prefix + (i + 1) }); 184 if (steps[i].content && steps[i].content != null) 185 div.append(steps[i].content); 186 div.appendTo(wizard); 187 } 188 return wizard; 189 } 190 191 192 function makeTree() { 193 var tree = $('#container').dynatree({ 194 onActivate: function (node) { 195 if (node && node.data.title !== "Experiment") { 196 $('input[name="RemoveNode"]').removeAttr("disabled"); 197 } else if (node) { 198 $('input[name="RemoveNode"]').attr("disabled", "disabled"); 199 } 200 }, 201 onDeactivate: function (node) { 202 }, 203 dnd: { 204 autoExpandMS: 750, 205 206 onDragStart: function (node) { 207 return node.data.title !== "Experiment"; 208 }, 209 onDragEnter: function (node, sourceNode) { 210 return true; 211 }, 212 onDragOver: function (node, sourceNode, hitMode) { 213 return node.data.title !== "Experiment" || hitMode === "over"; 214 }, 215 onDrop: function (node, sourceNode, hitMode, ui, draggable) { 216 if (sourceNode) { 217 sourceNode.move(node, hitMode); 218 } 219 else { 220 newNode = { title: draggable.element[0].id }; 221 if (hitMode == "over") { 222 node.addChild(newNode); 223 node.expand(true); 224 } 225 else if (hitMode == "before") { 226 node.parent.addChild(newNode, node); 227 } 228 else { 229 node.parent.addChild(newNode, node.getNextSibling()); 230 } 231 } 232 }, 233 onDragLeave: function (node, sourceNode) { 234 } 235 } 236 }); 237 238 $('.dragables').each(function () { 239 $(this).draggable({ 240 revert: true, 241 connectToDynatree: true, 242 cursorAt: { top: -5, left: -5 }, 243 helper: "clone" 244 }); 245 }); 246 247 $('input[name="RemoveNode"]').click(function () { 248 var node = $("#container").dynatree("getActiveNode"); 249 if (node && node.data.title !== "Experiment") 250 node.remove(); 251 $(this).attr("disabled", "disabled"); 252 }); 253 } 254 255 function leaveStep(obj) { 256 var stepNum = obj.attr("rel"); 257 return validateStep(stepNum); 258 } 259 260 function validateStep(stepNum) { 261 var isStepValid = true; 262 if (stepNum == 1) { 263 previousWizards = {} 264 experiment = new Experiment(); 265 var data = $("#container").dynatree("getTree").toDict().children; 266 $("#container2").dynatree({ 267 onActivate: editElement 268 }); 269 var rootNode = $("#container2").dynatree("getRoot"); 270 rootNode.removeChildren(); 271 rootNode.addChild(data); 272 // based on the data rebuild the experiment 273 experiment.buildAndStore(data[0], 0, $("#container2").dynatree("getTree")); 274 } 275 return isStepValid; 276 } 277 278 function resetDialog() { 279 var canvas = $('#parameter-dialog-content'); 280 canvas.empty(); 281 $('<img />').attr('alt', 'Loading animation').attr('src', '@Url.Content("~/Content/ajax-loader.gif")').attr('class', 'loader').appendTo(canvas); 282 $('<div />').text("Loading...").appendTo(canvas); 283 } 284 285 globalCounter = 0; 286 287 function replaceWizard(result) { 288 var canvas = $('#parameter-dialog-content'); 289 canvas.empty(); 290 291 // get parameters as div 292 var algoParamsDiv = null; 293 294 if (result.Algorithm.Parameters) { 295 algoParamsDiv = createParamterDiv("Algorithm Parameters", result.Algorithm.Parameters.Items); 296 } 297 298 var problemParamsDiv = null; 299 if (result.Algorithm.Problem && result.Algorithm.Problem.Parameters) { 300 problemParamsDiv = createParamterDiv("Problem Parameters", result.Algorithm.Problem.Parameters.Items); 301 } 302 303 var wizard = null; 304 if (result.Algorithm.Problem) 305 wizard = createWizard("TestWizard", [ 306 { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoParamsDiv }, 307 { heading: "Problem Parameters", description: "Adjust problem parameters", content: problemParamsDiv } 308 ]); 309 else 310 wizard = createWizard("TestWizard", [ 311 { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoParamsDiv } 312 ]); 313 314 wizard.appendTo(canvas); 315 $(".wizard", canvas).smartWizard({ 316 onFinish: saveParameters, 317 labelFinish: 'Save' 318 }); 319 return wizard; 320 } 321 322 function editElement(node) { 323 resetDialog(); 324 $("#params").dialog("open"); 325 // if we opened this windows before, use the previously created wizard 326 if (node.data.key in previousWizards) { 327 var canvas = $('#parameter-dialog-content'); 328 canvas.empty(); 329 $(previousWizards[node.data.key]).appendTo(canvas); 330 var wiz = $(".wizard", canvas).smartWizard({ 331 onFinish: saveParameters, 332 labelFinish: 'Save' 333 }); 334 // we have to recreate the wizard, otherwise it is not responsive -> remove some multiple occuring wizard elements. 335 var parent = $('.stepContainer.content', wiz).parent('.stepContainer:not(.content)'); 336 var elem = $('.stepContainer.content .content', wiz).detach(); 337 elem.appendTo(parent); 338 $('.stepContainer.content', wiz).detach(); 339 $('.actionBar.content', wiz).detach(); 340 } 341 else { 342 $.ajax({ 343 type: "GET", 344 url: '/Experiment/GetParameters', 345 data: { scenario: node.data.title, context: experiment.nodeMapping[node.data.key].context, index: treeIndexOf(node) }, 346 contentType: "application/json; charset=utf-8", 347 dataType: "json", 348 success: function (result) { 349 if (result.Type == "Complex") $("#params").dialog("close"); 350 /*if (result.Type == "Complex") { 351 // extend the tree element 352 $("#params").dialog("close"); 353 node.removeChildren(); 354 for (var i=0; i < result.Subnames.length; i++) { 355 // add node to dynatree 356 var childNode = node.addChild({title: result.Subnames[i]}); 357 // add node to model 358 experiment.pushNode(node.data.key, childNode.data.key, result.Subnames[i], node.data.title); 359 } 360 } else*/ 361 if (result.Type == "Basic") { 362 // replace the wizard 363 previousWizards[node.data.key] = replaceWizard(result); 364 saveParameters(previousWizards[node.data.key], node); 365 } 366 } 367 }); 368 } 369 } 370 371 $(document).ready(function () { 372 var wiz = $(".wizard").smartWizard({ 373 /*updateHeight: false*/ 374 onLeaveStep: leaveStep, 375 onFinish: saveExperiment 376 }); 377 makeTree(); 378 379 $("#params").dialog({ 380 autoOpen: false, 381 width: 1024, 382 height: 768, 383 /*modal: true, 384 buttons: { 385 "Save parameters": function () { 386 387 } 388 , 389 "Cancel": function () { 390 $(this).dialog("close"); 391 } 392 }, 393 close: function () { 394 }*/ 395 }); 396 397 $("#status-dialog").dialog({ 398 autoOpen: false, 399 resizable: false, 400 height: 100, 401 modal: true, 402 buttons: { "OK" : function() { $(this).dialog('close'); $('.buttonFinish').removeAttr('disabled'); } } 403 }); 404 405 $('#runImmediately').change( 406 function() { 407 if ($(this).is(':checked')) { 408 $('#repititions').removeAttr('disabled'); 409 $('#group').removeAttr('disabled'); 410 } 411 else { 412 $('#repititions').attr('disabled', 'disabled'); 413 $('#group').attr('disabled', 'disabled'); 414 } 415 }); 416 }); 417 </script> 99 </script> 100 <noscript> 101 <p>You need JavaScript to view this page! Please activate it in your browser settings.</p> 102 </noscript> 418 103 419 104 <h2>Experiment</h2> 420 105 421 <div class="wizard swMain">106 <div id="stepWizard" class="wizard swMain"> 422 107 <ul> 423 108 <li> … … 450 135 </ul> 451 136 <div id="step1"> 452 @using (Html.BeginForm("TreeData", "Tree"))453 {454 137 <fieldset> 455 138 <div> 456 139 <p>Experiment Tree:</p> 457 140 </div> 458 459 <div id="container" class="treeStyle"> 460 <ul> 461 <li id="root">Experiment</li> 462 </ul> 463 </div> 464 <input style="margin-top:5px;" name="RemoveNode" type="button" value="Remove" disabled="disabled" /> 465 466 467 @if (Model.Scenarios.Count > 0) { 468 <p>Choose an algorithm:</p> 469 foreach (var scen in Model.Scenarios) { 470 <div class="dragables" id="@scen"><p>@scen</p></div> 471 } 472 <div class="clearer"/> 473 } 474 475 @if (Model.Scenarios.Count > 0) { 476 <p>Choose from your stored experiments:</p> 477 foreach (var scen in Model.Experiments) { 478 <div class="dragables" id="@scen"><p>@scen</p></div> 479 } 480 <div class="clearer"/> 481 } 482 141 <div id="container" class="treeStyle"></div> 142 <p>Choose an algorithm:</p> 143 <div id="algorithms"></div> 144 <div class="clearer"></div> 145 <p>Choose from your stored experiments:</p> 146 <div id="experiments"></div> 483 147 </fieldset> 484 }485 148 </div> 486 149 <div id="step2"> 487 <h2>Click on a experiment to adjust its parameters:</h2> 488 <div id="container2" class="treeStyle"> 489 <ul> 490 <li>Experiment</li> 491 </ul> 492 </div> 150 <h2>Click on a experiment to adjust its parameters:</h2> 151 <div id="container2" class="treeStyle"></div> 493 152 </div> 494 153 <div id="step3"> … … 524 183 <input id="group" name="Group" type="text" value="TESTAZURE" disabled="disabled" /> 525 184 </div> 526 </div> 527 </div> 528 529 <div id="status-dialog"> 530 <div> 531 Experiment has been saved! 532 </div> 533 </div> 534 535 <div id="params" title="Update parameters"> 536 <!-- Note: The content must be loaded asynchronously --> 537 <div id="parameter-dialog-content"> 538 <img src="@Url.Content("~/Content/ajax-loader.gif")" alt="Loading animation" class="loader" /> 539 Loading ... 540 </div> 541 542 </div> 185 </div> 186 </div> 187 188 <div id="parameterDialog"> 189 <div id="parameterDialog-content"> 190 </div> 191 </div> 192 193 <div id="loadingDialog"> 194 </div> 195 196 @section submenu { 197 <ul> 198 <li class="selected">@Html.ActionLink("Build", "New")</li> 199 <li>@Html.ActionLink("Edit", "NewEdit")</li> 200 <li>@Html.ActionLink("Status", "Index", "Status")</li> 201 </ul> 202 }
Note: See TracChangeset
for help on using the changeset viewer.