Network-Customelement/jira_graph.twig
2024-08-09 21:56:32 +02:00

216 lines
6.5 KiB
Twig

<!doctype html>
<html>
<head>
<title>Jira Graph</title>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v3.js"></script>
<script src="jsnetworkx.js"></script>
<script>
function simulateClick(control) {
if (document.all) {
control.click();
} else {
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window, 1, 12, 345, 7, 220, false, false, true, false, 0, null );
control.dispatchEvent(evObj);
}
}
</script>
</head>
<body style="font-family: Arial; background-color: black; color: white; height: 890px;">
{% for k, v in issues.items() %}
<div id="{{ k }}_state" style="display: none;">{{ v['state'] }}</div>
{% endfor %}
{% for k, v in issues.items() %}
<div id="{{ k }}_summary" style="display: none;">{{ v['summary'] }}</div>
{% endfor %}
{% for k, v in issues.items() %}
<div id="{{ k }}_description" style="display: none;">{{ v['description'] }}</div>
{% endfor %}
{% for k, v in issues.items() %}
<div id="{{ k }}_type" style="display: none;">{{ v['type'] }}</div>
{% endfor %}
<div style="width: 450px; float: right;">
<div>
<input type="text" id="search">
<button onclick="simulateClick(document.getElementById('node-' + document.getElementById('search').value));">Search</button>
</div>
<br>
<div style="display: flex;">
<table style="table-layout: fixed">
<thead>
<tr>
<th>Issue type(Nodes)</th>
</tr>
</thead>
<tbody>
{% for k, v in issue_colors.items() %}
<tr>
<td>{{ k }}</td>
<td style="width: 20px; background-color:{{ v }};" title="{{ v }}">
<!--<input type="color" value="{{ v }}">-->
</td>
</tr>
{% endfor %}
</tbody>
</table>
<table style="table-layout: fixed; float: right;">
<thead>
<tr>
<th>Link type(Edges)</th>
</tr>
</thead>
<tbody>
{% for k, v in link_colors.items() %}
<tr>
<td>{{ k }}</td>
<td style="width: 20px; background-color:{{ v }};" title="{{ v }}"></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<br>
<div style="width:300px; height: 350px;">
<b><span id="issue_type"></span>:<span id="issue_nr"></span>(<span style="font-size: 11pt;" id="issue_state"></span>)</b>
<br>
<br>
<b>Summary</b>
<br>
<br>
<div id="summary"></div>
<br>
<b>Description</b>
<br>
<br>
<div id="description"></div>
</div>
</div>
<div id="graph" style="background-color: darkblue; height: 100%; width: 1400px;"></div>
<script>
let G = new jsnx.MultiDiGraph();
G.addNodesFrom([
{% for k, v in issues.items() %}
[ {{ k }}, { radius: {{ v['radius'] }}, color: "{{ v['color'] }}"} ],
{% endfor %}
], {color: 'black'} );
G.addEdgesFrom([
{% for d in connections %}
[{{ d['start'] }}, {{ d['end'] }}, {color: "{{d['color']}}"}],
{% endfor %}
], {color: 'black'} );
jsnx.draw(G, {
element: '#graph',
//weighted: true,
withLabels: true,
labelStyle: {fill: 'white'},
edgeStyle: {
'stroke-width': 5,
fill: function(d) {
//stroke: function(d) {
//console.log(d.data.color);
//console.log(d.data[0]);
return d.data[0].color;// || 'red';
//return d.data.color
//return "red";
}
},
nodeStyle: {
fill: function(d) {
//hsl({link_hue_values[link.type.name]},100%,50%)
return d.data.color;
}
},
nodeAttr: {
r: function(d) {
// `d` has the properties `node`, `data` and `G`
return d.data.radius | 10;
}
}
});
//add ids
d3.selectAll('.node').each(function(d, i){
d3.select(this).attr('id', "node-" + d.node);
});
d3.selectAll('.edge').each(function(d, i){
d3.select(this).attr('id', "edge-" + d.edge[0] + "-" + d.edge[1]);
});
function highlight_nodes(d, on, active_color="#f00", ignore_color="#000") {
let node = d.node;
let neighbours = d.G.neighbors(d.node);
let n = d3.select('#node-' + node);
let circle_ele = n[0][0].children[0];
circle_ele.style["fill"] = on ? active_color : d.data.color;
d.G.nodes(true).forEach(function(t) {
let[node2, data] = t;
if(node !== node2){
let n = d3.select('#node-' + node2);
let circle_ele = n[0][0].children[0];
circle_ele.style["fill"] = on ? ignore_color : data.color;
}
});
d.G.edges(true).forEach(function(t) {
let[a, b, data] = t;
let n = d3.select('#edge-' + a + "-" + b);
let circle_ele = n[0][0].children[0];
circle_ele.style["fill"] = on ? ignore_color : data.color;
});
}
// bind event handlers
//d3.selectAll('.node').on('mouseover', function(d) {
//highlight_nodes(d.G.neighbors(d.node).concat(d.node), true);
//console.log("("+d.node+")");
//});
//d3.selectAll('.node').on('mouseout', function(d) {
//highlight_nodes(d.G.neighbors(d.node).concat(d.node), false);
//});
let focus_node = null;
d3.selectAll('.node').on('click', function(d) {
if(focus_node === d.node){
highlight_nodes(d, false);
focus_node = null;
}
else{
highlight_nodes(d, true);
focus_node = d.node;
}
document.getElementById("issue_nr").innerHTML = `<a style="color:lightblue;" target="_blank" rel="noopener noreferrer" href="https://team.breuer-gmbh.de/browse/DW-${d.node}">${d.node}</a>`;
document.getElementById("issue_type").innerHTML = document.getElementById(d.node+"_type").innerHTML;
document.getElementById("issue_state").innerHTML = document.getElementById(d.node+"_state").innerHTML;
document.getElementById("summary").innerHTML = document.getElementById(d.node+"_summary").innerHTML;
document.getElementById("description").innerHTML = document.getElementById(d.node+"_description").innerHTML;
});
</script>
</body>
</html>