Current Dev State

This commit is contained in:
Tim Lorsbach
2025-06-23 20:13:54 +02:00
parent b4f9bb277d
commit ded50edaa2
22617 changed files with 4345095 additions and 174 deletions

217
static/js/epp/epp.js Normal file
View 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);
}
}

View 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
View 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);
}
});
}