From fbcba54f08e11e21b2ff4136b96d80f70f82ca5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bonhomme?= Date: Thu, 9 Jan 2025 18:10:46 +0100 Subject: [PATCH] chg: [website] adapt the view when too much nodes with +/- buttons. --- website/web/templates/vuln.html | 64 +++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/website/web/templates/vuln.html b/website/web/templates/vuln.html index b3982c82..c3136831 100644 --- a/website/web/templates/vuln.html +++ b/website/web/templates/vuln.html @@ -908,16 +908,17 @@

Nomenclature

function loadSightingsCorrelations() { - // Clear any existing graph in the container - d3.select("#graph-container").selectAll("svg").remove(); - - // Fetch data from API and create the graph - fetch("{{ url_for('apiv1.sighting_sightings_list', vuln_id=vulnerability_id) }}&date_from=1970-01-01", { - method: 'GET', - headers: { - 'Accept': 'application/json' - } - }) + // Clear any existing graph in the container + d3.select("#graph-container").selectAll("svg").remove(); + d3.select("#graph-container").selectAll(".zoom-controls").remove(); + + // Fetch data from API and create the graph + fetch("{{ url_for('apiv1.sighting_sightings_list', vuln_id=vulnerability_id) }}&date_from=1970-01-01", { + method: 'GET', + headers: { + 'Accept': 'application/json' + } + }) .then(response => response.json()) .then(apiData => { // Extract the central node (vulnerability ID) and sightings @@ -941,7 +942,12 @@

Nomenclature

.select("#graph-container") .append("svg") .attr("width", width) - .attr("height", height); + .attr("height", height) + .call(d3.zoom().on("zoom", (event) => { + svgGroup.attr("transform", event.transform); + })); + + const svgGroup = svg.append("g"); svg.append("defs").append("marker") .attr("id", "arrow") @@ -961,9 +967,9 @@

Nomenclature

.force("charge", d3.forceManyBody().strength(-300)) .force("center", d3.forceCenter(width / 2, height / 2)); - const linkGroup = svg.append("g").attr("class", "links"); - const nodeGroup = svg.append("g").attr("class", "nodes"); - const labelGroup = svg.append("g").attr("class", "labels"); + const linkGroup = svgGroup.append("g").attr("class", "links"); + const nodeGroup = svgGroup.append("g").attr("class", "nodes"); + const labelGroup = svgGroup.append("g").attr("class", "labels"); function updateGraph() { // Bind data for links @@ -1046,6 +1052,34 @@

Nomenclature

simulation.alpha(1).restart(); } + // Add zoom in and zoom out buttons + const zoom = d3.zoom().on("zoom", (event) => { + svgGroup.attr("transform", event.transform); + }); + + svg.call(zoom); + + const zoomControls = d3.select("#graph-container") + .append("div") + .attr("class", "zoom-controls m-2") + .style("position", "relative") + .style("top", "10px") + .style("right", "10px"); + + zoomControls.append("button") + .attr("class", "btn btn-primary") + .text("+") + .on("click", () => { + svg.transition().call(zoom.scaleBy, 1.2); // Adjust the zoom behavior + }); + + zoomControls.append("button") + .attr("class", "btn btn-primary m-2") + .text("-") + .on("click", () => { + svg.transition().call(zoom.scaleBy, 0.8); // Adjust the zoom behavior + }); + // Automatically fetch vulnerabilities for all group 2 nodes const group2Nodes = nodes.filter(node => node.group === 2); @@ -1068,6 +1102,7 @@

Nomenclature

}) .catch(error => console.error('Error fetching vulnerabilities:', error)); }); + simulation.on("tick", () => { linkGroup.selectAll("line") .attr("x1", d => d.source.x) @@ -1095,6 +1130,7 @@

Nomenclature

+ document.getElementById("btnThemeSwitch").addEventListener("click",()=>{ if (document.documentElement.getAttribute("data-bs-theme") == "dark") { Array.from(document.getElementsByClassName("card")).forEach(container => {