landing-demo / components /script.js
b08x's picture
adjusted theme
4c5cf89
/**
* Theme Management
*/
const themeToggleBtn = document.getElementById('theme-toggle');
const htmlElement = document.documentElement;
const sunIcon = document.getElementById('sun-icon');
const moonIcon = document.getElementById('moon-icon');
// Initialize Theme
function initTheme() {
const savedTheme = localStorage.getItem('theme');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
// Default to dark if no save, or if saved is dark
const isDark = savedTheme === 'dark' || (!savedTheme && systemPrefersDark);
applyTheme(isDark ? 'dark' : 'light');
}
function applyTheme(theme) {
htmlElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
// Toggle Icons
if (theme === 'dark') {
sunIcon.style.display = 'block';
moonIcon.style.display = 'none';
} else {
sunIcon.style.display = 'none';
moonIcon.style.display = 'block';
}
// Trigger graph update if it exists (to recolor canvas/svg)
if (window.updateGraphTheme) {
window.updateGraphTheme();
}
}
themeToggleBtn.addEventListener('click', () => {
const currentTheme = htmlElement.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
applyTheme(newTheme);
});
// Initialize on load
initTheme();
/**
* Graph Visualization (Mock D3 Implementation for Demonstration)
* Replaces or Augments existing logic
*/
const graphContainer = document.getElementById('graph-container');
const width = graphContainer.clientWidth;
const height = graphContainer.clientHeight;
// Clear loading text
graphContainer.innerHTML = '';
// Create SVG
const svg = d3.select("#graph-container")
.append("svg")
.attr("width", "100%")
.attr("height", "100%")
.call(d3.zoom().on("zoom", (event) => {
g.attr("transform", event.transform);
}));
const g = svg.append("g");
// Sample Data
const graphData = {
nodes: [
{ id: "Root", group: 1 },
{ id: "Config", group: 2 },
{ id: "Assets", group: 2 },
{ id: "Theme", group: 2 },
{ id: "Scripts", group: 3 },
{ id: "Styles", group: 3 }
],
links: [
{ source: "Root", target: "Config" },
{ source: "Root", target: "Assets" },
{ source: "Assets", target: "Theme" },
{ source: "Config", target: "Scripts" },
{ source: "Config", target: "Styles" }
]
};
// Simulation Setup
const simulation = d3.forceSimulation(graphData.nodes)
.force("link", d3.forceLink(graphData.links).id(d => d.id).distance(100))
.force("charge", d3.forceManyBody().strength(-300))
.force("center", d3.forceCenter(width / 2, height / 2));
// Elements
const link = g.append("g")
.attr("class", "links")
.selectAll("line")
.data(graphData.links)
.enter().append("line");
const node = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graphData.nodes)
.enter().append("circle")
.attr("r", 8)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
const labels = g.append("g")
.attr("class", "labels")
.selectAll("text")
.data(graphData.nodes)
.enter().append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(d => d.id);
// Sidebar population
const nodeList = document.getElementById('node-list');
graphData.nodes.forEach(n => {
const div = document.createElement('div');
div.className = 'node-list-item';
div.textContent = `> ${n.id}`; // Terminal style prefix
div.addEventListener('click', () => {
// Zoom to node logic could go here
console.log(`Clicked ${n.id}`);
});
nodeList.appendChild(div);
});
// Simulation Tick
simulation.on("tick", () => {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
labels
.attr("x", d => d.x)
.attr("y", d => d.y);
});
// Drag functions
function dragstarted(event, d) {
if (!event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(event, d) {
d.fx = event.x;
d.fy = event.y;
}
function dragended(event, d) {
if (!event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
// Window Resize Handling
window.addEventListener('resize', () => {
simulation.force("center", d3.forceCenter(graphContainer.clientWidth / 2, graphContainer.clientHeight / 2));
simulation.alpha(0.3).restart();
});
// Expose update function for theme changes (CSS vars handle most, but sometimes D3 needs explicit updates)
window.updateGraphTheme = function() {
// Current CSS handles colors via variables, but if complex logic needed:
// const isDark = htmlElement.getAttribute('data-theme') === 'dark';
// link.style('stroke', isDark ? '#...' : '#...');
};