diff --git a/static/js/graph.js b/static/js/graph.js index 16cc2f6..e678393 100644 --- a/static/js/graph.js +++ b/static/js/graph.js @@ -194,7 +194,6 @@ class GraphManager { - `; this.container.appendChild(controlsContainer); @@ -204,7 +203,6 @@ class GraphManager { document.getElementById('graph-reset').addEventListener('click', () => this.resetView()); document.getElementById('graph-physics').addEventListener('click', () => this.togglePhysics()); document.getElementById('graph-cluster').addEventListener('click', () => this.toggleClustering()); - document.getElementById('graph-clear').addEventListener('click', () => this.clear()); } /** @@ -912,6 +910,48 @@ class GraphManager { console.log('Image export not yet implemented'); return null; } + + /** + * Apply filters to the graph + * @param {string} nodeType - The type of node to show ('all' for no filter) + * @param {number} minConfidence - The minimum confidence score for edges to be visible + */ + applyFilters(nodeType, minConfidence) { + console.log(`Applying filters: nodeType=${nodeType}, minConfidence=${minConfidence}`); + + const nodeUpdates = []; + const edgeUpdates = []; + + const allNodes = this.nodes.get({ returnType: 'Object' }); + const allEdges = this.edges.get(); + + // Determine which nodes are visible based on the nodeType filter + for (const nodeId in allNodes) { + const node = allNodes[nodeId]; + const isVisible = (nodeType === 'all' || node.type === nodeType); + nodeUpdates.push({ id: nodeId, hidden: !isVisible }); + } + + // Update nodes first to determine edge visibility + this.nodes.update(nodeUpdates); + + // Determine which edges are visible based on confidence and connected nodes + for (const edge of allEdges) { + const sourceNode = this.nodes.get(edge.from); + const targetNode = this.nodes.get(edge.to); + const confidence = edge.metadata ? edge.metadata.confidence_score : 0; + + const isVisible = confidence >= minConfidence && + sourceNode && !sourceNode.hidden && + targetNode && !targetNode.hidden; + + edgeUpdates.push({ id: edge.id, hidden: !isVisible }); + } + + this.edges.update(edgeUpdates); + + console.log('Filters applied.'); + } } // Export for use in main.js diff --git a/static/js/main.js b/static/js/main.js index 3146fe9..795b3f2 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -87,7 +87,12 @@ class DNSReconApp { // Other elements sessionId: document.getElementById('session-id'), - connectionStatus: document.getElementById('connection-status') + connectionStatus: document.getElementById('connection-status'), + + // Filter elements + nodeTypeFilter: document.getElementById('node-type-filter'), + confidenceFilter: document.getElementById('confidence-filter'), + confidenceValue: document.getElementById('confidence-value') }; // Verify critical elements exist @@ -211,6 +216,13 @@ class DNSReconApp { } }); + // Filter events + this.elements.nodeTypeFilter.addEventListener('change', () => this.applyFilters()); + this.elements.confidenceFilter.addEventListener('input', () => { + this.elements.confidenceValue.textContent = this.elements.confidenceFilter.value; + this.applyFilters(); + }); + console.log('Event handlers set up successfully'); } catch (error) { @@ -942,6 +954,18 @@ class DNSReconApp { this.elements.virustotalApiKey.value = ''; } + /** + * Apply graph filters + */ + applyFilters() { + if (this.graphManager) { + const nodeType = this.elements.nodeTypeFilter.value; + const minConfidence = parseFloat(this.elements.confidenceFilter.value); + this.graphManager.applyFilters(nodeType, minConfidence); + } + } + + /** * Check if graph data has changed * @param {Object} graphData - New graph data diff --git a/templates/index.html b/templates/index.html index 8a75f41..ede5651 100644 --- a/templates/index.html +++ b/templates/index.html @@ -113,8 +113,22 @@