Download charts_web/chart.html from codepawl/loupe: direct link, hf CLI and curl.
- Browser
- Download file 6.74 kB
-
https://huggingface.co/codepawl/loupe/resolve/main/charts_web/chart.html
- Command line
-
hf download hf://codepawl/loupe/charts_web/chart.html
-
curl -L -o chart.html https://huggingface.co/codepawl/loupe/resolve/main/charts_web/chart.html
6.74 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>Loupe charts</title> | |
| <style> | |
| @font-face { font-family: "Inter"; src: url("InterVariable.woff2") format("woff2"); font-weight: 100 900; font-style: normal; } | |
| :root { --ink: #f4f4f6; --muted: #8d93a3; --accent: #6a92ee; --plain: #c9ccd6; --faint: #4a4e5c; --track: #ffffff0d; } | |
| html, body { margin: 0; } | |
| body { | |
| width: 1600px; height: 900px; overflow: hidden; color: var(--ink); | |
| font-family: "Inter", system-ui, sans-serif; -webkit-font-smoothing: antialiased; font-optical-sizing: auto; | |
| background: radial-gradient(70% 60% at 15% 0%, #1a2242 0%, transparent 70%), radial-gradient(60% 50% at 95% 100%, #132a22 0%, transparent 70%), #0e0e11; | |
| } | |
| .frame { position: absolute; inset: 0; padding: 84px 100px 0; box-sizing: border-box; } | |
| h1 { margin: 0; font-size: 76px; line-height: 1.04; font-weight: 760; letter-spacing: -0.04em; } | |
| .note { margin: 22px 0 0; font-size: 30px; line-height: 1.3; color: var(--muted); max-width: 1280px; } | |
| .chart { position: absolute; left: 100px; right: 100px; top: 330px; bottom: 150px; display: flex; flex-direction: column; justify-content: center; gap: 30px; } | |
| .bar-row { display: grid; grid-template-columns: 420px 1fr; align-items: center; column-gap: 28px; } | |
| .bar-label { font-size: 30px; font-weight: 560; letter-spacing: -0.01em; text-align: right; color: var(--ink); } | |
| .bar-row.faint .bar-label { color: var(--muted); } | |
| .track { position: relative; height: 68px; border-radius: 18px; background: var(--track); } | |
| .bar-row.compact .track { height: 44px; border-radius: 13px; } | |
| .fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: inherit; background: var(--plain); min-width: 14px; } | |
| .bar-row.strong .fill { background: var(--accent); } | |
| .bar-row.faint .fill { background: var(--faint); } | |
| .value { position: absolute; top: 50%; transform: translateY(-50%); font-size: 40px; font-weight: 740; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; white-space: nowrap; } | |
| .bar-row.compact .value { font-size: 28px; } | |
| .bar-row.compact .bar-label { font-size: 26px; } | |
| .marker { position: absolute; top: -14px; bottom: -14px; width: 0; border-left: 2px dashed #ffffff40; } | |
| .marker span { position: absolute; top: -34px; left: -40px; width: 80px; text-align: center; font-size: 20px; color: var(--muted); } | |
| .matrix { display: grid; grid-template-columns: 420px repeat(4, 1fr); gap: 16px 16px; align-items: center; } | |
| .matrix .head { font-size: 26px; color: var(--muted); text-align: center; font-weight: 560; } | |
| .matrix .label { font-size: 30px; font-weight: 560; text-align: right; padding-right: 12px; } | |
| .cell { height: 104px; border-radius: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; background: var(--track); } | |
| .cell b { font-size: 42px; font-weight: 740; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; } | |
| .cell span { font-size: 20px; color: #ffffffb0; margin-top: 2px; font-variant-numeric: tabular-nums; } | |
| .foot { position: absolute; left: 100px; bottom: 62px; right: 420px; font-size: 22px; line-height: 1.35; color: var(--muted); } | |
| .mark { position: absolute; right: 100px; bottom: 58px; display: flex; align-items: center; gap: 12px; font-size: 26px; font-weight: 600; letter-spacing: -0.02em; } | |
| .mark small { font-size: 22px; font-weight: 460; color: var(--muted); } | |
| .mark img { width: 38px; height: 38px; filter: invert(1); image-rendering: pixelated; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="frame"> | |
| <h1 id="title"></h1> | |
| <p class="note" id="note"></p> | |
| </div> | |
| <div class="chart" id="chart"></div> | |
| <div class="foot" id="foot"></div> | |
| <div class="mark"><span>Loupe</span><small>by</small><img src="codepawl-logo.png" alt=""><span>codepawl</span></div> | |
| <script type="module"> | |
| const element = (tag, className, text) => { | |
| const node = document.createElement(tag); | |
| if (className) node.className = className; | |
| if (text !== undefined) node.textContent = text; | |
| return node; | |
| }; | |
| function drawBars(chart, holder) { | |
| const compact = chart.bars.length > 4; | |
| if (compact) holder.style.gap = '18px'; | |
| for (const bar of chart.bars) { | |
| const row = element('div', `bar-row${bar.strong ? ' strong' : ''}${bar.faint ? ' faint' : ''}${compact ? ' compact' : ''}`); | |
| row.append(element('div', 'bar-label', bar.label)); | |
| const track = element('div', 'track'); | |
| const share = Math.min(bar.value / chart.maximum, 1); | |
| const fill = element('div', 'fill'); | |
| fill.style.width = `${share * 100}%`; | |
| const value = element('div', 'value', bar.text); | |
| // The number sits just past the bar, or inside its end when the bar is nearly full. | |
| if (share > 0.82) { value.style.right = `${(1 - share) * 100 + 2}%`; value.style.color = '#0e0e11'; } | |
| else value.style.left = `calc(${share * 100}% + 18px)`; | |
| track.append(fill, value); | |
| if (chart.marker !== undefined && bar === chart.bars[0]) { | |
| const marker = element('div', 'marker'); | |
| marker.style.left = `${(chart.marker / chart.maximum) * 100}%`; | |
| marker.style.bottom = `${-(chart.bars.length - 1) * (68 + 30) - 14}px`; | |
| marker.append(element('span', '', chart.marker_label)); | |
| track.append(marker); | |
| } | |
| row.append(track); | |
| holder.append(row); | |
| } | |
| } | |
| function drawMatrix(chart, holder) { | |
| const grid = element('div', 'matrix'); | |
| grid.append(element('div')); | |
| for (const column of chart.columns) grid.append(element('div', 'head', column)); | |
| for (const row of chart.rows) { | |
| grid.append(element('div', 'label', row.label)); | |
| for (const cell of row.cells) { | |
| const box = element('div', 'cell'); | |
| // Fuller colour for a higher share; an empty cell stays on the track colour. | |
| if (cell.value > 0) box.style.background = `rgba(106, 146, 238, ${0.16 + 0.84 * cell.value})`; | |
| box.append(element('b', '', `${Math.round(cell.value * 100)}%`), element('span', '', cell.text)); | |
| if (cell.value >= 0.6) box.querySelector('b').style.color = '#0e0e11', box.querySelector('span').style.color = '#0e0e11b0'; | |
| grid.append(box); | |
| } | |
| } | |
| holder.append(grid); | |
| } | |
| const charts = await (await fetch('data.json')).json(); | |
| const chart = charts[new URLSearchParams(location.search).get('chart')]; | |
| document.getElementById('title').textContent = chart.title; | |
| document.getElementById('note').textContent = chart.note; | |
| document.getElementById('foot').textContent = chart.foot; | |
| (chart.kind === 'matrix' ? drawMatrix : drawBars)(chart, document.getElementById('chart')); | |
| await document.fonts.ready; | |
| window.chartReady = true; | |
| </script> | |
| </body> | |
| </html> | |