From 7370253244e61ff21d571052c4af191c6efe93ac Mon Sep 17 00:00:00 2001 From: Matej Trojak Date: Thu, 6 Oct 2022 21:43:56 +0200 Subject: [PATCH] Separated mako template to JS script and CSS styles --- .../visualizations/ts_visjs/package.json | 6 +- .../visualizations/ts_visjs/static/script.js | 113 ++++ .../ts_visjs/templates/ts_visjs.mako | 486 ++++++------------ 3 files changed, 258 insertions(+), 347 deletions(-) create mode 100644 config/plugins/visualizations/ts_visjs/static/script.js diff --git a/config/plugins/visualizations/ts_visjs/package.json b/config/plugins/visualizations/ts_visjs/package.json index ada8e3d8b11..3d3d7e79f75 100644 --- a/config/plugins/visualizations/ts_visjs/package.json +++ b/config/plugins/visualizations/ts_visjs/package.json @@ -3,11 +3,9 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "plotly.js": "^2.11.1", - "pca-js": "^1.0.2", - "d3": "^7.4.4" + "vis": "^4.21.0" }, "scripts": { - "build": "mkdir -p static/dist && cp node_modules/pca-js/pca.min.js node_modules/plotly.js/dist/plotly.min.js node_modules/d3/dist/d3.min.js static/dist" + "build": "mkdir -p static/dist && cp node_modules/vis/vis.min.js node_modules/vis/vis.min.css static/dist" } } diff --git a/config/plugins/visualizations/ts_visjs/static/script.js b/config/plugins/visualizations/ts_visjs/static/script.js new file mode 100644 index 00000000000..42bf5817531 --- /dev/null +++ b/config/plugins/visualizations/ts_visjs/static/script.js @@ -0,0 +1,113 @@ +var container = document.getElementById('mynetwork'); + +// data filters +hell_filter = document.getElementById('hell_node') +loops_filter = document.getElementById('loop_edges') +border_filter = document.getElementById('border_nodes') + +let noHell = false +const nodesFilter = (node) => { + if (noHell) { + return (node.class != 'hell') + } else { + return true + } +} + +var nodesView = new vis.DataView(nodes, { filter: nodesFilter }) + +// remove hell +hell_filter.addEventListener('change', (e) => { + if (hell_filter.checked){ + noHell = false + } else { + noHell = true + } + nodesView.refresh() +}); + +data = { + nodes: nodesView, + edges: edges + }; + +var network = new vis.Network(container, data, options); + +loops_filter.addEventListener('change', (e) => { + if (loops_filter.checked){ + for (index = 0; index < self_loops.length; index++) { + edges.add(self_loops[index]); + } + } else { + for (index = 0; index < self_loops.length; index++) { + edges.remove({id: self_loops[index].id}); + } + } +}); + +border_filter.addEventListener('change', (e) => { + if (border_filter.checked){ + for (index = 0; index < border_nodes.length; index++) { + nodes.update({id: border_nodes[index].id, shape: "box"}); + } + } else { + for (index = 0; index < border_nodes.length; index++) { + nodes.update({id: border_nodes[index].id, shape: "ellipse"}); + } + } +}); + +var stabil = true; + +network.on("click", function (params) { + params.event = "[original event]"; + var tmp = " "; + + + for (var i = 1; i <= nodes.length; i++) { + if (nodes.get(i).id == params.nodes) { + tmp = nodes.get(i).text; + }; + }; + + if(params.nodes.length === 0 && params.edges.length > 0) { + for (var i = 1; i <= edges.length; i++) { + if (edges.get(i).id == params.edges) { + tmp = edges.get(i).text; + }; + }; + }; + + document.getElementById('rectangle').innerHTML = '
' + tmp + '
'; +}); + +network.on("stabilized", function (params) { + if(stabil) { + network.fit(); + stabil = false; + }; +}); + +network.once("stabilizationIterationsDone", function() { + document.getElementById('text').innerHTML = '100%'; + document.getElementById('bar').style.width = '496px'; + document.getElementById('loadingBar').style.opacity = 0; + // really clean the dom element + setTimeout(function () {document.getElementById('loadingBar').style.display = 'none';}, 0); +}); + +clickedNode = nodes.get(fromNode); +clickedNode.color = { + border: 'orange', + background: 'orange', + highlight: { + border: 'orange', + background: 'orange' + } + } + nodes.update(clickedNode); + +network.on("doubleClick", function (params) { + params.event = "[original event]"; + network.focus(params.nodes); +}); diff --git a/config/plugins/visualizations/ts_visjs/templates/ts_visjs.mako b/config/plugins/visualizations/ts_visjs/templates/ts_visjs.mako index ae6be9d77b8..6893d2b17f5 100644 --- a/config/plugins/visualizations/ts_visjs/templates/ts_visjs.mako +++ b/config/plugins/visualizations/ts_visjs/templates/ts_visjs.mako @@ -7,13 +7,7 @@ from numpy import inf <% def to_counter(state, ordering): - """ - Transforms given state to Counter using given ordering - - :param state: str representation of state - :param ordering: enumeration of agents - :return: Counter representing the state - """ + """Transforms given state to Counter using given ordering.""" state = eval(state) if state[0] == inf: return inf @@ -21,36 +15,21 @@ def to_counter(state, ordering): def node_to_string(node): - """ - Creates string representation of Counter of agents. - - :param node: given Counter of agents. - :return: string representation of Counter - """ + """Creates string representation of Counter of agents.""" if node == inf: return "inf" return "
".join([str(int(v)) + " " + str(k) for k, v in node.items()]) def side_to_string(side): - """ - Another string representation of Counter, this time used as side in reaction - :param side: given Counter - :return: string representation of Counter - """ + """Another string representation of Counter, this time used as side in reaction.""" if side == inf: return "inf" return " + ".join([str(int(v)) + " " + str(k) for k, v in side.items()]) def create_sides(lhs, rhs): - """ - From given substrates and products counters creates their mutual differences - - :param lhs: dict of substrates - :param rhs: dict of products - :return: two counters representing differences - """ + """From given substrates and products counters creates their mutual differences.""" if lhs == inf: return inf, inf if rhs == inf: @@ -61,13 +40,7 @@ def create_sides(lhs, rhs): def write_node(ID, label, node_class): - """ - Creates string representation of a node - - :param ID: ID of given node - :param label: enumeration of agents - :return: string representation - """ + """Creates string representation of a node.""" if label == "inf": node_class = "hell" return "\t\t{{id: {0}, label: '{0}', class: '{2}', shape: 'ellipse', title: '{0}', text: '{1}'}},\n".format( @@ -75,32 +48,19 @@ def write_node(ID, label, node_class): def write_reaction(edge_id, left_index, right_index, substrates, products, rate, label): - """ - Creates string representation of a reaction - - :param edge_id: ID of given reaction - :param left_index: ID of FROM node - :param right_index: ID of TO node - :param substrates: enumeration of substrates - :param products: enumeration of products - :param rate: rate of the reaction (if any) - :param label: used rule label - :return: string representation - """ + """Creates string representation of a reaction.""" rate = " @ " + str(rate) if rate else "" label = label + " ~ " if label else "" return "\t\t{{id: {}, from: {}, to: {}, arrows: 'to', text: '{}{} => {}{}'}},\n".format( edge_id, left_index, right_index, label, side_to_string(substrates), side_to_string(products), rate) -def create_HTML_graph(): #data): - output_file = firstpart +def load_data(): + output = dict() data = ''.join(list(hda.datatype.dataprovider(hda, 'line', strip_lines=True, strip_newlines=True))) data = json.loads(data) - # data = json.load(data) - ordering = data['ordering'] nodes = {int(key): to_counter(data['nodes'][key], ordering) for key in data['nodes'].keys()} @@ -118,6 +78,8 @@ def create_HTML_graph(): #data): if products == inf and substrates != inf: border_nodes.add(edge['s']) + output["nodes"] = "" + border_nodes_write = [] for id, state in nodes.items(): if id in border_nodes: @@ -125,338 +87,176 @@ def create_HTML_graph(): #data): border_nodes_write.append((id, node_to_string(state), node_class)) else: node_class = "default" - output_file += write_node(id, node_to_string(state), node_class) + output["nodes"] += write_node(id, node_to_string(state), node_class) - output_file += mid_1 + output["border_nodes"] = "" for node in border_nodes_write: - output_file += write_node(*node) + output["border_nodes"] += write_node(*node) - output_file += mid_2 + output["edges"] = "" for edge in edges: - output_file += write_reaction(*edge) + output["edges"] += write_reaction(*edge) - output_file += mid_3 + output["self_loops"] = "" for edge in self_loops: - output_file += write_reaction(*edge) + output["self_loops"] += write_reaction(*edge) initial = data['initial'] iterations = (len(nodes)//100+1) * 100 step = iterations//100 - output_file += secondpart_1_1 - output_file += stabil_physics.format(iterations, step) - output_file += secondpart_1_2 - - output_file += "\tvar fromNode = " + str(int(initial)) + ";\n" - - output_file += secondpart_2_1 - output_file += stabil_bar.format(iterations, step) - output_file += secondpart_2_2 - return output_file + output["step"] = step + output["iterations"] = iterations + output["fromNode"] = str(int(initial)) + return output -firstpart = \ -''' +root = h.url_for("/static/") +app_root = root + "plugins/visualizations/ts_visjs/static/" +output = load_data() +%> + +## ---------------------------------------------------------------------------- + + TS network visualisation ${h.javascript_link(app_root + "dist/vis.min.js")} - # da sa to? ${h.stylesheet_link(app_root + "dist/vis.min.css")} ${h.stylesheet_link(app_root + "style.css")} - - + + + ${h.javascript_link(app_root + "script.js")} + + + +
-
+ - +
-
-
+
0%
-
- - +
-''' - -stabil_physics = \ -''' iterations: {}, - updateInterval: {} -''' - -stabil_bar = \ -''' var iterations = {}; - var updateInterval = {}; -''' - -# for testing -# filename = open('bigger_pMC.json', "r") -# graph = create_HTML_graph(filename) - -graph = create_HTML_graph() -%> - -${graph}