Gráficos y Estadísticas chartsvgzero-dependencypolarseasonalityradialcyclical
Polar Area Chart
Sectores de igual ángulo con radio proporcional al área para categorías cíclicas como meses.
Vista Previa en Vivo
Seasonality at a glance
View data
| Item | Value |
|---|---|
| Jan | 320 |
| Feb | 280 |
| Mar | 360 |
| Apr | 410 |
| May | 470 |
| Jun | 520 |
| Jul | 490 |
| Aug | 450 |
| Sep | 430 |
| Oct | 510 |
| Nov | 690 |
| Dec | 820 |
Uso
Copia y pega este código directamente en tu página de Astro:
astro
---
import { PolarAreaChart } from 'astro-component-kit/charts';
---
<PolarAreaChart
items={[
{ label: 'Q1', value: 320 },
{ label: 'Q2', value: 410 },
{ label: 'Q3', value: 380 },
{ label: 'Q4', value: 690 },
]}
/> ---
import { PolarAreaChart } from 'astro-component-kit/charts';
---
<PolarAreaChart
items={[
{ label: 'Q1', value: 320 },
{ label: 'Q2', value: 410 },
{ label: 'Q3', value: 380 },
{ label: 'Q4', value: 690 },
]}
/> Instalación Manual
Si no estás usando el paquete npm, crea un archivo nuevo y pega el siguiente código: src/components/lib/PolarAreaChart.astro:
astro
---
/**
* PolarAreaChart — Equal-angle wedges whose radius encodes value (area-correct
* via square-root scaling). Good for cyclical categories like months or hours.
*
* @param {Array<{label: string, value: number}>} items - Wedges (max 12).
* @param {string} color - Wedge hue (single series).
* @param {string} suffix - Value suffix.
* @param {string} variant - Card style (glass|solid|ghost).
* @param {string} size - Density (sm|md|lg).
*/
import ChartFrame from './ChartFrame.astro';
import { arcPath, polar, formatValue } from './chart-utils';
interface Props {
title?: string;
subtitle?: string;
items?: Array<{ label: string; value: number }>;
color?: string;
prefix?: string;
suffix?: string;
variant?: 'glass' | 'solid' | 'ghost';
size?: 'sm' | 'md' | 'lg';
className?: string;
}
const {
title = 'Orders by month',
subtitle = 'Seasonality at a glance',
items = [
{ label: 'Jan', value: 320 }, { label: 'Feb', value: 280 }, { label: 'Mar', value: 360 },
{ label: 'Apr', value: 410 }, { label: 'May', value: 470 }, { label: 'Jun', value: 520 },
{ label: 'Jul', value: 490 }, { label: 'Aug', value: 450 }, { label: 'Sep', value: 430 },
{ label: 'Oct', value: 510 }, { label: 'Nov', value: 690 }, { label: 'Dec', value: 820 },
],
color = 'var(--chart-7, #9085e9)',
prefix = '',
suffix = '',
variant = 'glass',
size = 'md',
className = '',
} = Astro.props;
const S = 320;
const c = S / 2;
const R = S / 2 - 26;
const max = Math.max(...items.map((i) => i.value)) || 1;
const n = Math.min(items.length, 12);
const sweep = (Math.PI * 2) / n;
const rings = [0.25, 0.5, 0.75, 1];
const fmt = (v: number) => formatValue(v, prefix, suffix);
---
<ChartFrame
title={title}
subtitle={subtitle}
variant={variant}
size={size}
className={className}
table={{ headers: ['Item', 'Value'], rows: items.map((i) => [i.label, fmt(i.value)]) }}
>
<div class="pa">
<svg viewBox={`0 0 ${S} ${S}`} role="img" aria-label={`${title}: polar area chart of ${n} categories`}>
{rings.map((f) => <circle class="cf-grid" cx={c} cy={c} r={R * Math.sqrt(f)} fill="none" />)}
{items.slice(0, n).map((it, i) => {
const r = R * Math.sqrt(it.value / max);
const a0 = i * sweep + 0.012;
const a1 = (i + 1) * sweep - 0.012;
const [lx, ly] = polar(c, c, R + 14, i * sweep + sweep / 2);
const isMax = it.value === max;
return (
<g>
<path class="cf-mark cf-dim" d={arcPath(c, c, r, 0, a0, a1)} fill={color} fill-opacity={0.35 + 0.6 * (it.value / max)}
tabindex="0" role="img" aria-label={`${it.label}: ${fmt(it.value)}`} data-tip-title={it.label} data-tip={`${color}::${fmt(it.value)}`} />
<text class={isMax ? 'cf-label cf-label--strong' : 'cf-label'} x={lx} y={ly + 4} text-anchor="middle">{it.label}</text>
</g>
);
})}
</svg>
</div>
</ChartFrame>
<style>
.pa { max-width: 360px; margin: 0 auto; }
</style> ---
/**
* PolarAreaChart — Equal-angle wedges whose radius encodes value (area-correct
* via square-root scaling). Good for cyclical categories like months or hours.
*
* @param {Array<{label: string, value: number}>} items - Wedges (max 12).
* @param {string} color - Wedge hue (single series).
* @param {string} suffix - Value suffix.
* @param {string} variant - Card style (glass|solid|ghost).
* @param {string} size - Density (sm|md|lg).
*/
import ChartFrame from './ChartFrame.astro';
import { arcPath, polar, formatValue } from './chart-utils';
interface Props {
title?: string;
subtitle?: string;
items?: Array<{ label: string; value: number }>;
color?: string;
prefix?: string;
suffix?: string;
variant?: 'glass' | 'solid' | 'ghost';
size?: 'sm' | 'md' | 'lg';
className?: string;
}
const {
title = 'Orders by month',
subtitle = 'Seasonality at a glance',
items = [
{ label: 'Jan', value: 320 }, { label: 'Feb', value: 280 }, { label: 'Mar', value: 360 },
{ label: 'Apr', value: 410 }, { label: 'May', value: 470 }, { label: 'Jun', value: 520 },
{ label: 'Jul', value: 490 }, { label: 'Aug', value: 450 }, { label: 'Sep', value: 430 },
{ label: 'Oct', value: 510 }, { label: 'Nov', value: 690 }, { label: 'Dec', value: 820 },
],
color = 'var(--chart-7, #9085e9)',
prefix = '',
suffix = '',
variant = 'glass',
size = 'md',
className = '',
} = Astro.props;
const S = 320;
const c = S / 2;
const R = S / 2 - 26;
const max = Math.max(...items.map((i) => i.value)) || 1;
const n = Math.min(items.length, 12);
const sweep = (Math.PI * 2) / n;
const rings = [0.25, 0.5, 0.75, 1];
const fmt = (v: number) => formatValue(v, prefix, suffix);
---
<ChartFrame
title={title}
subtitle={subtitle}
variant={variant}
size={size}
className={className}
table={{ headers: ['Item', 'Value'], rows: items.map((i) => [i.label, fmt(i.value)]) }}
>
<div class="pa">
<svg viewBox={`0 0 ${S} ${S}`} role="img" aria-label={`${title}: polar area chart of ${n} categories`}>
{rings.map((f) => <circle class="cf-grid" cx={c} cy={c} r={R * Math.sqrt(f)} fill="none" />)}
{items.slice(0, n).map((it, i) => {
const r = R * Math.sqrt(it.value / max);
const a0 = i * sweep + 0.012;
const a1 = (i + 1) * sweep - 0.012;
const [lx, ly] = polar(c, c, R + 14, i * sweep + sweep / 2);
const isMax = it.value === max;
return (
<g>
<path class="cf-mark cf-dim" d={arcPath(c, c, r, 0, a0, a1)} fill={color} fill-opacity={0.35 + 0.6 * (it.value / max)}
tabindex="0" role="img" aria-label={`${it.label}: ${fmt(it.value)}`} data-tip-title={it.label} data-tip={`${color}::${fmt(it.value)}`} />
<text class={isMax ? 'cf-label cf-label--strong' : 'cf-label'} x={lx} y={ly + 4} text-anchor="middle">{it.label}</text>
</g>
);
})}
</svg>
</div>
</ChartFrame>
<style>
.pa { max-width: 360px; margin: 0 auto; }
</style>
Información Rápida
- Categoría
- Gráficos y Estadísticas
- Nombre de archivo
PolarAreaChart.astro- Dependencias
- apexcharts (peer)
- Etiquetas
- chartsvgzero-dependencypolarseasonalityradialcyclical