Skip to content

Cria gráficos 3D interativos no Angular usando Three.js. 4 tipos de gráfico (barras, linhas, pizza, rosca), modo 2D/3D, tooltips, controles de mouse e exporta PNG. É só copiar o componente pro seu projeto e passar os dados. Simples assim!

License

Notifications You must be signed in to change notification settings

maycon-d3v/angular-threejs-charts

Repository files navigation

Angular 3D Charts

Componente de gráficos 3D reutilizável para Angular usando Three.js. Fiz esse projeto pra facilitar a criação de visualizações interativas sem precisar mexer diretamente com WebGL.

Angular Three.js TypeScript License

O que tem aqui?

  • 4 tipos de gráfico: Barras, Linhas, Pizza e Rosca (donut)
  • Modo 2D e 3D: Alterna entre visualização plana e tridimensional
  • Controles interativos: Rotaciona, move e dá zoom com o mouse
  • Tooltips no hover: Mostra os dados quando passa o mouse
  • Customizável: Muda cores, tamanhos e estilos
  • Liga/desliga séries: Clica na legenda pra esconder ou mostrar séries
  • Exporta PNG: Baixa o gráfico como imagem
  • Responsivo: Se adapta ao tamanho do container
  • TypeScript: Tudo tipado certinho

Instalação rápida

1. Instala o Three.js

npm install three@^0.158.0
npm install --save-dev @types/three@^0.158.0

2. Copia a pasta do componente

Pega a pasta chart-3d-threejs e joga no seu projeto Angular:

src/app/components/
└── chart-3d-threejs/
    ├── chart-3d-threejs.component.ts
    ├── chart-3d-threejs.component.html
    ├── chart-3d-threejs.component.css
    └── charts/
        ├── base-chart.ts
        ├── bar-chart.ts
        ├── line-chart.ts
        └── pie-chart.ts

3. Importa no módulo

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { Chart3DThreejsComponent } from './components/chart-3d-threejs/chart-3d-threejs.component';

@NgModule({
  declarations: [
    Chart3DThreejsComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule  // importante pra animações funcionarem
  ]
})
export class AppModule { }

Como usar

Exemplo básico

import { Component } from '@angular/core';
import { Chart3DConfig } from './components/chart-3d-threejs/chart-3d-threejs.component';

@Component({
  selector: 'app-root',
  template: '<app-chart-3d-threejs [chartData]="chartData"></app-chart-3d-threejs>'
})
export class AppComponent {
  chartData: Chart3DConfig = {
    title: 'Vendas Trimestrais',
    type: 'bar',
    mode: '3d',
    labels: ['Q1', 'Q2', 'Q3', 'Q4'],
    series: [
      { name: 'Receita', values: [120, 145, 138, 160] },
      { name: 'Custos', values: [80, 95, 88, 100] }
    ]
  };
}

Pronto! Já vai aparecer um gráfico de barras 3D interativo.

Exemplo com dados de API

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Chart3DConfig } from './components/chart-3d-threejs/chart-3d-threejs.component';

@Component({
  selector: 'app-dashboard',
  template: '<app-chart-3d-threejs [chartData]="chartData"></app-chart-3d-threejs>'
})
export class DashboardComponent implements OnInit {
  chartData!: Chart3DConfig;

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.http.get<any[]>('/api/vendas-mensais').subscribe(dados => {
      this.chartData = {
        title: 'Desempenho Mensal',
        type: 'line',
        mode: '3d',
        labels: dados.map(d => d.mes),
        series: [
          { name: 'Vendas', values: dados.map(d => d.total) }
        ]
      };
    });
  }
}

Tipos de gráfico

Gráfico de Barras

chartData: Chart3DConfig = {
  title: 'Vendas por Região',
  type: 'bar',
  labels: ['Norte', 'Sul', 'Leste', 'Oeste'],
  series: [
    { name: '2023', values: [100, 120, 90, 110] },
    { name: '2024', values: [120, 140, 110, 130] }
  ]
};

Gráfico de Linhas

chartData: Chart3DConfig = {
  title: 'Temperatura ao longo do ano',
  type: 'line',
  labels: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun'],
  series: [
    { name: 'São Paulo', values: [25, 26, 24, 22, 20, 18] },
    { name: 'Rio', values: [30, 31, 29, 27, 25, 23] }
  ]
};

Gráfico Pizza

chartData: Chart3DConfig = {
  title: 'Participação de Mercado',
  type: 'pie',
  labels: ['Produto A', 'Produto B', 'Produto C'],
  series: [
    { name: 'Market Share', values: [450, 320, 230] }
  ]
};

Gráfico Rosca (Donut)

chartData: Chart3DConfig = {
  title: 'Alocação de Orçamento',
  type: 'donut',
  labels: ['Marketing', 'Desenvolvimento', 'Operações'],
  series: [
    { name: 'Orçamento', values: [35000, 50000, 25000] }
  ]
};

Configurações disponíveis

Chart3DConfig

