added files
This commit is contained in:
parent
fdcb949f19
commit
670432e96e
46
dynamic_usage_example.html
Executable file
46
dynamic_usage_example.html
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>JsNetworkx Custom Element</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script src="https://d3js.org/d3.v3.js"></script>
|
||||||
|
<script src="jsnetworkx.js"></script>
|
||||||
|
<script src="widget.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<net-graph id="graph2" weighted="true" style="border-style: dotted; width:800px; height:600px;">
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
[ 1, { "radius": 5, "color": "yellow"} ],
|
||||||
|
[ 2, { "radius": 15, "color": "green"} ],
|
||||||
|
[ 3, { "radius": 25, "color": "red"} ]
|
||||||
|
],
|
||||||
|
"edges": [
|
||||||
|
[1, 2, {"color": "red"}]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</net-graph>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<net-graph id="graph" weighted="true" style="border-style: dotted; width:800px; height:600px;" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let ele = document.getElementById("graph");
|
||||||
|
|
||||||
|
let i = 10;
|
||||||
|
setInterval(()=>{
|
||||||
|
ele.G.addNode(i, { "radius": Math.floor(Math.random() * 30), "color": "red"} );
|
||||||
|
|
||||||
|
ele.G.addEdge(i - 1, i);
|
||||||
|
|
||||||
|
if(i > 20) i = -10;
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
},1000);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
216
jira_graph.twig
Normal file
216
jira_graph.twig
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
<!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>
|
8
jsnetworkx.js
Normal file
8
jsnetworkx.js
Normal file
File diff suppressed because one or more lines are too long
27
usage_example.html
Executable file
27
usage_example.html
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>My Custom Element</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script src="https://d3js.org/d3.v3.js"></script>
|
||||||
|
<script src="jsnetworkx.js"></script>
|
||||||
|
<script src="widget.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<net-graph style="border-style: dotted; width:800px; height:600px;">
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
[ 1, { "radius": 5, "color": "yellow"} ],
|
||||||
|
[ 2, { "radius": 15, "color": "green"} ],
|
||||||
|
[ 3, { "radius": 25, "color": "red"} ]
|
||||||
|
],
|
||||||
|
"edges": [
|
||||||
|
|
||||||
|
[1, 2, {"color": "red"}]
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</net-graph>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
89
widget.js
Executable file
89
widget.js
Executable file
@ -0,0 +1,89 @@
|
|||||||
|
|
||||||
|
class NetGraphElement extends HTMLElement {
|
||||||
|
|
||||||
|
static get observedAttributes() {
|
||||||
|
return ['G'];
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.attachShadow({mode: 'open'});
|
||||||
|
this.content_div = document.createElement('div');
|
||||||
|
this.shadowRoot.appendChild(this.content_div);
|
||||||
|
this.slot_ele = document.createElement('slot');
|
||||||
|
this.shadowRoot.appendChild(this.slot_ele);
|
||||||
|
this.G = new jsnx.MultiDiGraph();
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback(){
|
||||||
|
let style = this.hasAttribute('style') ? this.getAttribute('style') : "";
|
||||||
|
let weighted = this.hasAttribute('weighted') ? JSON.parse(this.getAttribute('weighted')) : false;
|
||||||
|
let withLabels = this.hasAttribute('withLabels') ? JSON.parse(this.getAttribute('withLabels')) : true;
|
||||||
|
|
||||||
|
this.content_div.style = style;
|
||||||
|
let that = this;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
jsnx.draw(that.G, {
|
||||||
|
element: that.content_div,
|
||||||
|
weighted,
|
||||||
|
withLabels,
|
||||||
|
labelStyle: {fill: 'white'},
|
||||||
|
edgeStyle: {
|
||||||
|
'stroke-width': 5,
|
||||||
|
fill: d => d.data[0].color
|
||||||
|
},
|
||||||
|
nodeStyle: {
|
||||||
|
fill: d => d.data.color
|
||||||
|
},
|
||||||
|
nodeAttr: {
|
||||||
|
r: d => d.data.radius | 10
|
||||||
|
}
|
||||||
|
}, true); //true ensures redrawing
|
||||||
|
|
||||||
|
|
||||||
|
this.slot_ele.addEventListener('slotchange', e => {
|
||||||
|
try{
|
||||||
|
let text = that.innerText.trim();
|
||||||
|
let{nodes, edges} = JSON.parse(text);
|
||||||
|
that.G.addNodesFrom(nodes, {color: 'black'} );
|
||||||
|
that.G.addEdgesFrom(edges, {color: 'black'} );
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
jsnx.draw(that.G, {
|
||||||
|
element: that.content_div,
|
||||||
|
weighted,
|
||||||
|
withLabels,
|
||||||
|
labelStyle: {fill: 'white'},
|
||||||
|
edgeStyle: {
|
||||||
|
'stroke-width': 5,
|
||||||
|
fill: d => d.data[0].color
|
||||||
|
},
|
||||||
|
nodeStyle: {
|
||||||
|
fill: d => d.data.color
|
||||||
|
},
|
||||||
|
nodeAttr: {
|
||||||
|
r: d => d.data.radius | 10
|
||||||
|
}
|
||||||
|
}, true); //true ensures redrawing
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
that.slot_ele.style.display = "none";
|
||||||
|
that.content_div.children[0].setAttribute("width", that.content_div.style.width);
|
||||||
|
that.content_div.children[0].setAttribute("height", that.content_div.style.height);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('net-graph', NetGraphElement);
|
Loading…
x
Reference in New Issue
Block a user