App Domain Pathway Prediction (#47)

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#47
This commit is contained in:
2025-08-19 02:53:56 +12:00
parent 3308d47071
commit c3c1d4f5cf
9 changed files with 424 additions and 178 deletions

View File

@ -4,16 +4,22 @@
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
svg {
#vizdiv {
width: 100%;
height: 600px;
background: white;
}
#pwsvg {
width: 100%;
height: 100%;
color: red;
}
.link {
stroke: #999;
stroke-opacity: 0.6;
marker-end: url(#arrow);
//marker-end: url(#arrow);
}
.link_no_arrow {
@ -31,6 +37,31 @@
stroke-width: 1.5px;
}
.inside_app_domain {
fill: green;
stroke: green;
stroke-width: 1.5px;
}
.outside_app_domain {
fill: red;
stroke: red;
stroke-width: 1.5px;
}
.passes_app_domain {
stroke: green;
stroke-width: 1.5px;
stroke-opacity: 0.6;
}
.fails_app_domain {
stroke: red;
stroke-width: 1.5px;
stroke-opacity: 0.6;
}
.highlighted {
stroke: red;
stroke-width: 3px;
@ -80,8 +111,7 @@
<ul class="nav navbar-nav">
<li class="dropdown requiresWritePerm">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true"
aria-expanded="false">
aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-edit"></span>
Edit
<span class="caret"></span></a>
@ -91,11 +121,26 @@
{% endblock %}
</ul>
</li>
{% if pathway.setting.model.app_domain %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-eye-open"></span>
View
<span class="caret"></span></a>
<ul id="editingList" class="dropdown-menu">
<li>
<a class="button" id="app-domain-toggle-button">
<i id="app-domain-toggle-button" class="glyphicon glyphicon-eye-open"></i> App Domain View</a>
</li>
</ul>
</li>
{% endif %}
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a role="button" data-toggle="modal" onclick="goFullscreen('pwcontent')">
<a role="button" data-toggle="modal" onclick="goFullscreen('vizdiv')">
<span class="glyphicon glyphicon-fullscreen"></span>
Fullscreen
</a>
@ -126,16 +171,24 @@
</div>
</nav>
<div id="vizdiv">
<svg width="2000" height="2000">
<div id="vizdiv" >
<svg id="pwsvg">
{% if debug %}
<rect width="100%" height="100%" fill="aliceblue"/>
{% endif %}
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="43" refY="5" markerWidth="6" markerHeight="6"
orient="auto-start-reverse">
orient="auto-start-reverse" markerUnits="userSpaceOnUse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#999"/>
</marker>
<marker id="arrow_passes_app_domain" viewBox="0 0 10 10" refX="43" refY="5" markerWidth="6" markerHeight="6"
orient="auto-start-reverse" markerUnits="userSpaceOnUse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="green"/>
</marker>
<marker id="arrow_fails_app_domain" viewBox="0 0 10 10" refX="43" refY="5" markerWidth="6" markerHeight="6"
orient="auto-start-reverse" markerUnits="userSpaceOnUse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="red"/>
</marker>
</defs>
<g id="zoomable"></g>
</svg>
@ -160,7 +213,7 @@
<a id="pathwaySettingLink" data-toggle="collapse" data-parent="#pathwayAccordion"
href="#pathwaySetting">Setting</a></h4>
</div>
<div id="pathwaySetting" class="panel-collapse collapse in">
<div id="pathwaySetting" class="panel-collapse collapse">
<div class="panel-body list-group-item" id="pathwaySettingContent">
<table class="table table-bordered table-hover">
<tr style="background-color: rgba(0, 0, 0, 0.08);">
@ -246,6 +299,8 @@
</div>
</div>
<script>
// Globla switch for app domain view
var appDomainViewEnabled = false;
function goFullscreen(id) {
var element = document.getElementById(id);
@ -267,6 +322,51 @@
// TODO fix somewhere else...
var newDesc = transformReferences($('#DescriptionContent')[0].innerText);
$('#DescriptionContent').html(newDesc);
$('#app-domain-toggle-button').on('click', function () {
// glyphicon glyphicon-eye-close
// glyphicon glyphicon-eye-open
appDomainViewEnabled = !appDomainViewEnabled;
if (appDomainViewEnabled) {
$('#app-domain-toggle-button > i').removeClass('glyphicon-eye-open');
$('#app-domain-toggle-button > i').addClass('glyphicon-eye-close');
nodes.forEach((x) => {
if(x.app_domain) {
if (x.app_domain.inside_app_domain) {
d3.select(x.el).select("circle").classed("inside_app_domain", true);
} else {
d3.select(x.el).select("circle").classed("outside_app_domain", true);
}
}
});
links.forEach((x) => {
if(x.app_domain) {
if (x.app_domain.passes_app_domain) {
d3.select(x.el).attr("marker-end", d => d.target.pseudo ? "" : "url(#arrow_passes_app_domain)");
d3.select(x.el).classed("passes_app_domain", true);
} else {
d3.select(x.el).attr("marker-end", d => d.target.pseudo ? "" : "url(#arrow_fails_app_domain)");
d3.select(x.el).classed("fails_app_domain", true);
}
}
});
} else {
$('#app-domain-toggle-button > i').removeClass('glyphicon-eye-close');
$('#app-domain-toggle-button > i').addClass('glyphicon-eye-open');
nodes.forEach((x) => {
d3.select(x.el).select("circle").classed("inside_app_domain", false);
d3.select(x.el).select("circle").classed("outside_app_domain", false);
});
links.forEach((x) => {
d3.select(x.el).attr("marker-end", d => d.target.pseudo ? "" : "url(#arrow)");
d3.select(x.el).classed("passes_app_domain", false);
d3.select(x.el).classed("fails_app_domain", false);
});
}
})
});
</script>