Gráficos y Estadísticasdataanalyticschartbar
Bar Chart
Gráfico de barras vertical con esquinas redondeadas y datos comparativos por categorías.
Vista Previa en Vivo
Loading Chart...
Uso
Copia y pega este código directamente en tu componente React:
tsx
import { BarChart } from 'react-component-kit-ui/charts';
<BarChart title="Daily Traffic" categories={categories} series={series} />Instalación Manual
Si no estás usando el paquete npm, crea un archivo nuevo y pega el siguiente código: src/components/BarChart.tsx + BarChart.css:
BarChart.tsx
'use client';
import { useEffect, useRef } from 'react';
import './BarChart.css';
/**
* BarChart — A premium bar chart component.
*/
export interface BarChartProps {
title?: string;
subtitle?: string;
categories?: any[];
series?: any[];
height?: number | string;
colors?: string[];
horizontal?: boolean;
stacked?: boolean;
className?: string;
}
export function BarChart({
title,
subtitle,
categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
series = [{ name: 'Sessions', data: [44, 55, 41, 67, 22] }],
height = 350,
colors = ['var(--c-accent, #b8860b)', '#3b82f6', '#10b981'],
horizontal = false,
stacked = false,
className = '',
}: BarChartProps) {
const chartConfig = {
categories,
series,
height,
colors,
horizontal,
stacked,
};
// Ported from the Astro <script>: runs once after mount (DOM logic kept as in the Astro kit).
const mounted = useRef(false);
useEffect(() => {
if (mounted.current) return;
mounted.current = true;
async function initCharts() {
const charts = document.querySelectorAll('.premium-chart-card[data-chart-type="bar"]');
if (charts.length === 0) return;
let ApexChartsModule;
try {
ApexChartsModule = await import('apexcharts');
} catch (e) {
console.error('ApexCharts failed to load:', e);
return;
}
const ApexCharts = ApexChartsModule.default || ApexChartsModule;
charts.forEach(container => {
if (container.getAttribute('data-initialized')) return;
const configStr = container.getAttribute('data-config');
if (!configStr) return;
const config = JSON.parse(configStr);
config.colors = (config.colors || []).map((c: string) => {
const m = /^var\((--[\w-]+)\s*(?:,\s*([^)]+))?\)$/.exec(String(c).trim());
return m ? getComputedStyle(container as Element).getPropertyValue(m[1]).trim() || (m[2] || '').trim() : c;
});
const target = container.querySelector('.chart-container');
const fallback = container.querySelector('.chart-fallback');
if (!target) return;
const options = {
series: config.series,
chart: {
type: 'bar',
height: config.height,
stacked: config.stacked,
toolbar: { show: false },
background: 'transparent',
fontFamily: 'Inter, sans-serif',
},
plotOptions: {
bar: {
horizontal: config.horizontal,
columnWidth: '55%',
borderRadius: 8,
borderRadiusApplication: 'end',
},
},
colors: config.colors,
dataLabels: { enabled: false },
xaxis: {
categories: config.categories,
axisBorder: { show: false },
axisTicks: { show: false },
labels: { style: { colors: '#64748b', fontSize: '12px' } },
},
yaxis: {
labels: { style: { colors: '#64748b', fontSize: '12px' } },
},
grid: {
borderColor: 'rgba(148, 163, 184, 0.12)',
strokeDashArray: 4,
},
legend: {
show: true,
position: 'top',
horizontalAlign: 'right',
labels: { colors: '#94a3b8' },
},
tooltip: { theme: 'dark' },
theme: { mode: 'dark' }
};
try {
const chart = new ApexCharts(target, options);
chart.render().then(() => {
if (fallback) (fallback as HTMLElement).style.display = 'none';
});
container.setAttribute('data-initialized', 'true');
} catch (err) {
console.error('Failed to render chart:', err);
if (fallback) fallback.textContent = 'Failed to load chart';
}
});
}
initCharts();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<>
<div className={`premium-chart-card ${className}`} data-chart-type="bar" data-config={JSON.stringify(chartConfig)} data-rk-006992="">
{(title || subtitle) && (
<div className="premium-chart-card__header" data-rk-006992="">
{title && <h3 className="premium-chart-card__title" data-rk-006992="">{title}</h3>}
{subtitle && <p className="premium-chart-card__subtitle" data-rk-006992="">{subtitle}</p>}
</div>
)}
<div className="premium-chart-card__body" data-rk-006992="">
<div className="chart-container" data-rk-006992=""></div>
<div className="chart-fallback" data-rk-006992="">Loading Chart...</div>
</div>
</div>
</>
);
}
export default BarChart;BarChart.css
/* BarChart — ported from astro-component-kit (charts/BarChart.astro) */
.premium-chart-card:where([data-rk-006992]) {
background: rgb(var(--ink-rgb, 255 255 255) / 0.03);
backdrop-filter: blur(12px);
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
border-radius: var(--r-xl, 24px);
padding: var(--sp-6, 24px);
width: 100%;
min-width: 300px;
}
.premium-chart-card__header:where([data-rk-006992]) {
margin-bottom: var(--sp-6, 24px);
}
.premium-chart-card__title:where([data-rk-006992]) {
font-size: 1.125rem;
font-weight: 700;
color: var(--c-text-1, #ffffff);
margin: 0;
}
.premium-chart-card__subtitle:where([data-rk-006992]) {
font-size: 0.875rem;
color: var(--c-text-2, #94a3b8);
margin: var(--sp-1, 4px) 0 0;
}
.premium-chart-card__body:where([data-rk-006992]) {
width: 100%;
position: relative;
min-height: 200px;
}
.chart-container:where([data-rk-006992]) {
width: 100%;
position: relative;
z-index: 2;
}
.chart-fallback:where([data-rk-006992]) {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.8rem;
color: var(--c-text-3, #64748b);
z-index: 1;
}Información Rápida
- Categoría
- Gráficos y Estadísticas
- Nombre de archivo
BarChart.tsx- Dependencias
- Ninguna — React + CSS puro
- Etiquetas
- dataanalyticschartbar