document.addEventListener('DOMContentLoaded', function() { // Initialize GOV.UK Frontend window.GOVUKFrontend.initAll(); // Taxonomy Explorer implementation class TaxonomyExplorer { constructor(containerId) { this.container = document.getElementById(containerId); this.data = null; this.hierarchy = null; this.currentNode = null; this.searchTerm = ''; this.stats = { l1: 0, l2: 0, l3: 0 }; this.init(); } async init() { // Load taxonomy data await this.loadData(); // Initialize visualization this.initVisualization(); // Render controls this.renderControls(); } async loadData() { // In a real implementation, this would load from an API // For now we'll use the static data structure this.data = this.parseMarkdown(markdownData); this.hierarchy = d3.hierarchy(this.data); this.calculateStats(); } parseMarkdown(markdown) { // Improved parsing logic from original code // ... (keep existing parsing logic) } calculateStats() { // Calculate stats for the taxonomy // ... (keep existing stats logic) } initVisualization() { // Set up D3 visualization with improved GOV.UK styling const width = this.container.clientWidth; const height = this.container.clientHeight; this.svg = d3.select(this.container) .append('svg') .attr('width', width) .attr('height', height) .style('font-family', '"GDS Transport", Arial, sans-serif'); this.g = this.svg.append('g'); // Add zoom behavior this.zoom = d3.zoom() .scaleExtent([0.1, 2]) .on('zoom', (event) => this.g.attr('transform', event.transform)); this.svg.call(this.zoom); // Set up tree layout this.tree = d3.tree() .size([width - 200, height - 200]) .separation((a, b) => a.parent === b.parent ? 1.5 : 2); // Initial render this.updateVisualization(); } updateVisualization() { // Update the visualization based on current state const treeData = this.tree(this.hierarchy); const nodes = treeData.descendants(); const links = treeData.links(); // Normalize positions nodes.forEach(d => d.y = d.depth * 180); // Update nodes and links // ... (keep existing update logic with GOV.UK styling) } renderControls() { // Create control panel const controls = this.container.insertBefore( document.createElement('div'), this.container.firstChild ); controls.className = 'taxonomy-controls'; // Add search input const searchDiv = document.createElement('div'); searchDiv.className = 'taxonomy-search'; searchDiv.innerHTML = `
`; controls.appendChild(searchDiv); // Add stats display const statsDiv = document.createElement('div'); statsDiv.className = 'taxonomy-stats'; statsDiv.innerHTML = `
${this.stats.l1}
L1 Categories
${this.stats.l2}
L2 Subcategories
${this.stats.l3}
L3 Topics
`; controls.appendChild(statsDiv); // Add event listeners document.getElementById('taxonomy-search').addEventListener('input', (e) => { this.searchTerm = e.target.value.toLowerCase(); this.highlightMatches(); }); } highlightMatches() { // Highlight nodes matching search term this.svg.selectAll('.node') .classed('node-highlighted', (d) => { if (!this.searchTerm) return false; const nameMatch = d.data.name.toLowerCase().includes(this.searchTerm); const slugMatch = d.data.slug && d.data.slug.toLowerCase().includes(this.searchTerm); return nameMatch || slugMatch; }); } showDetails(node) { // Show details panel for selected node // ... (keep existing details panel logic with GOV.UK styling) } } // Initialize the explorer new TaxonomyExplorer('taxonomy-explorer'); });