/
komarovdd
/
GraphViz
Обзор
Документация
Войти
/
komarovdd
/
GraphViz
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
scripts/renderer.js
128 строк
4 KB
komarovdd
new project
09 фев 2026, 14:29
Верифицирован
09 фев 2026, 14:29
966388e
Код
Авторство
О чём код?
/** * Handles all drawing operations on the HTML5 Canvas. */ class Renderer { constructor(canvas) { this.canvas = canvas; this.ctx = canvas.getContext('2d'); this.transform = { x: 0, y: 0, scale: 1.0 }; this.hoveredNodeId = null; this.selectedNodeId = null; this.isDark = true; // Colors (Premium Dark Theme Palette) this.palette = [ '#38bdf8', '#818cf8', '#4ade80', '#fbbf24', '#f472b6', '#a78bfa', '#fb923c', '#2dd4bf' ]; this.defaultNodeColorDark = '#334155'; this.defaultNodeColorLight = '#cbd5e1'; } /** * Clears the canvas and draws the graph. */ render(graph) { const { ctx, canvas, transform } = this; // Clear background ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.save(); // Apply camera transformations ctx.translate(transform.x, transform.y); ctx.scale(transform.scale, transform.scale); // 1. Draw Edges graph.edges.forEach(edge => { const source = graph.nodes.get(edge.source); const target = graph.nodes.get(edge.target); if (!source || !target) return; this.drawEdge(source, target, edge.weight); }); // 2. Draw Nodes graph.nodes.forEach(node => { this.drawNode(node); }); ctx.restore(); } drawNode(node) { const { ctx } = this; const radius = 15; const isHighlighted = node.id === this.hoveredNodeId || node.id === this.selectedNodeId; ctx.beginPath(); ctx.arc(node.x, node.y, radius, 0, Math.PI * 2); // Color based on cluster or default if (node.clusterId !== null) { ctx.fillStyle = this.palette[node.clusterId % this.palette.length]; } else { ctx.fillStyle = this.isDark ? this.defaultNodeColorDark : this.defaultNodeColorLight; } ctx.fill(); // Border ctx.lineWidth = isHighlighted ? 3 : 1; ctx.strokeStyle = isHighlighted ? (this.isDark ? '#ffffff' : '#000000') : (this.isDark ? '#475569' : '#94a3b8'); ctx.stroke(); // Label ctx.fillStyle = this.isDark ? '#ffffff' : '#1e293b'; ctx.font = 'bold 10px "Inter", sans-serif'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(node.id, node.x, node.y); } drawEdge(source, target, weight) { const { ctx } = this; const isHighlighted = source.id === this.hoveredNodeId || target.id === this.hoveredNodeId; ctx.beginPath(); ctx.moveTo(source.x, source.y); ctx.lineTo(target.x, target.y); // Thickness proportional to weight ctx.lineWidth = Math.max(1, weight * 0.4); // Contrast for highlighted edges if (isHighlighted) { ctx.strokeStyle = this.isDark ? 'rgba(255, 255, 255, 0.6)' : 'rgba(0, 0, 0, 0.4)'; ctx.lineWidth += 1; } else { ctx.strokeStyle = this.isDark ? 'rgba(255, 255, 255, 0.15)' : 'rgba(148, 163, 184, 0.2)'; } ctx.stroke(); } /** * Converts screen coordinates to world coordinates. */ screenToWorld(x, y) { return { x: (x - this.transform.x) / this.transform.scale, y: (y - this.transform.y) / this.transform.scale }; } resize() { this.canvas.width = this.canvas.parentElement.clientWidth; this.canvas.height = this.canvas.parentElement.clientHeight; } } export { Renderer };