forked from enviPath/enviPy
Current Dev State
This commit is contained in:
217
static/js/epp/epp.js
Normal file
217
static/js/epp/epp.js
Normal file
@ -0,0 +1,217 @@
|
||||
class Setting {
|
||||
constructor(nameInputId, selectedPackagesId, relativeReasoningSelectId, cutoffInputId, evaluationTypeSelectId,
|
||||
availableTSSelectId, formsId, tableId, summaryTableId) {
|
||||
this.nameInputId = nameInputId;
|
||||
this.selectedPackagesId = selectedPackagesId;
|
||||
this.relativeReasoningSelectId = relativeReasoningSelectId;
|
||||
this.cutoffInputId = cutoffInputId;
|
||||
this.evaluationTypeSelectId = evaluationTypeSelectId;
|
||||
this.availableTSSelectId = availableTSSelectId;
|
||||
this.formsId = formsId;
|
||||
this.tableId = tableId;
|
||||
this.summaryTableId = summaryTableId;
|
||||
|
||||
// General settings
|
||||
this.name = null;
|
||||
this.selectedPackages = [];
|
||||
|
||||
// Relative Reasoning related
|
||||
this.selectedRelativeReasoning = null;
|
||||
this.cutoff = null;
|
||||
this.evaluationType = null;
|
||||
|
||||
// parameters such as { "lowPH": 7, "highPH": 8 }
|
||||
this.tsParams = {};
|
||||
}
|
||||
|
||||
extractName() {
|
||||
var tempName = $('#' + this.nameInputId).val()
|
||||
if (tempName == '') {
|
||||
console.log("Name was empty...");
|
||||
return;
|
||||
}
|
||||
this.name = tempName;
|
||||
}
|
||||
|
||||
extractSelectedPackages() {
|
||||
var selPacks = $("#" + this.selectedPackagesId + " :selected");
|
||||
var ref = this;
|
||||
ref.selectedPackages = [];
|
||||
selPacks.each(function () {
|
||||
var obj = {}
|
||||
obj['id'] = this.value;
|
||||
obj['name'] = this.text;
|
||||
ref.selectedPackages.push(obj);
|
||||
});
|
||||
}
|
||||
|
||||
extractRelativeReasoning() {
|
||||
var tempRR = $('#' + this.relativeReasoningSelectId + " :selected").val()
|
||||
if (tempRR == '') {
|
||||
console.log("RR was empty...");
|
||||
return;
|
||||
}
|
||||
var obj = {}
|
||||
obj['id'] = $('#' + this.relativeReasoningSelectId + " :selected").val()
|
||||
obj['name'] = $('#' + this.relativeReasoningSelectId + " :selected").text()
|
||||
this.selectedRelativeReasoning = obj;
|
||||
}
|
||||
|
||||
extractCutoff() {
|
||||
var tempCutoff = $('#' + this.cutoffInputId).val()
|
||||
if (tempCutoff == '') {
|
||||
console.log("Cutoff was empty...");
|
||||
return;
|
||||
}
|
||||
this.cutoff = tempCutoff;
|
||||
}
|
||||
|
||||
extractEvaluationType() {
|
||||
var tempEvaluationType = $('#' + this.evaluationTypeSelectId).val()
|
||||
if (tempEvaluationType == '') {
|
||||
console.log("EvaluationType was empty...");
|
||||
return;
|
||||
}
|
||||
this.evaluationType = tempEvaluationType;
|
||||
}
|
||||
|
||||
addTruncator() {
|
||||
// triggered by "Add"
|
||||
// will extract values and afterwards updates table + summary
|
||||
var type = $("#" + this.availableTSSelectId + " :selected").val();
|
||||
var text = $("#" + this.availableTSSelectId + " :selected").text();
|
||||
var form = $("#" + type + "_form > :input")
|
||||
|
||||
// flag to check whether at least one input had a valid value
|
||||
var addedValue = false;
|
||||
|
||||
// reference being used in each
|
||||
var ref = this;
|
||||
|
||||
form.each(function() {
|
||||
if(this.value == "" || this.value === "undefined"){
|
||||
console.log(this);
|
||||
console.log("Skipping " + this.name);
|
||||
} else {
|
||||
var obj = {}
|
||||
obj[this.name] = this.value;
|
||||
obj['text'] = text;
|
||||
ref.tsParams[type] = obj
|
||||
}
|
||||
});
|
||||
|
||||
this.updateTable();
|
||||
this.updateSummaryTable();
|
||||
}
|
||||
|
||||
removeTruncator(rowId) {
|
||||
var summary = rowId.startsWith("sum") ? true : false;
|
||||
// plain key
|
||||
var key = rowId.replace(summary ? "sum" : "trunc", "").replace("row", "");
|
||||
|
||||
console.log("Removing " + key);
|
||||
|
||||
// remove the rows
|
||||
$("#trunc"+ key + "row").remove();
|
||||
if($("#sum"+ key + "row").length > 0) {
|
||||
$("#sum"+ key + "row").remove();
|
||||
}
|
||||
|
||||
delete this.tsParams[key];
|
||||
}
|
||||
|
||||
updateTable() {
|
||||
// remove all children
|
||||
$('#'+this.tableId + "Body").empty()
|
||||
|
||||
var innerHTML = "<tr>" +
|
||||
"<td>Name</td>" +
|
||||
"<td>Value</td>" +
|
||||
"<td width='10%'>Action</td>" +
|
||||
"</tr>";
|
||||
|
||||
for (var x in this.tsParams) {
|
||||
var val = "";
|
||||
for (var y in this.tsParams[x]){
|
||||
if (y == 'text') {
|
||||
continue;
|
||||
}
|
||||
val += this.tsParams[x][y]
|
||||
|
||||
}
|
||||
innerHTML += "<tr id='trunc" + x + "row'>" +
|
||||
"<td>" + this.tsParams[x]['text'] + "</td>" +
|
||||
"<td>" + val + "</td>" +
|
||||
"<td width='10%'>"+
|
||||
"<button type='button' id='" + x + "button' class='form-control' onclick='s.removeTruncator(\"trunc" + x + "row\")'>Remove</button>" +
|
||||
"</td>" +
|
||||
"</tr>";
|
||||
}
|
||||
|
||||
$('#'+this.tableId + "Body").append(innerHTML);
|
||||
}
|
||||
|
||||
packageRows() {
|
||||
var res = '';
|
||||
for(var p in this.selectedPackages) {
|
||||
var obj = this.selectedPackages[p];
|
||||
res += "<tr>" +
|
||||
"<td>Package</td>" +
|
||||
"<td>" + obj['name'] + "</td>" +
|
||||
"<td width='10%'>" +
|
||||
// "<button type='button' id='relativereasoningbutton' class='form-control' onclick='s.removeTruncator(\"Relative Reasoning\")'>Remove</button>" +
|
||||
"</td>" +
|
||||
"</tr>";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
modelRow() {
|
||||
if(this.selectedRelativeReasoning == null) {
|
||||
return '';
|
||||
}
|
||||
return "<tr>" +
|
||||
"<td>Relative Reasoning</td>" +
|
||||
"<td>" + this.selectedRelativeReasoning['name'] + " " + (this.evaluationType == "singleGen" ? "SG" : "MG") + " with t=" + this.cutoff + " </td>" +
|
||||
"<td width='10%'>" +
|
||||
// "<button type='button' id='relativereasoningbutton' class='form-control' onclick='s.removeTruncator(\"Relative Reasoning\")'>Remove</button>" +
|
||||
"</td>" +
|
||||
"</tr>";
|
||||
}
|
||||
|
||||
updateSummaryTable() {
|
||||
// remove all children
|
||||
$('#'+this.summaryTableId + "Body").empty()
|
||||
|
||||
var innerHTML = "<tr>" +
|
||||
"<td>Name</td>" +
|
||||
"<td>Value</td>" +
|
||||
"<td width='10%'>Action</td>" +
|
||||
"</tr>";
|
||||
|
||||
innerHTML += this.packageRows();
|
||||
innerHTML += this.modelRow();
|
||||
|
||||
// var innerHTML = ''
|
||||
for (var x in this.tsParams) {
|
||||
var val = "";
|
||||
for (var y in this.tsParams[x]){
|
||||
if (y == 'text') {
|
||||
continue;
|
||||
}
|
||||
val += this.tsParams[x][y]
|
||||
|
||||
}
|
||||
innerHTML += "<tr id='sum" + x + "row'>" +
|
||||
"<td>" + this.tsParams[x]['text'] + "</td>" +
|
||||
"<td>" + val + "</td>" +
|
||||
"<td width='10%'>"+
|
||||
"<button type='button' id='" + x + "button' class='form-control' onclick='s.removeTruncator(\"sum" + x + "row\")'>Remove</button>" +
|
||||
"</td>" +
|
||||
"</tr>";
|
||||
}
|
||||
|
||||
$('#'+this.summaryTableId + "Body").append(innerHTML);
|
||||
}
|
||||
|
||||
}
|
||||
1
static/js/epp/jquery-bootstrap-modal-steps.js
vendored
Normal file
1
static/js/epp/jquery-bootstrap-modal-steps.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
!function(t){"use strict";t.fn.modalSteps=function(a){var e=this,n=t.extend({btnCancelHtml:"Cancel",btnPreviousHtml:"Previous",btnNextHtml:"Next",btnLastStepHtml:"Complete",disableNextButton:!1,completeCallback:function(){},callbacks:{},getTitleAndStep:function(){}},a),d=function(t){return void 0!==t&&"function"==typeof t&&(t(),!0)};return e.on("show.bs.modal",function(){var a,l,s,i=e.find(".modal-footer"),o=i.find(".js-btn-step[data-orientation=cancel]"),p=i.find(".js-btn-step[data-orientation=previous]"),r=i.find(".js-btn-step[data-orientation=next]"),c=n.callbacks["*"],b=n.callbacks[1];n.disableNextButton&&r.attr("disabled","disabled"),p.attr("disabled","disabled"),function(){var t=n.callbacks["*"];if(void 0!==t&&"function"!=typeof t)throw"everyStepCallback is not a function! I need a function";if("function"!=typeof n.completeCallback)throw"completeCallback is not a function! I need a function";for(var a in n.callbacks)if(n.callbacks.hasOwnProperty(a)){var e=n.callbacks[a];if("*"!==a&&void 0!==e&&"function"!=typeof e)throw"Step "+a+" callback must be a function"}}(),d(c),d(b),o.html(n.btnCancelHtml),p.html(n.btnPreviousHtml),r.html(n.btnNextHtml),a=t("<input>").attr({type:"hidden",id:"actual-step",value:"1"}),e.find("#actual-step").remove(),e.append(a),e.find("[data-step=1]").removeClass("d-none"),r.attr("data-step",2),l=e.find("[data-step=1]").data("title"),s=t("<span>").addClass("label label-success").html(1),e.find(".js-title-step").append(s).append(" "+l),n.getTitleAndStep(a.attr("data-title"),1)}).on("hidden.bs.modal",function(){var t=e.find("#actual-step"),a=e.find(".js-btn-step[data-orientation=next]");e.find("[data-step]").not(e.find(".js-btn-step")).addClass("d-none"),t.not(e.find(".js-btn-step")).remove(),a.attr("data-step",1).html(n.btnNextHtml),e.find(".js-title-step").html("")}),e.find(".js-btn-step").on("click",function(){var a,l,s,i,o=t(this),p=e.find("#actual-step"),r=e.find(".js-btn-step[data-orientation=previous]"),c=e.find(".js-btn-step[data-orientation=next]"),b=e.find(".js-title-step"),f=o.data("orientation"),u=parseInt(p.val()),m=n.callbacks["*"];if(a=e.find("div[data-step]").length,"complete"===o.attr("data-step"))return n.completeCallback(),void e.modal("hide");if("next"===f)l=u+1,r.attr("data-step",u),p.val(l);else{if("previous"!==f)return void e.modal("hide");l=u-1,c.attr("data-step",u),r.attr("data-step",l-1),p.val(u-1)}parseInt(p.val())===a?c.attr("data-step","complete").html(n.btnLastStepHtml):c.attr("data-step",l).html(n.btnNextHtml),n.disableNextButton&&c.attr("disabled","disabled"),e.find("[data-step="+u+"]").not(e.find(".js-btn-step")).addClass("d-none"),e.find("[data-step="+l+"]").not(e.find(".js-btn-step")).removeClass("d-none"),parseInt(r.attr("data-step"))>0?r.removeAttr("disabled"):r.attr("disabled","disabled"),"previous"===f&&c.removeAttr("disabled"),(s=e.find("[data-step="+l+"]")).attr("data-unlock-continue")&&c.removeAttr("disabled"),i=s.attr("data-title");var v=t("<span>").addClass("label label-success").html(l);b.html(v).append(" "+i),n.getTitleAndStep(s.attr("data-title"),l);var h=n.callbacks[p.val()];d(m),d(h)}),this}}(jQuery);
|
||||
191
static/js/epp/pathway.js
Normal file
191
static/js/epp/pathway.js
Normal file
@ -0,0 +1,191 @@
|
||||
// drawarea
|
||||
var svg;
|
||||
|
||||
// colors
|
||||
var border = "thin solid lightgrey";
|
||||
|
||||
|
||||
// nodes
|
||||
|
||||
|
||||
// links
|
||||
|
||||
// tree
|
||||
var compoundSize = 75; // = diameter of nodes of small compounds
|
||||
var maxCompoundSize = function(){ return 1.5 * compoundSize }; // limit increased size of larger compounds
|
||||
var maxCompoundPopupSize = function(){ return 5 * compoundSize };
|
||||
var compoundImageMargin = 0.15; // compounds images are rectangles, reduce size to fit into nodes
|
||||
|
||||
var treeLayoutLinkDistance = function(){ return 2.5 * compoundSize };
|
||||
var treeLayoutCharge = -1000; // compounds push each other apart
|
||||
var treeLayoutPseudoCharge = treeLayoutCharge * 0.1; // relaxes forces on pseudo nodes
|
||||
var treeLayoutLevelGravity = 0.5; // pulls compounds back to their depth level
|
||||
var treeLayoutXCenterGravity = 0.03; // pulls compounds to x center
|
||||
var treeLayoutLevels = function(){ return treeLayoutLinkDistance() }; // distance between depth levels
|
||||
var treeLayoutXInitMargin = function(){ return treeLayoutLinkDistance() }; // initial x-distance between nodes of same depth
|
||||
|
||||
|
||||
// Convenience method to check wether a given node is a leaf
|
||||
function isLeaf(node) {
|
||||
return node.children.length == 0;
|
||||
}
|
||||
|
||||
function getMaxNodeDepth(graph) {
|
||||
maxDepth = 0
|
||||
graph.nodes.forEach(function(node, i) {
|
||||
if (node.depth > maxDepth)
|
||||
maxDepth = node.depth;
|
||||
});
|
||||
return maxDepth;
|
||||
}
|
||||
|
||||
// adds a parents[] and a children[] array for each node set treeSize
|
||||
function setChildrenAndParents(graph) {
|
||||
// Init arrays on each node
|
||||
graph.nodes.forEach(function(node, i) {
|
||||
node.parents = []
|
||||
node.children = []
|
||||
});
|
||||
|
||||
// loop through links, determine source and target and populate
|
||||
// their parent/children arrays
|
||||
graph.links.forEach(function(link, j) {
|
||||
source = graph.nodes[link.source];
|
||||
target = graph.nodes[link.target];
|
||||
source.children.push(target);
|
||||
target.parents.push(source);
|
||||
});
|
||||
|
||||
// Recursively traverses the tree to count the nodes that can be reached
|
||||
function count(node) {
|
||||
node.touch = true;
|
||||
c = 1;
|
||||
node.children.forEach(function(child, i) {
|
||||
if (!child.touch) {
|
||||
c += count(child);
|
||||
}
|
||||
});
|
||||
node.count = false;
|
||||
return c;
|
||||
}
|
||||
|
||||
// Check how many nodes can be reached from each given node
|
||||
// by traversing the children property
|
||||
graph.nodes.forEach(function(node, i) {
|
||||
// reset touch on all nodes
|
||||
graph.nodes.forEach(function(n, i) {
|
||||
n.touch = false;
|
||||
});
|
||||
// get count
|
||||
node.downstreamNodeCount = count(node);
|
||||
});
|
||||
|
||||
// determine siblings for each links
|
||||
graph.links.forEach(function(link, j) {
|
||||
p = graph.nodes[link.source].children.length;
|
||||
c = graph.nodes[link.target].parents.length;
|
||||
link.siblings = Math.max(p, c);
|
||||
});
|
||||
}
|
||||
|
||||
// sets all links to pseudo that are connected to a pseudo node
|
||||
function setPseudoLinks(graph) {
|
||||
graph.links.forEach(function(link, j) {
|
||||
if (graph.nodes[link.source].pseudo || graph.nodes[link.target].pseudo) {
|
||||
link.pseudo = true;
|
||||
} else {
|
||||
link.pseudo = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function redraw() {
|
||||
svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
|
||||
}
|
||||
|
||||
function reset() {
|
||||
// remove all;
|
||||
svg.selectAll("g.node").remove();
|
||||
svg.selectAll("rect").remove();
|
||||
svg.selectAll("image").remove();
|
||||
svg.selectAll("line").remove();
|
||||
svg.selectAll("marker").remove();
|
||||
svg.selectAll("text").remove();
|
||||
svg.selectAll("g").remove();
|
||||
svg.selectAll("defs").remove();
|
||||
//start(__graph);
|
||||
}
|
||||
|
||||
function _drawPathway(elem, graph, options) {
|
||||
width = document.getElementById(elem).offsetWidth;
|
||||
height = width * 0.75;
|
||||
|
||||
svg = d3.select("#" + elem)
|
||||
.append("svg")
|
||||
.attr("width", "100%")
|
||||
.attr("height", height)
|
||||
.style("border", border)
|
||||
.attr("inline", "block")
|
||||
.attr("margin", "auto")
|
||||
.attr("pointer-events", "all")
|
||||
.append('svg:g')
|
||||
.call(d3.behavior.zoom().on("zoom", redraw))
|
||||
.attr("preserveAspectRatio", "xMidYMid meet")
|
||||
.append('svg:g');
|
||||
|
||||
// Background rectangle to enable zoom function
|
||||
// even cursor is not on a node or path
|
||||
svg.append('svg:rect')
|
||||
.attr('width', 9 * width)
|
||||
.attr('height', 9 * height)
|
||||
.attr('fill', 'white')
|
||||
.attr("x", -4 * width)
|
||||
.attr("y", -4 * height)
|
||||
.attr("opacity", 0.0);
|
||||
|
||||
setChildrenAndParents(graph)
|
||||
setPseudoLinks(graph)
|
||||
var maxDepths = getMaxNodeDepth(graph);
|
||||
|
||||
// if(options.treeLayout) {
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// }
|
||||
force = d3.layout.force()
|
||||
.charge(function(d) {
|
||||
if (d.pseudo) {
|
||||
return treeLayoutPseudoCharge;
|
||||
} else {
|
||||
return treeLayoutCharge;
|
||||
}
|
||||
})
|
||||
.gravity(0)
|
||||
.linkDistance(function(d) {
|
||||
dist = Math.abs(d.target.treeLevel - d.source.treeLevel) * treeLayoutLinkDistance();
|
||||
if (dist == 0) {
|
||||
// nodes with depth in brackets: A (0) -> B (1) + C (2)
|
||||
// then there is a pseudo node that is on the same level as B
|
||||
dist = 0.5 * treeLayoutLinkDistance();
|
||||
}
|
||||
return dist;
|
||||
})
|
||||
.linkStrength(function(d) {
|
||||
return strength = 1 / d.siblings;
|
||||
})
|
||||
.size([width, height]);
|
||||
|
||||
force.nodes(graph.nodes).links(graph.links).start();
|
||||
|
||||
}
|
||||
|
||||
function drawPathway(elem, options) {
|
||||
|
||||
d3.json("", function(error, graph) {
|
||||
if (graph) {
|
||||
_drawPathway(elem, graph, options);
|
||||
} else {
|
||||
throw new Error("Graph not defined: " + error);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user