Guia de Charts
Guia de UsoAprenda como usar os componentes de gráficos com as cores padronizadas do hollow-UI.
Paleta de Cores hollow-UI
Cores padronizadas definidas no sistema de temas para consistência visual
Cores Principais
--chart-1
#d00b12
Dark: #d00b12
--chart-2
#9a1c1f
Dark: #9a1c1f
--chart-3
#f87171
Dark: #f87171
--chart-4
#64748b
Dark: #64748b
--chart-5
#94a3b8
Dark: #94a3b8
Cores de Status de Tarefas
--chart-concluido
#6ee7b7
Dark: #22c55e
--chart-em-analise
#22d3ee
Dark: #3b82f6
--chart-enviado
#a855f7
Dark: #8b5cf6
--chart-cancelado
#a1a1aa
Dark: #64748b
--chart-warning
#e11d48
Dark: #f43f5e
Cores de Programa
--chart-program-1
#ef4444
Dark: #f43f5e
--chart-program-2
#dc2626
Dark: #c81e3c
--chart-program-3
#b91c1c
Dark: #a7182f
--chart-program-4
#991b1b
Dark: #7a1222
--chart-program-5
#7f1d1d
Dark: #4a0b13
Cores de Criticidade
--chart-crit
#ff4848
Dark: #ef4444
--chart-moderate
#ff8c3a
Dark: #f97316
--chart-light
#ffd24b
Dark: #eab308
--chart-prevent
#44ff88
Dark: #22c55e
Cores de Métricas
--chart-metric-1
#10b981
Dark: #10b981
--chart-metric-2
#3b82f6
Dark: #3b82f6
--chart-metric-3
#f59e0b
Dark: #f59e0b
--chart-metric-4
#ef4444
Dark: #ef4444
Cores de Performance
--chart-performance-1
#059669
Dark: #059669
--chart-performance-2
#dc2626
Dark: #dc2626
--chart-performance-3
#7c3aed
Dark: #7c3aed
Cores Adicionais
--chart-baby
#4384fd
Dark: #6f98f2
--chart-selected
#8884d8
Dark: #ffffffa5
1. Configuração das Variáveis CSS
Defina as variáveis de cor no seu globals.css seguindo o padrão hollow-UI
globals.css
:root {
/* Cores principais dos gráficos - valores HSL */
--chart-1: 356 91% 43%; /* #d00b12 */
--chart-2: 356 73% 35%; /* #9a1c1f */
--chart-3: 0 70% 70%; /* #f87171 */
--chart-4: 215 16% 47%; /* #64748b */
--chart-5: 215 14% 64%; /* #94a3b8 */
/* Cores específicas de status */
--chart-concluido: 149 76% 67%; /* #6ee7b7 */
--chart-em-analise: 186 78% 53%; /* #22d3ee */
--chart-enviado: 271 81% 56%; /* #a855f7 */
--chart-cancelado: 0 0% 64%; /* #a1a1aa */
--chart-warning: 348 83% 47%; /* #e11d48 */
/* Cores de criticidade */
--chart-crit: 0 100% 64%; /* #ff4848 */
--chart-moderate: 20 95% 60%; /* #ff8c3a */
--chart-light: 44 100% 64%; /* #ffd24b */
--chart-prevent: 140 100% 64%; /* #44ff88 */
/* Cores de Métricas e Performance */
--chart-metric-1: 158 64% 52%; /* #10b981 */
--chart-metric-2: 221 83% 53%; /* #3b82f6 */
--chart-metric-3: 38 92% 50%; /* #f59e0b */
--chart-metric-4: 0 84% 60%; /* #ef4444 */
--chart-performance-1: 160 84% 39%; /* #059669 */
--chart-performance-2: 0 74% 42%; /* #dc2626 */
--chart-performance-3: 262 83% 58%; /* #7c3aed */
}
.dark {
/* Adaptações para modo escuro - mantém compatibilidade */
--chart-1: 356 91% 43%; /* #d00b12 */
--chart-2: 356 73% 35%; /* #9a1c1f */
--chart-3: 0 70% 70%; /* #f87171 */
--chart-concluido: 142 71% 45%; /* #22c55e */
--chart-em-analise: 221 83% 53%; /* #3b82f6 */
--chart-enviado: 262 83% 58%; /* #8b5cf6 */
--chart-cancelado: 215 16% 47%; /* #64748b */
--chart-crit: 0 84% 60%; /* #ef4444 */
--chart-moderate: 21 90% 48%; /* #f97316 */
--chart-light: 45 93% 47%; /* #eab308 */
--chart-prevent: 142 71% 45%; /* #22c55e */
}
.contrast {
/* Adaptações para alto contraste */
--chart-1: 356 91% 43%; /* #d00b12 */
--chart-2: 356 73% 35%; /* #9a1c1f */
--chart-3: 0 100% 70%; /* #ff6666 */
--chart-4: 0 0% 100%; /* #ffffff */
--chart-5: 0 0% 80%; /* #cccccc */
--chart-concluido: 142 71% 45%; /* #22c55e */
--chart-em-analise: 221 83% 53%; /* #3b82f6 */
--chart-enviado: 61 100% 97%; /* #f6ff00 */
--chart-cancelado: 0 0% 38%; /* #616060 */
--chart-crit: 0 100% 50%; /* #ff0000 */
--chart-moderate: 60 100% 50%; /* #ffff00 */
--chart-light: 60 100% 50%; /* #ffff00 */
--chart-prevent: 120 100% 50%; /* #00ff00 */
}2. Gráfico de Barras - Problemas Mensais
Exemplo baseado no gráfico de tarefas mensais Control
Componente - GraficoPRMensal.tsx
"use client";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent } from "@/components/ui/chart";
import { Bar, BarChart, XAxis, YAxis } from "recharts";
const data = [
{ month: "Jan", problemas: 45, concluidos: 32, abertos: 13 },
{ month: "Fev", problemas: 52, concluidos: 41, abertos: 11 },
{ month: "Mar", problemas: 38, concluidos: 29, abertos: 9 },
{ month: "Abr", problemas: 61, concluidos: 48, abertos: 13 },
{ month: "Mai", problemas: 44, concluidos: 36, abertos: 8 },
{ month: "Jun", problemas: 57, concluidos: 45, abertos: 12 },
];
const chartConfig = {
problemas: {
label: "Problemas Totais",
color: "var(--chart-1)",
},
concluidos: {
label: "Problemas Resolvidos",
color: "var(--chart-2)",
},
abertos: {
label: "Problemas Abertos",
color: "var(--chart-3)",
},
};
export function GraficoPRMensal() {
return (
<Card>
<CardHeader>
<CardTitle>Problemas por Mês</CardTitle>
</CardHeader>
<CardContent>
<ChartContainer config={chartConfig} className="h-80">
<BarChart data={data}>
<XAxis dataKey="month" />
<YAxis />
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
<Bar dataKey="problemas" fill="var(--chart-1)" radius={[4, 4, 0, 0]} />
<Bar dataKey="concluidos" fill="var(--chart-2)" radius={[4, 4, 0, 0]} />
<Bar dataKey="abertos" fill="var(--chart-3)" radius={[4, 4, 0, 0]} />
</BarChart>
</ChartContainer>
</CardContent>
</Card>
);
}3. Gráfico de Pizza - Status dos Problemas
Distribuição de status usando as cores específicas do sistema
Componente - GraficoStatusProblemas.tsx
"use client";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent } from "@/components/ui/chart";
import { PieChart, Pie, Cell } from "recharts";
const data = [
{ name: "Concluído", value: 231, fill: "var(--chart-concluido)" },
{ name: "Em Análise", value: 89, fill: "var(--chart-em-analise)" },
{ name: "Enviado", value: 45, fill: "var(--chart-enviado)" },
{ name: "Cancelado", value: 23, fill: "var(--chart-cancelado)" },
];
export function GraficoStatusProblemas() {
return (
<Card>
<CardHeader>
<CardTitle>Status dos Problemas</CardTitle>
</CardHeader>
<CardContent>
<ChartContainer config={{}} className="mx-auto aspect-square max-h-[300px]">
<PieChart>
<ChartTooltip content={<ChartTooltipContent nameKey="name" />} />
<Pie
data={data}
dataKey="value"
nameKey="name"
cx="50%"
cy="50%"
outerRadius={80}
>
{data.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.fill} />
))}
</Pie>
<ChartLegend content={<ChartLegendContent />} />
</PieChart>
</ChartContainer>
</CardContent>
</Card>
);
}4. Gráfico de Área - Problemas por Criticidade
Usando as cores específicas de criticidade do sistema
Componente - GraficoProblemasPrograma.tsx
"use client";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent } from "@/components/ui/chart";
import { AreaChart, Area, XAxis, YAxis } from "recharts";
const data = [
{ month: "Jan", crit: 15, moderate: 22, light: 28, prevent: 12 },
{ month: "Fev", crit: 12, moderate: 25, light: 31, prevent: 15 },
{ month: "Mar", crit: 18, moderate: 28, light: 25, prevent: 18 },
{ month: "Abr", crit: 10, moderate: 23, light: 34, prevent: 22 },
{ month: "Mai", crit: 14, moderate: 20, light: 29, prevent: 19 },
{ month: "Jun", crit: 8, moderate: 18, light: 32, prevent: 25 },
];
const chartConfig = {
crit: { label: "Crítico", color: "var(--chart-crit)" },
moderate: { label: "Moderado", color: "var(--chart-moderate)" },
light: { label: "Leve", color: "var(--chart-light)" },
prevent: { label: "Preventivo", color: "var(--chart-prevent)" },
};
export function GraficoProblemasPrograma() {
return (
<Card>
<CardHeader>
<CardTitle>Evolução de Problemas por Criticidade</CardTitle>
</CardHeader>
<CardContent>
<ChartContainer config={chartConfig} className="h-80">
<AreaChart data={data}>
<XAxis dataKey="month" />
<YAxis />
<ChartTooltip content={<ChartTooltipContent />} />
<Area
type="monotone"
dataKey="prevent"
stackId="1"
stroke="var(--chart-prevent)"
fill="var(--chart-prevent)"
fillOpacity={0.6}
/>
<Area
type="monotone"
dataKey="light"
stackId="1"
stroke="var(--chart-light)"
fill="var(--chart-light)"
fillOpacity={0.6}
/>
<Area
type="monotone"
dataKey="moderate"
stackId="1"
stroke="var(--chart-moderate)"
fill="var(--chart-moderate)"
fillOpacity={0.6}
/>
<Area
type="monotone"
dataKey="crit"
stackId="1"
stroke="var(--chart-crit)"
fill="var(--chart-crit)"
fillOpacity={0.6}
/>
<ChartLegend content={<ChartLegendContent />} />
</AreaChart>
</ChartContainer>
</CardContent>
</Card>
);
}5. Instalação e Dependências
Pacotes necessários para implementar os gráficos
Instalação
npm install recharts💡 Nota: Os componentes Chart (ChartContainer, ChartTooltip, etc.) já estão incluídos no hollow-UI e são baseados no shadcn/ui com estilizações customizadas.
6. Padrões e Boas Práticas
Diretrizes para uso consistente dos gráficos no hollow-UI Control
🎨 Uso de Cores
- chart-1 a chart-5: Para séries de dados gerais
- chart-concluido, chart-em-analise, etc.: Especificamente para status de problemas
- chart-crit, chart-moderate, etc.: Para níveis de criticidade
- chart-metric-1 a chart-metric-4: Para métricas e indicadores diversos
📊 Tipos de Gráfico por Contexto
- Barras: Comparações mensais, contagens por categoria
- Pizza: Distribuição de status, proporções
- Linha: Tendências ao longo do tempo
- Área: Volumes cumulativos, progressão
🎯 Responsividade
- Sempre use
ChartContainerpara wrapper responsivo - Defina altura fixa ou use classes como
h-80 - Configure tooltips e legendas para mobile
♿ Acessibilidade
- Use
ChartTooltippara informações detalhadas - Inclua legendas com
ChartLegend - Teste com modo de alto contraste
- Forneça textos alternativos quando necessário
Exemplo Completo: Dashboard de Performance
Implementação completa baseada no padrão hollow-UI
Dashboard.tsx - Exemplo Completo
"use client";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent } from "@/components/ui/chart";
import { BarChart, Bar, PieChart, Pie, LineChart, Line, XAxis, YAxis, Cell } from "recharts";
// Dados de exemplo
const performanceData = [
{ month: "Jan", metric1: 85, metric2: 72, metric3: 68, metric4: 91 },
{ month: "Fev", metric1: 88, metric2: 75, metric3: 71, metric4: 89 },
{ month: "Mar", metric1: 92, metric2: 78, metric3: 74, metric4: 87 },
{ month: "Abr", metric1: 87, metric2: 81, metric3: 77, metric4: 93 },
];
const statusDistribution = [
{ name: "Concluído", value: 231, fill: "var(--chart-concluido)" },
{ name: "Em Análise", value: 89, fill: "var(--chart-em-analise)" },
{ name: "Enviado", value: 45, fill: "var(--chart-enviado)" },
{ name: "Cancelado", value: 23, fill: "var(--chart-cancelado)" },
];
const metricConfig = {
metric1: { label: "Qualidade", color: "var(--chart-metric-1)" },
metric2: { label: "Prazo", color: "var(--chart-metric-2)" },
metric3: { label: "Custo", color: "var(--chart-metric-3)" },
metric4: { label: "Satisfação", color: "var(--chart-metric-4)" },
};
export function DashboardPerformance() {
return (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Métricas por Mês */}
<Card>
<CardHeader>
<CardTitle>Performance - Métricas Mensais</CardTitle>
</CardHeader>
<CardContent>
<ChartContainer config={metricConfig} className="h-80">
<LineChart data={performanceData}>
<XAxis dataKey="month" />
<YAxis domain={[0, 100]} />
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
<Line
type="monotone"
dataKey="metric1"
stroke="var(--chart-metric-1)"
strokeWidth={2}
dot={{ fill: "var(--chart-metric-1)" }}
/>
<Line
type="monotone"
dataKey="metric2"
stroke="var(--chart-metric-2)"
strokeWidth={2}
dot={{ fill: "var(--chart-metric-2)" }}
/>
<Line
type="monotone"
dataKey="metric3"
stroke="var(--chart-metric-3)"
strokeWidth={2}
dot={{ fill: "var(--chart-metric-3)" }}
/>
<Line
type="monotone"
dataKey="metric4"
stroke="var(--chart-metric-4)"
strokeWidth={2}
dot={{ fill: "var(--chart-metric-4)" }}
/>
</LineChart>
</ChartContainer>
</CardContent>
</Card>
{/* Distribuição de Status */}
<Card>
<CardHeader>
<CardTitle>Distribuição de Status</CardTitle>
</CardHeader>
<CardContent>
<ChartContainer config={{}} className="mx-auto aspect-square max-h-[300px]">
<PieChart>
<ChartTooltip content={<ChartTooltipContent nameKey="name" />} />
<Pie
data={statusDistribution}
dataKey="value"
nameKey="name"
cx="50%"
cy="50%"
outerRadius={80}
label={({ name, percent }) => `${name} ${(percent * 100).toFixed(0)}%`}
>
{statusDistribution.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.fill} />
))}
</Pie>
<ChartLegend content={<ChartLegendContent />} />
</PieChart>
</ChartContainer>
</CardContent>
</Card>
</div>
);
}


