216 lines
6.5 KiB
Twig
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> |