# ChartRadial

O arco de uma medida só: meta batida, uso de cota, taxa de conversão.

```tsx
<ChartRadial value={82} centerLabel="da meta do mês" />
```

## Contra o Meter

Escolha pelo espaço, não pelo gosto. A barra do `Meter` cabe numa linha de
formulário e lê mais rápido. O arco pede um cartão inteiro, e ganha quando o
número **é o assunto** do cartão, não um detalhe dentro dele.

## Não é Progress

O progresso anda para o fim e termina; esta medida sobe e desce enquanto o mês
corre. Por isso ela sai como `role="img"` com rótulo, e não como barra de
carregamento, trocar um pelo outro faz o leitor de tela anunciar "carregando"
para algo que não carrega.

## Movimento

Na primeira vez que aparece, o arco varre do início até o valor; quando o
`value` muda, anda do valor velho ao novo. Nos dois casos, com a duração e a
curva dos tokens (`--rc-duration-slow`, `--rc-ease`), pela mesma decisão do
`ChartContainer`. Com "reduzir movimento", o arco nasce no lugar e salta.

No `segmented`, os tracinhos acesos acendem em sequência, do primeiro ao último,
dentro do mesmo `--rc-duration-slow`. Cada um acende inteiro: ele é contagem, e
não traço contínuo, e tracinho meio aceso não diz nada.

## O eixo escondido

`sweep` é quanto do círculo o arco ocupa. Em `270`, que é o padrão, ele deixa a
base aberta, e é ali que o rótulo de baixo respira. Em `360` fecha.

Por dentro há um `PolarAngleAxis` com `domain={[0, max]}` que não desenha nada.
Ele existe porque a Recharts normaliza pelo maior valor da série, e com um único
ponto isso significa que **qualquer valor daria a volta inteira**.

## O miolo é pequeno, e ele não cresce com o cartão

O arco é um quadrado limitado pelo menor lado, e a peça tem `11rem` (176px) de
altura fixa. Num cartão de 176px ou mais o vão de dentro trava em **cerca de
125px de largura**: alargar o cartão alarga o gráfico, e não o buraco.

O que cabe ali, medido nesse vão: **umas dez letras** no número grande
(`1,5rem`) e **umas dezoito** na linha de baixo (`0,75rem`) — `da meta do mês`
tem catorze e sobra espaço; `R$ 246,7K de R$ 300K` tem vinte e não cabe.
Passando do limite nada corta nem vira reticências, porque o teto que o CSS
impõe é uma fração da **largura do cartão**, e não o buraco: num cartão largo
a frase atravessa o anel de ponta a ponta, e num estreito ela quebra em duas
linhas e aperta contra a base aberta. Os dois saem feios, e nenhum dos dois acusa.

A hierarquia que funciona é a porcentagem como número grande e o denominador
como a linha de baixo, que é justamente o que a porcentagem não carrega:

```tsx
<ChartRadial value={246_700} max={300_000} centerLabel="de R$ 300K" />
```

Quando a frase é maior que isso, ela sai do miolo. O arco não tem legenda de
fora para receber texto — a rosca tem, e é uma das razões para escolhê-la —,
então o lugar é o cartão em volta: o título, ou uma linha de apoio acima do
gráfico. Para quem ouve, a frase inteira vai em `label`: sem ele o nome
acessível é só a porcentagem, e "82 por cento" sozinho não diz por cento de
quê.

## A legenda da rosca

`ChartDonut` tem lista embaixo com nome e valor de cada fatia, ligada por
padrão. O arco não tem: ele mostra uma medida só, e a legenda de um item é o
próprio rótulo.

Com `variant="segmented"` o arco vira tracinhos, que é a variação mais pedida
de medidor em painel. Os traços apagados continuam na tela de propósito: sem a
escala inteira visível, um traço aceso não significa nada.

## No React Native

Traduz quase inteiro, em `@rivocode/ui-native/chart`, e é a peça de gráfico que menos muda: **ela nunca teve dica**. O valor mora no meio do arco, em texto, desde o web. O que o dedo faria aqui, o olho já fez. `value`, `max`, `sweep`, `variant` e `segments` atravessam iguais, o arco em tracinhos incluído.

