File size: 5,597 Bytes
a389a28 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | 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 = `
<div class="govuk-form-group">
<label class="govuk-label" for="taxonomy-search">Search taxonomy</label>
<input class="govuk-input" id="taxonomy-search" type="text" placeholder="Search...">
</div>
`;
controls.appendChild(searchDiv);
// Add stats display
const statsDiv = document.createElement('div');
statsDiv.className = 'taxonomy-stats';
statsDiv.innerHTML = `
<div class="taxonomy-stat">
<div class="taxonomy-stat-value" id="stat-l1">${this.stats.l1}</div>
<div class="taxonomy-stat-label">L1 Categories</div>
</div>
<div class="taxonomy-stat">
<div class="taxonomy-stat-value" id="stat-l2">${this.stats.l2}</div>
<div class="taxonomy-stat-label">L2 Subcategories</div>
</div>
<div class="taxonomy-stat">
<div class="taxonomy-stat-value" id="stat-l3">${this.stats.l3}</div>
<div class="taxonomy-stat-label">L3 Topics</div>
</div>
`;
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');
}); |