diff --git a/tools/mkdocs/generator.py b/tools/mkdocs/generator.py index e993aee..ef144b5 100644 --- a/tools/mkdocs/generator.py +++ b/tools/mkdocs/generator.py @@ -93,7 +93,6 @@ class Galaxy(): self.entry += f' |{author}|\n' def _create_clusters(self): - # global public_clusters_dict clusters = [] for cluster in self.cluster_list: clusters.append(Cluster( @@ -195,18 +194,11 @@ class Cluster(): self.entry += f'\n' self.entry += f'??? info "Associated metadata"\n' self.entry += f'\n' - self.entry += f'
\n' - self.entry += f' \n' self.entry += f' |Metadata key {{ .no-filter }} |Value|\n' self.entry += f' |-----------------------------------|-----|\n' for meta in sorted(self.meta.keys()): if meta not in excluded_meta: self.entry += f' | {meta} | {self.meta[meta]} |\n' - # self.entry += " {: .no-filter }\n" - self.entry += f' \n' - self.entry += f'
\n' - self.entry += f'\n' - def get_related_clusters(self, cluster_dict, depth=-1, visited=None, level=1): global public_relations_count diff --git a/tools/mkdocs/site/docs/javascripts/d3.js b/tools/mkdocs/site/docs/javascripts/d3.js index 9ced2fc..1088cea 100644 --- a/tools/mkdocs/site/docs/javascripts/d3.js +++ b/tools/mkdocs/site/docs/javascripts/d3.js @@ -1,28 +1,43 @@ document$.subscribe(function () { // Function to parse table and return data - function parseTable(table) { + // function parseTable(table) { + // var data = []; + // var rows = table.querySelectorAll("tr"); + // rows.forEach((row, i) => { + // // Skipping header row and filter row + // if (i > 1) { + // var cells = row.querySelectorAll("td"); + // data.push({ source: cells[0].textContent, target: cells[1].textContent, level: cells[2].textContent }); + // } + // }); + // return data; + // } + + function parseFilteredTable(tf) { var data = []; - var rows = table.querySelectorAll("tr"); - rows.forEach((row, i) => { - // Skipping header row and filter row - if (i > 1) { - var cells = row.querySelectorAll("td"); - data.push({ source: cells[0].textContent, target: cells[1].textContent, level: cells[2].textContent }); - } - }); + tf.getFilteredData().forEach((row, i) => { + // console.log("Row"); + // console.log(row); + data.push({ source: row[1][0], target: row[1][1], level: row[1][2] }); + // console.log("Data"); + // console.log(data); + } + ); return data; } - // Function to create graph - function createGraph(data, elementId) { + // Function to create Force-Directed Graph + function createForceDirectedGraph(data, elementId) { // Extract nodes and links var nodes = Array.from(new Set(data.flatMap(d => [d.source, d.target]))) .map(id => ({ id })); var links = data.map(d => ({ source: d.source, target: d.target })); + // console.log("Nodes"); + // console.log(nodes); // Set up the dimensions of the graph - var width = 800, height = 600; + var width = 1000, height = 1000; // Append SVG for the graph var svg = d3.select(elementId).append("svg") @@ -66,19 +81,132 @@ document$.subscribe(function () { .attr("cx", d => d.x) .attr("cy", d => d.y); }); + + // return simulation; + // invalidation.then(() => simulation.stop()); + return Object.assign(svg.node(), { + update({ newNodes, newLinks }) { + // Process new nodes and maintain the existing ones + const oldNodesMap = new Map(node.data().map(d => [d.id, d])); + nodes = newNodes.map(d => Object.assign(oldNodesMap.get(d.id) || {}, d)); + + // Update nodes with new data + node = node.data(nodes, d => d.id) + .join( + enter => enter.append("circle") + .attr("r", 5) + .attr("fill", "#69b3a2"), + update => update, + exit => exit.remove() + ); + + // Process new links + const oldLinksMap = new Map(link.data().map(d => [`${d.source.id},${d.target.id}`, d])); + links = newLinks.map(d => Object.assign(oldLinksMap.get(`${d.source.id},${d.target.id}`) || {}, d)); + + // Update links with new data + link = link.data(links, d => `${d.source.id},${d.target.id}`) + .join( + enter => enter.append("line") + .attr("stroke-width", d => Math.sqrt(d.value)), + update => update, + exit => exit.remove() + ); + + // Restart the simulation with new data + simulation.nodes(nodes); + simulation.force("link").links(links); + simulation.alpha(1).restart(); + } + }); } - // Find all tables that have a th with the class .graph and generate graphs + // Find all tables that have a th with the class .graph and generate Force-Directed Graphs document.querySelectorAll("table").forEach((table, index) => { var graphHeader = table.querySelector("th.graph"); if (graphHeader) { - var data = parseTable(table); - console.log(data); + // var data = parseTable(table); + // //var data = parseFilteredTable(table); + // // console.log("Data"); + // // console.log(data); + // var graphId = "graph" + index; + // var div = document.createElement("div"); + // div.id = graphId; + // table.after(div); + // var simulation = createForceDirectedGraph(data, "#" + graphId); + + // Initialize TableFilter for the table + var tf = new TableFilter(table, { + // Define filter options for each column (customize as needed) + base_path: "https://unpkg.com/tablefilter@0.7.3/dist/tablefilter/", + highlight_keywords: true, + col_2: "checklist", + col_widths: ["350px", "350px", "100px"], + col_types: ["string", "string", "number"], + grid_layout: false, + responsive: false, + watermark: ["Filter table ...", "Filter table ..."], + auto_filter: { + delay: 100 //milliseconds + }, + filters_row_index: 1, + state: true, + rows_counter: true, + status_bar: true, + themes: [{ + name: "transparent", + }], + btn_reset: { + tooltip: "Reset", + toolbar_position: "right", + }, + toolbar: true, + extensions: [{ + name: "sort", + }, + { + name: 'filtersVisibility', + description: 'Sichtbarkeit der Filter', + toolbar_position: 'right', + }], + }); + + tf.init(); + //var data = parseTable(table); + var data = parseFilteredTable(tf); + // console.log("Data"); + // console.log(data); var graphId = "graph" + index; var div = document.createElement("div"); div.id = graphId; table.after(div); - createGraph(data, "#" + graphId); + var simulation = createForceDirectedGraph(data, "#" + graphId); + + // Function to filter the table data and update the graph + function filterTableAndGraph() { + var filteredData = parseFilteredTable(tf); + // console.log("Filtered Data"); + // console.log(filteredData); + var { newNodes, newLinks } = processNewData(filteredData); + + // Restart the simulation with filtered data + simulation.update({ newNodes: newNodes, newLinks: newLinks }); + } + + function processNewData(newData) { + // Extracting new nodes + var newNodes = Array.from(new Set(newData.flatMap(d => [d.source, d.target]))) + .map(id => ({ id })); + + // Preparing the links in the required format + var newLinks = newData.map(d => ({ source: d.source, target: d.target })); + // console.log("New Nodes"); + // console.log(newNodes); + return { newNodes, newLinks }; + } + + // Listen for table filtering events + tf.emitter.on(['after-filtering'], filterTableAndGraph); } }); }); diff --git a/tools/mkdocs/site/docs/javascripts/tablefilter.js b/tools/mkdocs/site/docs/javascripts/tablefilter.js index b9314ad..295d125 100644 --- a/tools/mkdocs/site/docs/javascripts/tablefilter.js +++ b/tools/mkdocs/site/docs/javascripts/tablefilter.js @@ -32,9 +32,9 @@ document$.subscribe(function () { tooltip: "Reset", toolbar_position: "right", }, - no_results_message: { - content: "No matching records found", - }, + // no_results_message: { + // content: "No matching records found", + // }, toolbar: true, extensions: [{ name: "sort", diff --git a/tools/mkdocs/site/mkdocs.yml b/tools/mkdocs/site/mkdocs.yml index 43602cc..9a0ad62 100644 --- a/tools/mkdocs/site/mkdocs.yml +++ b/tools/mkdocs/site/mkdocs.yml @@ -66,7 +66,7 @@ extra: generator: false extra_javascript: - - javascripts/tablefilter.js + # - javascripts/tablefilter.js - "https://unpkg.com/tablefilter@0.7.3/dist/tablefilter/tablefilter.js" - "https://d3js.org/d3.v6.min.js" - javascripts/d3.js