Duas mudanças de tipo, as mesmas da rosca: `centerValue` e `centerLabel` são `string`, e `color` é papel de token (`chart-3`, `success`) e não cor de CSS.

O papel de acessibilidade é `image`, como o `role="img"` do web, e os dois vizinhos explicam por quê: o `Meter` nativo já tinha recusado `progressbar`, que faz o leitor de tela anunciar indicador de progresso para uma medida que sobe e desce, e `adjustable`, que prometeria que o gesto muda o valor. O nome carrega o número, então ouvir a peça é ouvir a medida. Sem `label`, ele é montado do que está escrito no meio (o valor **e** a linha de baixo), e não só a porcentagem como no web: "82 por cento" sozinho não diz por cento de quê.

O arco liso anda até o valor novo como no web, e nasce no lugar; o `segmented` acende os tracinhos de uma vez, também como no web.

## Importação

```tsx
import { ChartRadial } from '@rivocode/ui/chart'
```

## Exemplos

### Meta do mês

```tsx
import { Card, CardContent } from '@rivocode/ui'
import { ChartRadial, currencyShort } from '@rivocode/ui/chart'

export function MonthlyGoal() {
  return (
    <div className="w-64">
      <ChartRadial value={82} centerLabel="da meta do mês" />
    </div>
  )
}
```

### Com valor escrito

```tsx
import { Card, CardContent } from '@rivocode/ui'
import { ChartRadial, currencyShort } from '@rivocode/ui/chart'

export function WithOwnValue() {
  return (
    <Card className="w-64">
      <CardContent className="py-4">
        <p className="text-sm text-fg-muted">Faturado</p>
        <ChartRadial
          value={246_700}
          max={300_000}
          centerLabel={`de ${currencyShort(300_000)}`}
          label={`82% da meta de ${currencyShort(300_000)}`}
        />
      </CardContent>
    </Card>
  )
}
```

### Círculo fechado

```tsx
import { Card, CardContent } from '@rivocode/ui'
import { ChartRadial, currencyShort } from '@rivocode/ui/chart'

export function FullCircle() {
  return (
    <div className="w-56">
      <ChartRadial value={64} sweep={360} centerLabel="dos clientes ativos" />
    </div>
  )
}
```

### Medidor segmentado

```tsx
import { Card, CardContent } from '@rivocode/ui'
import { ChartRadial, currencyShort } from '@rivocode/ui/chart'

export function SegmentedGauge() {
  return (
    <div className="w-64">
      <ChartRadial
        value={82}
        variant="segmented"
        centerValue="82%"
        centerLabel="satisfação no mês"
        label="82% de satisfação no mês"
      />
    </div>
  )
}
```

## Props

| Prop | Tipo | Obrigatória | Desde | O que faz |
| --- | --- | --- | --- | --- |
| `value` | `number` | sim | 0.4.0 | De 0 a `max`. |
| `centerLabel` | `ReactNode` |  | 0.4.0 | A linha pequena embaixo do numero. |
| `centerValue` | `ReactNode` |  | 0.4.0 | O numero grande no meio. |
| `color` | `string` |  | 0.4.0 | A cor do arco. |
| `label` | `string` |  | 0.4.0 | O que o leitor de tela ouve. |
| `max` | `number` |  | 0.4.0 |  |
| `segments` | `number` |  | 0.5.0 | Quantos tracinhos, no `segmented`. |
| `sweep` | `number` |  | 0.4.0 | Onde o arco comeca e termina, em graus. |
| `variant` | `"segmented" \| "solid"` |  | 0.5.0 | `solid` desenha um arco liso; `segmented` desenha o arco em tracinhos, que e a variacao mais pedida de medidor em painel e custava 42 linhas de SVG no projeto de quem usa - com a cor cravada, entao sem responder ao tema. |

Além dessas: repassa `className`, `style`, `id` e os demais atributos do elemento raiz.

## Ver também

- [ChartContainer](/componentes/chart-container.md)
- [ChartDonut](/componentes/chart-donut.md)
- [Sparkline](/componentes/sparkline.md)
- [Convenções da biblioteca](/convencoes.md): Provider, tokens e as regras que valem para toda peça
- [Índice completo](/llms.txt)
