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