mviz v1.7.0
O que mviz faz?
Gere gráficos e painéis limpos e focados em dados a partir de especificações JSON compactas ou markdown. Maximiza a relação dados-tinta com o mínimo de enfeites, grades e elementos decorativos. Usa um sistema de layout de grade de 16 colunas.
Configuração
Nenhuma instalação necessária. Use npx -y -q mviz que baixa automaticamente do npm. A flag -q reduz a saída do npm enquanto ainda mostra erros de lint.
Para uso repetido mais rápido, instale globalmente: npm install -g mviz
O Que Esta Skill Faz
mviz é duas coisas:
- Uma linguagem de especificação — markdown com blocos de código cercados descrevendo componentes (gráficos, KPIs, tabelas, notas, etc.). Um arquivo markdown (ou uma única especificação JSON) descreve uma visualização inteira.
- Um conjunto de renderizadores que transformam essa especificação em HTML para diferentes contextos de exibição. Hoje existem dois:
visualize:show_widget(inline) — quando você está no claude.ai com a ferramenta de visualização disponível, renderize a especificação mviz como um fragmento HTMLwidget_codeusando o sistema de design do claude.ai (Chart.js, tokensvar(--color-*)). O widget aparece inline na conversa.- CLI mviz (independente) —
mviz dashboard.md -o report.htmlproduz um documento HTML completo com o próprio sistema de design do mviz (tema mdsinabox, ECharts). Adequado para downloads, blocos iframe, impressão/PDF.
A especificação markdown do mviz é canônica; o renderizador é escolhido com base em onde a visualização aparecerá. Mesma especificação, duas renderizações. Um terceiro poderia construir um renderizador diferente (CLI baseado em Chart.js, renderizador com tema do Slack, etc.) sem alterar a especificação.
Escolhendo um renderizador
Sempre componha a especificação markdown do mviz primeiro, mesmo ao renderizar inline. A especificação é o artefato canônico — emita-a em um bloco de código cercado em sua resposta para que o usuário possa copiar/reutilizar/enviar para o CLI posteriormente. Em seguida, renderize-a com o renderizador que melhor se adequa à solicitação.
Antes de renderizar, decida qual renderizador se adequa — e declare sua inferência para que o usuário possa corrigi-lo. Alguns sinais:
Inline (visualize:show_widget):
- "mostre-me X" / "como foi X" / "como X mudou" / "renderize"
- Uma visualização pequena (tipicamente 1–4 componentes) que flui com o texto ao redor
- O usuário está explorando dados, não preparando algo para compartilhar
visualize:show_widgetestá disponível nesta conversa
Independente (CLI mviz):
- "faça um relatório" / "envie-me o arquivo" / "exporte para PDF" / "salve"
- Visualização composta com várias seções (5+ componentes, divisores, quebras de página, tabelas de largura total)
- O usuário quer algo para salvar, compartilhar, imprimir ou incorporar em um host externo (bloco iframe, célula de painel)
visualize:show_widgetnão está disponível (sem superfície de renderização inline)
Padrão para inline quando ambíguo. Declare a inferência explicitamente:
"Vou renderizar isso inline, já que você pediu para ver no chat. Se preferir um arquivo para download, posso executar o CLI mviz na mesma especificação — é só falar."
Se o usuário mais tarde pedir a versão em arquivo após uma renderização inline, a especificação já está na conversa — canalize-a através de mviz ... -o out.html sem recompor.
Estilo Visual (tema mdsinabox — para o renderizador CLI)
- Fonte: Helvetica Neue, Arial (sem serifa limpa)
- Assinatura: Linha de destaque laranja no topo dos painéis
- Paleta: Azul primário, laranja secundário, cores semânticas (verde=positivo, âmbar=aviso, vermelho=erro)
- Fundo: Papel (
#f8f8f8claro) / Escuro (#231f20escuro) - Princípios: Alta relação dados-tinta, sem enfeites, grades mínimas, os dados falam por si
Renderizador: CLI mviz (HTML independente)
O renderizador CLI produz um documento HTML completo estilizado com o tema mdsinabox acima. A saída é adequada para visualização direta no navegador, exportação para PDF, incorporação em iframe ou compartilhamento como arquivo.
Gráfico Único (JSON)
echo '<json_spec>' | npx -y -q mviz -o chart.html
Painel a partir de Markdown
npx -y -q mviz dashboard.md -o dashboard.html
Painel a partir de Pasta
npx -y -q mviz my-dashboard/ -o dashboard.html
Saída incorporada em iframe (--embed)
Quando o HTML renderizado viverá dentro do iframe de outro produto (blocos Prism do mdw-turbo, células de painel, etc.), use --embed para remover a moldura da página (barra de destaque vermelha, linha de título, alternador de tema) e aplicar uma bateria de pós-processamentos que otimizam o corpo: poda de CSS, fundos transparentes para que o cartão do host apareça, script ECharts removido quando não há gráficos, marked removido quando não há chamadores marked.parse(...), minificação de JS, etc.
npx -y -q mviz dashboard.md --embed -o tile.html
O modo embed emite um documento HTML completo (DOCTYPE + html + head + body intactos). Não é a ferramenta certa para visualize:show_widget — para isso, use o outro renderizador (veja abaixo).
Sistema de Grade de 16 Colunas
Os componentes são dimensionados usando a sintaxe size=[colunas,linhas]:
```big_value size=[4,2]
{"value": 1250000, "label": "Revenue", "format": "currency0m"}
```
```bar size=[8,6]
{"title": "Sales", "x": "month", "y": "sales", "file": "data/sales.json"}
```
- 16 colunas de largura total (retrato e paisagem)
- Altura da linha: ~32px por unidade de linha (aproximado - gráficos têm padding)
- Capacidade da página: Retrato [16c × 30l], Paisagem [16c × 22l]
- Componentes na mesma linha compartilham a linha
- Linha vazia = nova linha
Diretrizes de Altura:
| Unidades de Linha | Altura Aproximada | Adequado Para |
|---|---|---|
| 2 | ~64px | KPIs, notas de linha única |
| 4 | ~128px | Tabelas pequenas, blocos de texto |
| 5-6 | ~160-192px | Gráficos padrão |
| 8+ | ~256px+ | Tabelas densas, gráficos detalhados |
Para gráficos com muitas categorias (10+ barras, 10+ linhas em haltere), aumente as unidades de linha para evitar compressão.
Layout Lado a Lado
Crítico: Para colocar componentes lado a lado, seus blocos de código NÃO devem ter linhas em branco entre eles:
```bar size=[8,5]
{"title": "Chart A", ...}
```
```line size=[8,5]
{"title": "Chart B", ...}
```
Isso renderiza o Gráfico A e o Gráfico B na mesma linha. Adicionar uma linha em branco entre eles os colocaria em linhas separadas.
Títulos e Quebras de Seção
| Sintaxe | Efeito |
|---|---|
# H1 | Título da página |
## H2 | Título da seção |
### H3 | Cabeçalho inline leve (sutil, texto menor) |
--- | Linha divisória visual |
=== | Quebra de página para impressão |
empty_space | Espaçador de célula de grade invisível (padrão 4 cols × 2 linhas) |
Diretrizes de Título:
- Defina o título da página com o frontmatter
title:ou com um# H1inicial, não ambos. - Use
## H2para títulos de seção dentro de uma página (mais comum). - Use
### H3para subtítulos leves que não interrompem o fluxo.
Quebras de Seção vs. Página:
- Use
---para separar seções lógicas visualmente. O conteúdo flui naturalmente para a próxima página quando necessário. - Use
===somente quando você quiser explicitamente forçar uma nova página (por exemplo, separando capítulos ou seções principais de relatório para saída em PDF). - Nunca use
===por padrão. Adicione quebras de página apenas quando o usuário as solicitar explicitamente.
Tamanhos Padrão
| Componente | Tamanho Padrão | Notas |
|---|---|---|
big_value | [4, 2] | Cabe 4 por linha |
delta | [4, 2] | Cabe 4 por linha |
sparkline | [4, 2] | Gráfico inline compacto |
bar, line, area | [8, 5] | Meia largura |
pie, scatter, bubble | [8, 5] | Meia largura |
funnel, sankey, heatmap | [8, 5] | Meia largura |
histogram, boxplot, waterfall | [8, 5] | Meia largura |
combo | [8, 5] | Meia largura |
dumbbell | [12, 6] | 3/4 largura |
table | [16, 4] | Largura total |
textarea | [16, 4] | Largura total |
calendar | [16, 3] | Largura total |
xmr | [16, 6] | Largura total, alta |
mermaid | [8, 5] | Meia largura (use ascii: true para arte de texto) |
alert, note, text | [16, 1] | Largura total, linha única |
empty_space | [4, 2] | Espaçador invisível |
Pares de Tamanho Recomendados
| Objetivo do Layout | Componentes | Tamanhos |
|---|---|---|
| 4 KPIs em uma linha | 4× big_value | [4,2] cada |
| 5 KPIs em uma linha | 4× big_value + 1 mais largo | [3,2] + [4,2] |
| KPI + contexto | big_value + textarea | [3,2] + [13,2] |
| KPI + gráfico | big_value + bar | [4,2] + [12,5] |
Exemplo: Linha de KPI Densa
```big_value size=[3,2]
{"value": 1250000, "label": "Revenue", "format": "currency0m"}
```
```big_value size=[3,2]
{"value": 8450, "label": "Orders", "format": "num0k"}
```
```big_value size=[3,2]
{"value": 2400000000, "label": "Queries", "format": "num0b"}
```
```delta size=[3,2]
{"value": 0.15, "label": "MoM", "format": "pct0"}
```
```delta size=[4,2]
{"value": 0.08, "label": "vs Target", "format": "pct0"}
```
Isso cria uma linha com 5 KPIs (3+3+3+3+4 = 16 colunas).
Exemplo: Dois Gráficos Lado a Lado
```bar size=[8,6] file=data/region-sales.json
```
```line size=[8,6] file=data/monthly-trend.json
```
Tipos Suportados
Gráficos: bar, line, area, pie, scatter, bubble, boxplot, histogram, waterfall, xmr, sankey, funnel, heatmap, calendar, sparkline, combo, dumbbell, mermaid
Componentes de UI: big_value, delta, alert, note, text, textarea, empty_space, table
Formatação de Tabela
As tabelas suportam formatação no nível de coluna e de célula:
Opções de coluna: bold, italic, type ("sparkline" ou "heatmap")
{
"type": "table",
"columns": [
{"id": "product", "title": "Product", "bold": true},
{"id": "category", "title": "Category", "italic": true},
{"id": "sales", "title": "Sales", "fmt": "currency"},
{"id": "margin", "title": "Margin", "type": "heatmap", "fmt": "pct"},
{"id": "trend", "title": "Trend", "type": "sparkline", "sparkType": "line"}
],
"data": [
{"product": "Widget", "category": "Electronics", "sales": 125000, "margin": 0.85, "trend": [85, 92, 88, 95, 102, 125]}
]
}
Substituições no nível da célula: Use {"value": "text", "bold": true} para substituir os padrões da coluna.
Heatmap: Aplica gradiente de cor de valores baixos a altos. O texto alterna automaticamente para branco em fundos escuros.
Tipos de sparkline: line, bar, area, pct_bar (barra de progresso), dumbbell (comparação antes/depois)
Classificar e filtrar:
| Campo | Valores | Padrão | Efeito |
|---|---|---|---|
sortable | true / false | true | Clique em um cabeçalho de coluna para classificar. Cicla asc → desc → desligado. Colunas numéricas classificam pelo valor bruto. |
filter | true / false | false | Quando verdadeiro, renderiza um campo de pesquisa "Filtrar por qualquer valor…" acima da tabela. As linhas são filtradas ao vivo por correspondência de conteúdo insensível a maiúsculas/minúsculas em todas as células. |
Exemplo: {"type": "table", "filter": true, "columns": [...], "data": [...]}
Tipos de Nota
As notas suportam três níveis de severidade via noteType:
| Tipo | Cor da Borda | Uso |
|---|---|---|
default | Vermelha | Avisos importantes (padrão) |
warning | Amarela | Cuidados, dados preliminares |
tip | Verde | Melhores práticas, dicas profissionais |
As notas também suportam um label opcional para texto de prefixo em negrito:
{"type": "note", "label": "Dica Profissional:", "content": "Use atalhos de teclado para navegação mais rápida.", "noteType": "tip"}
Exemplos de Gráficos Especializados
big_value - Métricas de destaque com exibição grande:
{"type": "big_value", "value": 1250000, "label": "Revenue", "format": "currency0m"}
- Objeto
comparisonopcional:{"value": 10300, "format": "currency", "label": "vs last month"}mostra a mudança com seta
dumbbell - Comparações antes/depois com coloração direcional:
{
"type": "dumbbell",
"title": "ELO Changes",
"category": "team",
"start": "before",
"end": "after",
"startLabel": "Week 1",
"endLabel": "Week 2",
"higherIsBetter": true,
"data": [
{"team": "Chiefs", "before": 1650, "after": 1720},
{"team": "Bills", "before": 1600, "after": 1550}
]
}
- Verde = melhoria, Vermelho = declínio, Cinza = sem mudança
higherIsBetter: falsepara classificações (menor = melhor)- Rótulos abreviaram automaticamente números grandes (7450 → "7k")
delta - Métricas de mudança com coloração direcional:
{"type": "delta", "value": 0.15, "label": "MoM Growth", "format": "pct0"}
- Valores positivos mostram verde com ▲, negativos mostram vermelho com ▼
- Objeto
comparisonopcional:{"value": 0.05, "label": "vs Target"}
area - Gráfico de área preenchida para dados cumulativos/volume:
{
"type": "area",
"title": "Daily Active Users",
"x": "date",
"y": "users",
"data": [{"date": "Mon", "users": 1200}, {"date": "Tue", "users": 1450}]
}
combo - Barras + linhas com eixo Y duplo:
{
"type": "combo",
"title": "Revenue vs Growth Rate",
"x": "quarter",
"y": ["revenue", "growth_rate"],
"data": [
{"quarter": "Q1", "revenue": 1000000, "growth_rate": 0.15},
{"quarter": "Q2", "revenue": 1200000, "growth_rate": 0.20}
]
}
- O primeiro campo y é renderizado como barras, o segundo como linha
- Eixos Y duplos com escalas independentes
heatmap - Visualização de matriz 2D:
{
"type": "heatmap",
"title": "Activity by Hour",
"xCategories": ["Mon", "Tue", "Wed", "Thu", "Fri"],
"yCategories": ["9am", "12pm", "3pm", "6pm"],
"format": "num0",
"data": [[0, 0, 85], [1, 0, 90], [2, 0, 72]]
}
- A opção
formatse aplica aos rótulos das células (por exemplo,num0k,currency0k,pct)
funnel - Fluxos de conversão ou eliminação:
{
"type": "funnel",
"title": "Sales Pipeline",
"format": "num0",
"data": [
{"stage": "Leads", "value": 1000},
{"stage": "Qualified", "value": 600},
{"stage": "Proposal", "value": 300},
{"stage": "Closed", "value": 100}
]
}
- A opção
formatse aplica aos rótulos/dicas de ferramenta (por exemplo,currency_auto,pct,num0)
waterfall - Visualização de mudança cumulativa:
{
"type": "waterfall",
"title": "Revenue Bridge",
"x": "item",
"y": "value",
"data": [
{"item": "Start", "value": 1000, "isTotal": true},
{"item": "Growth", "value": 200},
{"item": "Churn", "value": -50},
{"item": "End", "value": 1150, "isTotal": true}
]
}
bubble - Dispersão com dimensão de tamanho. Suporta series para agrupamento por cor e showLabels