Propriedade Tipo Padrão Descrição
title string? - Título do gráfico
labels string[] obrigatório Rótulos do eixo X
series ChartDataSeries[] obrigatório Array com as séries de dados
type 'bar' | 'line' | 'pie' | 'donut' 'bar' Tipo do gráfico
mode '2d' | '3d' '3d' Modo de visualização
maxHeight number 8 Altura máxima das barras/linhas
barWidth number automático Largura das barras
barDepth number automático Profundidade das barras (3D)
spacing number automático Espaçamento entre barras
showInstructions boolean true Mostra dica de ajuda ao carregar
backgroundColor string '#ffffff' Cor de fundo

ChartDataSeries

Propriedade Tipo Padrão Descrição
name string obrigatório Nome da série
values number[] obrigatório Valores dos dados
color string? automático Cor em hexadecimal (ex: '#3b82f6')

Funcionalidades avançadas

Cores personalizadas

chartData: Chart3DConfig = {
  title: 'Com cores customizadas',
  type: 'bar',
  labels: ['A', 'B', 'C'],
  series: [
    { name: 'Série 1', values: [10, 20, 15], color: '#ef4444' },  // vermelho
    { name: 'Série 2', values: [15, 25, 20], color: '#10b981' },  // verde
    { name: 'Série 3', values: [8, 18, 12] }  // cor automática
  ]
};

Modo 2D para dashboards

Quando você não quer que o usuário fique girando o gráfico (tipo num dashboard estático), usa o modo 2D:

chartData: Chart3DConfig = {
  title: 'Vista fixa',
  type: 'bar',
  mode: '2d',  // desabilita rotação e mostra vista frontal
  labels: ['Q1', 'Q2', 'Q3', 'Q4'],
  series: [
    { name: 'Vendas', values: [100, 120, 110, 140] }
  ]
};

Atualizar dados dinamicamente

export class MeuComponente {
  chartData: Chart3DConfig = { /* config inicial */ };

  atualizarDados(novosDados: number[]) {
    // cria um novo objeto pra triggar o change detection do Angular
    this.chartData = {
      ...this.chartData,
      series: [
        { name: 'Atualizado', values: novosDados }
      ]
    };
  }
}

Dicas de performance

  1. Limite de pontos: Tenta manter menos de 50 pontos por série pra não travar
  2. Usa modo 2D: Se tiver vários gráficos na tela, o modo 2D é mais leve
  3. Desliga as instruções: Em produção, coloca showInstructions: false
  4. Fundo transparente: Se não precisa de fundo, ajuda na performance

Estrutura do código

Organizei tudo de forma modular pra facilitar manutenção:

chart-3d-threejs/
├── chart-3d-threejs.component.ts    # Componente principal
├── chart-3d-threejs.component.html  # Template com toolbar
├── chart-3d-threejs.component.css   # Estilos
└── charts/
    ├── base-chart.ts                # Classe base abstrata
    ├── bar-chart.ts                 # Lógica do gráfico de barras
    ├── line-chart.ts                # Lógica do gráfico de linhas
    └── pie-chart.ts                 # Lógica dos gráficos pizza/donut

Criando novos tipos de gráfico

Se quiser adicionar um novo tipo de gráfico, é só estender a classe BaseChart:

import { BaseChart } from './base-chart';
import * as THREE from 'three';

export class MeuGrafico extends BaseChart {
  create(): void {
    // sua lógica de renderização aqui
    const geometry = new THREE.BoxGeometry(1, 1, 1);
    const material = new THREE.MeshStandardMaterial({ color: 0x3b82f6 });
    const mesh = new THREE.Mesh(geometry, material);
    this.scene.add(mesh);
  }
}

Depois adiciona no switch do componente principal e pronto!

Tecnologias usadas

  • Angular 16: Framework
  • Three.js 0.158: Engine de renderização 3D
  • TypeScript 5.1: Linguagem
  • OrbitControls: Controle de câmera
  • WebGL: Aceleração por GPU

Problemas comuns

Gráfico não aparece

  • Verifica se importou o BrowserAnimationsModule
  • Olha o console do navegador se tem erro do Three.js
  • Confere se o container tem altura definida (não pode ser 0)

Tá lento

  • Diminui o maxHeight
  • Usa menos pontos de dados
  • Muda pra mode: '2d'
  • Reduz o número de séries

Cores não aparecem

  • Usa formato hex nas cores (ex: '#3b82f6')
  • Verifica se os valores não são todos zero
  • Confere se a série tá visível na legenda

Navegadores suportados

Funciona em todos os navegadores modernos:

  • Chrome (recomendado)
  • Firefox
  • Safari
  • Edge
  • Navegadores mobile (com suporte a touch)

Licença

MIT - usa à vontade em projetos comerciais e pessoais.

Contribuindo

Pull requests são bem-vindos! Se encontrar algum bug ou tiver sugestões, abre uma issue.


Desenvolvido com Angular e Three.js

About

Cria gráficos 3D interativos no Angular usando Three.js. 4 tipos de gráfico (barras, linhas, pizza, rosca), modo 2D/3D, tooltips, controles de mouse e exporta PNG. É só copiar o componente pro seu projeto e passar os dados. Simples assim!

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published