UNPKG

lightview

Version:

A reactive UI library with features of Bau, Juris, and HTMX plus safe LLM UI generation

769 lines (712 loc) 38 kB
<!-- SEO-friendly SPA Shim --> <script src="/lightview-router.js"></script> <script> if (globalThis.LightviewRouter) { LightviewRouter.base('/index.html'); } </script> <script type="module" src="../../components/data-display/chart.js"></script> <!-- Load the page-specific stylesheet --> <link rel="stylesheet" href="./index.css"> <!-- Gallery Structure --> <div class="gallery-page"> <div class="gallery-layout"> <!-- Sidebar Overlay --> <div id="sidebar-overlay" class="sidebar-overlay"></div> <!-- Sidebar --> <div id="gallery-sidebar" class="gallery-sidebar" style="visibility: hidden" src="./component-nav.html"></div> <!-- Main Content --> <div id="gallery-main" class="gallery-main"> <!-- Header Container --> <div style="position: sticky; top: 0; z-index: 30; background: var(--gallery-surface); border-bottom: 1px solid var(--gallery-border); backdrop-filter: blur(8px);"> <!-- Breadcrumbs Row --> <div style="padding: 0.75rem 1.5rem 0;"> <script> (() => { const { Breadcrumbs } = Lightview.tags; const breadcrumbs = Breadcrumbs({ id: 'page-breadcrumbs', items: [ { label: 'Components', href: '/docs/components' }, { label: 'Chart Pie' } ] }); document.currentScript.replaceWith(breadcrumbs.domEl); })(); </script> </div> <!-- Title Row --> <div class="gallery-header" style="border-bottom: none; height: auto; padding-top: 0.5rem; padding-bottom: 0.75rem;"> <button id="toggle-btn" class="toggle-btn" aria-label="Toggle Sidebar"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="toggle-icon" style="stroke: currentColor; stroke-width: 2;"> <path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7" /> <path stroke-linecap="round" stroke-linejoin="round" d="M11 19l-7-7 7-7" /> </svg> </button> <h1 class="gallery-title">Chart Pie</h1> </div> </div> <!-- Content --> <div class="gallery-content"> <div class="section-content" style="max-width: 1000px;"> <p class="text-lg" style="opacity: 0.7; margin-bottom: 1.5rem;"> Pie charts display data as slices of a circular pie, ideal for showing proportions and percentages that add up to 100%. </p> <!-- Basic Usage --> <div class="card bg-base-200" style="margin-bottom: 2rem;"> <div class="card-body"> <h2 class="card-title">Basic Usage</h2> <p class="text-sm" style="opacity: 0.7; margin-bottom: 1rem;"> To create a pie chart, use <code>type: 'pie'</code> and specify <code>start</code> and <code>end</code> for each segment. </p> <!-- Tabs --> <script> globalThis.switchBasicPieTab = (tabId) => { const tabs = ['tagged', 'vdom', 'object']; tabs.forEach(t => { const tabEl = document.getElementById(`basic-pie-tab-btn-${t}`); const contentEl = document.getElementById(`basic-pie-syntax-${t}`); if (t === tabId) { tabEl.classList.add('syntax-tab-active'); contentEl.style.display = 'block'; } else { tabEl.classList.remove('syntax-tab-active'); contentEl.style.display = 'none'; } }); }; </script> <div role="tablist" class="syntax-tabs" style="margin-bottom: 1rem;"> <button id="basic-pie-tab-btn-tagged" role="tab" class="syntax-tab syntax-tab-active" onclick="switchBasicPieTab('tagged')">Tagged</button> <button id="basic-pie-tab-btn-vdom" role="tab" class="syntax-tab" onclick="switchBasicPieTab('vdom')">vDOM</button> <button id="basic-pie-tab-btn-object" role="tab" class="syntax-tab" onclick="switchBasicPieTab('object')">Object DOM</button> </div> <!-- Tagged Syntax --> <div id="basic-pie-syntax-tagged"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300, autoRun: true }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { tags, $ } = Lightview; const { Chart } = tags; const chart = Chart({ type: 'pie', style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;' }, Chart.Body({}, Chart.Row({}, Chart.Data({ start: 0.0, end: 0.5, color: '#4CAF50' }) // 50% ), Chart.Row({}, Chart.Data({ start: 0.5, end: 0.8, color: '#2196F3' }) // 30% ), Chart.Row({}, Chart.Data({ start: 0.8, end: 1.0, color: '#FF9800' }) // 20% ) ) ); $('#example').content(chart);</code></pre> </div> <!-- vDOM Syntax --> <div id="basic-pie-syntax-vdom" style="display: none;"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300 }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { tags, $ } = Lightview; const { Chart } = tags; const segments = [ { start: 0.0, end: 0.5, color: '#4CAF50' }, { start: 0.5, end: 0.8, color: '#2196F3' }, { start: 0.8, end: 1.0, color: '#FF9800' } ]; const chart = { tag: Chart, attributes: { type: 'pie', style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;' }, children: [ { tag: Chart.Body, children: segments.map(seg => ({ tag: Chart.Row, children: [ { tag: Chart.Data, attributes: seg } ] })) } ] }; $('#example').content(chart);</code></pre> </div> <!-- Object DOM Syntax --> <div id="basic-pie-syntax-object" style="display: none;"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300 }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { $ } = Lightview; const chart = { Chart: { type: 'pie', style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;', children: [ { 'Chart.Body': { children: [ { 'Chart.Row': { children: [{ 'Chart.Data': { start: 0.0, end: 0.5, color: '#4CAF50' } }] } }, { 'Chart.Row': { children: [{ 'Chart.Data': { start: 0.5, end: 0.8, color: '#2196F3' } }] } }, { 'Chart.Row': { children: [{ 'Chart.Data': { start: 0.8, end: 1.0, color: '#FF9800' } }] } } ] } } ] } }; $('#example').content(chart);</code></pre> </div> </div> </div> <!-- With Labels --> <div class="card bg-base-200" style="margin-bottom: 2rem;"> <div class="card-body"> <h2 class="card-title">With Labels</h2> <p class="text-sm" style="opacity: 0.7; margin-bottom: 1rem;"> Add data labels with <code>labels: true</code> and include a <code>&lt;span class="data"&gt;</code>. </p> <!-- Tabs --> <script> globalThis.switchLabelsPieTab = (tabId) => { const tabs = ['tagged', 'vdom', 'object']; tabs.forEach(t => { const tabEl = document.getElementById(`labels-pie-tab-btn-${t}`); const contentEl = document.getElementById(`labels-pie-syntax-${t}`); if (t === tabId) { tabEl.classList.add('syntax-tab-active'); contentEl.style.display = 'block'; } else { tabEl.classList.remove('syntax-tab-active'); contentEl.style.display = 'none'; } }); }; </script> <div role="tablist" class="syntax-tabs" style="margin-bottom: 1rem;"> <button id="labels-pie-tab-btn-tagged" role="tab" class="syntax-tab syntax-tab-active" onclick="switchLabelsPieTab('tagged')">Tagged</button> <button id="labels-pie-tab-btn-vdom" role="tab" class="syntax-tab" onclick="switchLabelsPieTab('vdom')">vDOM</button> <button id="labels-pie-tab-btn-object" role="tab" class="syntax-tab" onclick="switchLabelsPieTab('object')">Object DOM</button> </div> <!-- Tagged Syntax --> <div id="labels-pie-syntax-tagged"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300, autoRun: true }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { tags, $ } = Lightview; const { Chart, span } = tags; const chart = Chart({ type: 'pie', labels: true, style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;' }, Chart.Body({}, Chart.Row({}, Chart.Label({}, 'Chrome'), Chart.Data({ start: 0.0, end: 0.6, color: '#4CAF50' }, span({ class: 'data' }, '60%')) ), Chart.Row({}, Chart.Label({}, 'Firefox'), Chart.Data({ start: 0.6, end: 0.85, color: '#F44336' }, span({ class: 'data' }, '25%')) ), Chart.Row({}, Chart.Label({}, 'Safari'), Chart.Data({ start: 0.85, end: 1.0, color: '#2196F3' }, span({ class: 'data' }, '15%')) ) ) ); $('#example').content(chart);</code></pre> </div> <!-- vDOM Syntax --> <div id="labels-pie-syntax-vdom" style="display: none;"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300 }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { tags, $ } = Lightview; const { Chart, span } = tags; const browsers = [ { name: 'Chrome', start: 0.0, end: 0.6, color: '#4CAF50', text: '60%' }, { name: 'Firefox', start: 0.6, end: 0.85, color: '#F44336', text: '25%' }, { name: 'Safari', start: 0.85, end: 1.0, color: '#2196F3', text: '15%' } ]; const chart = { tag: Chart, attributes: { type: 'pie', labels: true, style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;' }, children: [ { tag: Chart.Body, children: browsers.map(b => ({ tag: Chart.Row, children: [ { tag: Chart.Label, children: [b.name] }, { tag: Chart.Data, attributes: { start: b.start, end: b.end, color: b.color }, children: [{ tag: span, attributes: { class: 'data' }, children: [b.text] }] } ] })) } ] }; $('#example').content(chart);</code></pre> </div> <!-- Object DOM Syntax --> <div id="labels-pie-syntax-object" style="display: none;"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300 }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { $ } = Lightview; const chart = { Chart: { type: 'pie', labels: true, style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;', children: [ { 'Chart.Body': { children: [ { 'Chart.Row': { children: [ { 'Chart.Label': { children: ['Chrome'] } }, { 'Chart.Data': { start: 0.0, end: 0.6, color: '#4CAF50', children: [{ span: { class: 'data', children: ['60%'] } }] } } ] } }, { 'Chart.Row': { children: [ { 'Chart.Label': { children: ['Firefox'] } }, { 'Chart.Data': { start: 0.6, end: 0.85, color: '#F44336', children: [{ span: { class: 'data', children: ['25%'] } }] } } ] } }, { 'Chart.Row': { children: [ { 'Chart.Label': { children: ['Safari'] } }, { 'Chart.Data': { start: 0.85, end: 1.0, color: '#2196F3', children: [{ span: { class: 'data', children: ['15%'] } }] } } ] } } ] } } ] } }; $('#example').content(chart);</code></pre> </div> </div> </div> <!-- Color Schemes --> <div class="card bg-base-200" style="margin-bottom: 2rem;"> <div class="card-body"> <h2 class="card-title">Color Schemes</h2> <p class="text-sm" style="opacity: 0.7; margin-bottom: 1rem;"> Use custom colors for each slice via the <code>color</code> prop. </p> <!-- Tabs --> <script> globalThis.switchColorPieTab = (tabId) => { const tabs = ['tagged', 'vdom', 'object']; tabs.forEach(t => { const tabEl = document.getElementById(`color-pie-tab-btn-${t}`); const contentEl = document.getElementById(`color-pie-syntax-${t}`); if (t === tabId) { tabEl.classList.add('syntax-tab-active'); contentEl.style.display = 'block'; } else { tabEl.classList.remove('syntax-tab-active'); contentEl.style.display = 'none'; } }); }; </script> <div role="tablist" class="syntax-tabs" style="margin-bottom: 1rem;"> <button id="color-pie-tab-btn-tagged" role="tab" class="syntax-tab syntax-tab-active" onclick="switchColorPieTab('tagged')">Tagged</button> <button id="color-pie-tab-btn-vdom" role="tab" class="syntax-tab" onclick="switchColorPieTab('vdom')">vDOM</button> <button id="color-pie-tab-btn-object" role="tab" class="syntax-tab" onclick="switchColorPieTab('object')">Object DOM</button> </div> <!-- Tagged Syntax --> <div id="color-pie-syntax-tagged"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300, autoRun: true }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { tags, $ } = Lightview; const { Chart, span } = tags; const chart = Chart({ type: 'pie', labels: true, style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;' }, Chart.Body({}, Chart.Row({}, Chart.Label({}, 'Desktop'), Chart.Data({ start: 0.0, end: 0.45, color: '#00BCD4' }, span({ class: 'data' }, '45%')) ), Chart.Row({}, Chart.Label({}, 'Mobile'), Chart.Data({ start: 0.45, end: 0.80, color: '#8BC34A' }, span({ class: 'data' }, '35%')) ), Chart.Row({}, Chart.Label({}, 'Tablet'), Chart.Data({ start: 0.80, end: 0.95, color: '#FFC107' }, span({ class: 'data' }, '15%')) ), Chart.Row({}, Chart.Label({}, 'Other'), Chart.Data({ start: 0.95, end: 1.0, color: '#607D8B' }, span({ class: 'data' }, '5%')) ) ) ); $('#example').content(chart);</code></pre> </div> <!-- vDOM Syntax --> <div id="color-pie-syntax-vdom" style="display: none;"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300 }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { tags, $ } = Lightview; const { Chart, span } = tags; const devices = [ { name: 'Desktop', start: 0.0, end: 0.45, color: '#00BCD4', text: '45%' }, { name: 'Mobile', start: 0.45, end: 0.80, color: '#8BC34A', text: '35%' }, { name: 'Tablet', start: 0.80, end: 0.95, color: '#FFC107', text: '15%' }, { name: 'Other', start: 0.95, end: 1.0, color: '#607D8B', text: '5%' } ]; const chart = { tag: Chart, attributes: { type: 'pie', labels: true, style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;' }, children: [ { tag: Chart.Body, children: devices.map(d => ({ tag: Chart.Row, children: [ { tag: Chart.Label, children: [d.name] }, { tag: Chart.Data, attributes: { start: d.start, end: d.end, color: d.color }, children: [{ tag: span, attributes: { class: 'data' }, children: [d.text] }] } ] })) } ] }; $('#example').content(chart);</code></pre> </div> <!-- Object DOM Syntax --> <div id="color-pie-syntax-object" style="display: none;"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300 }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { $ } = Lightview; const chart = { Chart: { type: 'pie', labels: true, style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;', children: [ { 'Chart.Body': { children: [ { 'Chart.Row': { children: [{ 'Chart.Label': { children: ['Desktop'] } }, { 'Chart.Data': { start: 0.0, end: 0.45, color: '#00BCD4', children: [{ span: { class: 'data', children: ['45%'] } }] } }] } }, { 'Chart.Row': { children: [{ 'Chart.Label': { children: ['Mobile'] } }, { 'Chart.Data': { start: 0.45, end: 0.80, color: '#8BC34A', children: [{ span: { class: 'data', children: ['35%'] } }] } }] } }, { 'Chart.Row': { children: [{ 'Chart.Label': { children: ['Tablet'] } }, { 'Chart.Data': { start: 0.80, end: 0.95, color: '#FFC107', children: [{ span: { class: 'data', children: ['15%'] } }] } }] } }, { 'Chart.Row': { children: [{ 'Chart.Label': { children: ['Other'] } }, { 'Chart.Data': { start: 0.95, end: 1.0, color: '#607D8B', children: [{ span: { class: 'data', children: ['5%'] } }] } }] } } ] } } ] } }; $('#example').content(chart);</code></pre> </div> </div> </div> <!-- Axes --> <div class="card bg-base-200" style="margin-bottom: 2rem;"> <div class="card-body"> <h2 class="card-title">Axes</h2> <p class="text-sm" style="opacity: 0.7; margin-bottom: 1rem;"> Add background lines to the pie chart with the <code>secondaryAxesCount</code> prop. </p> <!-- Tabs --> <script> globalThis.switchAxesPieTab = (tabId) => { const tabs = ['tagged', 'vdom', 'object']; tabs.forEach(t => { const tabEl = document.getElementById(`axes-pie-tab-btn-${t}`); const contentEl = document.getElementById(`axes-pie-syntax-${t}`); if (t === tabId) { tabEl.classList.add('syntax-tab-active'); contentEl.style.display = 'block'; } else { tabEl.classList.remove('syntax-tab-active'); contentEl.style.display = 'none'; } }); }; </script> <div role="tablist" class="syntax-tabs" style="margin-bottom: 1rem;"> <button id="axes-pie-tab-btn-tagged" role="tab" class="syntax-tab syntax-tab-active" onclick="switchAxesPieTab('tagged')">Tagged</button> <button id="axes-pie-tab-btn-vdom" role="tab" class="syntax-tab" onclick="switchAxesPieTab('vdom')">vDOM</button> <button id="axes-pie-tab-btn-object" role="tab" class="syntax-tab" onclick="switchAxesPieTab('object')">Object DOM</button> </div> <!-- Tagged Syntax --> <div id="axes-pie-syntax-tagged"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300, autoRun: true }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { tags, $ } = Lightview; const { Chart } = tags; const chart = Chart({ type: 'pie', secondaryAxesCount: 4, style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;' }, Chart.Body({}, Chart.Row({}, Chart.Data({ start: 0.0, end: 0.45, color: '#00BCD4' })), Chart.Row({}, Chart.Data({ start: 0.45, end: 0.8, color: '#8BC34A' })), Chart.Row({}, Chart.Data({ start: 0.8, end: 1.0, color: '#FFC107' })) ) ); $('#example').content(chart);</code></pre> </div> <!-- vDOM Syntax --> <div id="axes-pie-syntax-vdom" style="display: none;"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300 }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { tags, $ } = Lightview; const { Chart } = tags; const chart = { tag: Chart, attributes: { type: 'pie', secondaryAxesCount: 4, style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;' }, children: [ { tag: Chart.Body, children: [ { tag: Chart.Row, children: [{ tag: Chart.Data, attributes: { start: 0.0, end: 0.45, color: '#00BCD4' } }] }, { tag: Chart.Row, children: [{ tag: Chart.Data, attributes: { start: 0.45, end: 0.8, color: '#8BC34A' } }] }, { tag: Chart.Row, children: [{ tag: Chart.Data, attributes: { start: 0.8, end: 1.0, color: '#FFC107' } }] } ] } ] }; $('#example').content(chart);</code></pre> </div> <!-- Object DOM Syntax --> <div id="axes-pie-syntax-object" style="display: none;"> <pre><script> examplify(document.currentScript.nextElementSibling, { at: document.currentScript.parentElement, scripts: ['/lightview.js', '/lightview-x.js'], styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'], type: 'module', minHeight: 300 }); </script><code contenteditable="true">await import('/components/data-display/chart.js'); const { $ } = Lightview; const chart = { Chart: { type: 'pie', secondaryAxesCount: 4, style: 'width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1;', children: [ { 'Chart.Body': { children: [ { 'Chart.Row': { children: [{ 'Chart.Data': { start: 0.0, end: 0.45, color: '#00BCD4' } }] } }, { 'Chart.Row': { children: [{ 'Chart.Data': { start: 0.45, end: 0.8, color: '#8BC34A' } }] } }, { 'Chart.Row': { children: [{ 'Chart.Data': { start: 0.8, end: 1.0, color: '#FFC107' } }] } } ] } } ] } }; $('#example').content(chart);</code></pre> </div> </div> </div> <!-- Calculating Values --> <h2 class="text-xl font-bold mb-4">Calculating Values</h2> <div class="card bg-base-100 shadow-sm mb-8"> <div class="card-body"> <p class="mb-4">Here's how to calculate <code>--start</code> and <code>--end</code> from percentages: </p> <div class="overflow-x-auto"> <table class="table table-zebra"> <thead> <tr> <th>Segment</th> <th>Percentage</th> <th>--start</th> <th>--end</th> </tr> </thead> <tbody> <tr> <td>First</td> <td>50%</td> <td>0.0</td> <td>0.5 (0 + 0.5)</td> </tr> <tr> <td>Second</td> <td>30%</td> <td>0.5 (prev end)</td> <td>0.8 (0.5 + 0.3)</td> </tr> <tr> <td>Third</td> <td>20%</td> <td>0.8 (prev end)</td> <td>1.0 (0.8 + 0.2)</td> </tr> </tbody> </table> </div> <div class="mt-4"> <pre class="bg-base-300 p-4 rounded-lg text-sm overflow-x-auto"><code>// Helper function to convert percentages to pie chart values function percentagesToPie(percentages) { let cumulative = 0; return percentages.map(pct => { const start = cumulative; cumulative += pct / 100; return { start, end: cumulative }; }); } // Example: const slices = percentagesToPie([50, 30, 20]); // Returns: [ // { start: 0, end: 0.5 }, // { start: 0.5, end: 0.8 }, // { start: 0.8, end: 1.0 } // ]</code></pre> </div> </div> </div> </div> </div> </div> </div> </div>