| | <div class="transformers-banner" style="width:100%;margin:10px 0;aspect-ratio:3/1;min-height:260px;"></div> |
| | <script> |
| | (() => { |
| | const ensureD3 = (cb) => { |
| | if (window.d3 && typeof window.d3.select === 'function') return cb(); |
| | let s = document.getElementById('d3-cdn-script'); |
| | if (!s) { |
| | s = document.createElement('script'); |
| | s.id = 'd3-cdn-script'; |
| | s.src = 'https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js'; |
| | document.head.appendChild(s); |
| | } |
| | const onReady = () => { if (window.d3 && typeof window.d3.select === 'function') cb(); }; |
| | s.addEventListener('load', onReady, { once: true }); |
| | if (window.d3) onReady(); |
| | }; |
| | |
| | const bootstrap = () => { |
| | const mount = document.currentScript ? document.currentScript.previousElementSibling : null; |
| | const container = (mount && mount.querySelector && mount.querySelector('.transformers-banner')) || document.querySelector('.transformers-banner'); |
| | if (!container) return; |
| | if (container.dataset) { |
| | if (container.dataset.mounted === 'true') return; |
| | container.dataset.mounted = 'true'; |
| | } |
| | |
| | |
| | const nodes = [ |
| | { id: "llama", is_base: true, size: 3.0, x: 0.5, y: 0.5 }, |
| | { id: "mistral", is_base: false, size: 1.3, x: 0.3, y: 0.4 }, |
| | { id: "gemma", is_base: false, size: 1.3, x: 0.7, y: 0.4 }, |
| | { id: "qwen2", is_base: false, size: 1.2, x: 0.4, y: 0.6 }, |
| | { id: "phi3", is_base: false, size: 1.2, x: 0.6, y: 0.6 }, |
| | { id: "deepseek_v3", is_base: false, size: 1.15, x: 0.35, y: 0.3 }, |
| | { id: "cohere", is_base: false, size: 1.2, x: 0.65, y: 0.3 }, |
| | { id: "mixtral", is_base: false, size: 1.2, x: 0.25, y: 0.5 }, |
| | { id: "glm4", is_base: false, size: 1.15, x: 0.75, y: 0.5 }, |
| | { id: "llava", is_base: true, size: 1.3, x: 0.5, y: 0.7 } |
| | ]; |
| | |
| | const links = [ |
| | { source: "llama", target: "mistral" }, |
| | { source: "llama", target: "gemma" }, |
| | { source: "llama", target: "qwen2" }, |
| | { source: "llama", target: "phi3" }, |
| | { source: "llama", target: "deepseek_v3" }, |
| | { source: "llama", target: "cohere" }, |
| | { source: "mistral", target: "mixtral" }, |
| | { source: "llama", target: "llava" } |
| | ]; |
| | |
| | const svg = d3.select(container).append('svg') |
| | .attr('width', '100%') |
| | .attr('height', '100%') |
| | .style('display', 'block'); |
| | |
| | const width = container.clientWidth; |
| | const height = container.clientHeight; |
| | |
| | const g = svg.append('g'); |
| | |
| | |
| | const link = g.append('g') |
| | .selectAll('line') |
| | .data(links) |
| | .join('line') |
| | .attr('stroke', '#999') |
| | .attr('stroke-opacity', 0.4) |
| | .attr('stroke-width', 1.5); |
| | |
| | |
| | const node = g.append('g') |
| | .selectAll('g') |
| | .data(nodes) |
| | .join('g') |
| | .attr('class', d => d.is_base ? 'node base' : 'node derived'); |
| | |
| | |
| | node.filter(d => d.is_base) |
| | .append('circle') |
| | .attr('r', d => 30 * d.size) |
| | .attr('fill', '#FFD21E') |
| | .attr('stroke', '#FF9D00') |
| | .attr('stroke-width', 2); |
| | |
| | node.filter(d => d.is_base) |
| | .append('text') |
| | .attr('text-anchor', 'middle') |
| | .attr('dy', '0.35em') |
| | .style('font-size', '20px') |
| | .text('🤗'); |
| | |
| | |
| | node.filter(d => !d.is_base) |
| | .append('circle') |
| | .attr('r', d => 15 * d.size) |
| | .attr('fill', '#667eea'); |
| | |
| | |
| | node.append('text') |
| | .attr('text-anchor', 'middle') |
| | .attr('dy', d => d.is_base ? 45 : 25) |
| | .style('font-size', '11px') |
| | .style('font-weight', '600') |
| | .style('fill', 'var(--text-color, #333)') |
| | .text(d => d.id); |
| | |
| | |
| | const updatePositions = () => { |
| | link |
| | .attr('x1', d => { |
| | const source = nodes.find(n => n.id === d.source); |
| | return source ? source.x * width : 0; |
| | }) |
| | .attr('y1', d => { |
| | const source = nodes.find(n => n.id === d.source); |
| | return source ? source.y * height : 0; |
| | }) |
| | .attr('x2', d => { |
| | const target = nodes.find(n => n.id === d.target); |
| | return target ? target.x * width : 0; |
| | }) |
| | .attr('y2', d => { |
| | const target = nodes.find(n => n.id === d.target); |
| | return target ? target.y * height : 0; |
| | }); |
| | |
| | node.attr('transform', d => `translate(${d.x * width}, ${d.y * height})`); |
| | }; |
| | |
| | updatePositions(); |
| | |
| | |
| | let resizeTimer; |
| | window.addEventListener('resize', () => { |
| | clearTimeout(resizeTimer); |
| | resizeTimer = setTimeout(updatePositions, 100); |
| | }); |
| | }; |
| | |
| | ensureD3(bootstrap); |
| | })(); |
| | </script> |
| |
|