Spaces:
Running
Running
AGORA EU SO GOSTARIA QUE DEPOIS DE PUBLICADO ELE FICASSE ALINHADO E NAO DESCONFIGURASSE AS ESCCRITAS, QUE TODOS SEGUISSEM O MESMO ALINHAMENTO - Follow Up Deployment
2a195cb verified | <html lang="pt-BR"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Painel Financeiro - PMW</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet"> | |
| <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script> | |
| <script> | |
| tailwind.config = { | |
| theme: { | |
| extend: { | |
| colors: { | |
| primary: '#2563eb', | |
| secondary: '#64748b', | |
| success: '#22c55e', | |
| danger: '#ef4444', | |
| warning: '#f59e0b', | |
| info: '#06b6d4', | |
| dark: '#1e293b', | |
| light: '#f8fafc' | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <style> | |
| .card { | |
| transition: transform 0.3s ease, box-shadow 0.3s ease; | |
| } | |
| .card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1); | |
| } | |
| .positive { color: #22c55e; } | |
| .negative { color: #ef4444; } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 font-sans"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <header class="text-center mb-8" data-aos="fade-down"> | |
| <h1 class="text-3xl md:text-4xl font-bold text-dark mb-2">Painel Financeiro PMW</h1> | |
| <p class="text-secondary">Visão geral das finanças por fluxo e real</p> | |
| <!-- Seletor de Período --> | |
| <div class="mt-6 bg-white rounded-lg shadow-md p-4 inline-block"> | |
| <div class="flex items-center space-x-4"> | |
| <span class="text-sm font-medium text-gray-700">Período:</span> | |
| <select id="periodSelect" class="border border-gray-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary"> | |
| <option value="geral">Geral</option> | |
| <option value="01-2024">Janeiro 2024</option> | |
| <option value="02-2024">Fevereiro 2024</option> | |
| <option value="03-2024">Março 2024</option> | |
| <option value="04-2024">Abril 2024</option> | |
| <option value="05-2024">Maio 2024</option> | |
| <option value="06-2024">Junho 2024</option> | |
| <option value="07-2024">Julho 2024</option> | |
| <option value="08-2024">Agosto 2024</option> | |
| <option value="09-2024">Setembro 2024</option> | |
| <option value="10-2024">Outubro 2024</option> | |
| <option value="11-2024">Novembro 2024</option> | |
| <option value="12-2024">Dezembro 2024</option> | |
| </select> | |
| <button onclick="loadData()" class="bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-700 transition-colors text-sm"> | |
| <i data-feather="refresh-cw" class="w-4 h-4 mr-1 inline"></i> | |
| Carregar Dados | |
| </button> | |
| </div> | |
| </div> | |
| </header> | |
| <div id="loadingSpinner" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center"> | |
| <div class="bg-white rounded-lg p-6 flex items-center"> | |
| <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mr-3"></div> | |
| <span>Carregando dados...</span> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-12"> | |
| <!-- Total por Fluxo --> | |
| <div class="card bg-white rounded-xl shadow-md p-6" data-aos="fade-right"> | |
| <h2 class="text-xl font-semibold text-dark mb-6 flex items-center"> | |
| <i data-feather="trending-up" class="mr-2"></i> Total por Fluxo | |
| </h2> | |
| <div class="grid grid-cols-3 gap-4 text-center"> | |
| <div class="p-4 bg-blue-50 rounded-lg"> | |
| <p class="text-sm text-secondary mb-1">Receita</p> | |
| <p class="text-2xl font-bold text-primary" data-summary="revenue">R$ 634.182,54</p> | |
| <p class="text-sm">100%</p> | |
| </div> | |
| <div class="p-4 bg-red-50 rounded-lg"> | |
| <p class="text-sm text-secondary mb-1">Despesa</p> | |
| <p class="text-2xl font-bold text-danger" data-summary="expenses">R$ 635.407,39</p> | |
| <p class="text-sm">100,19%</p> | |
| </div> | |
| <div class="p-4 bg-green-50 rounded-lg"> | |
| <p class="text-sm text-secondary mb-1">Diferença</p> | |
| <p class="text-2xl font-bold negative" data-summary="difference">R$ -1.224,85</p> | |
| <p class="text-sm negative" data-summary="difference-percentage">-0,19%</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Total Real --> | |
| <div class="card bg-white rounded-xl shadow-md p-6" data-aos="fade-left"> | |
| <h2 class="text-xl font-semibold text-dark mb-6 flex items-center"> | |
| <i data-feather="dollar-sign" class="mr-2"></i> Total Real | |
| </h2> | |
| <div class="grid grid-cols-3 gap-4 text-center"> | |
| <div class="p-4 bg-blue-50 rounded-lg"> | |
| <p class="text-sm text-secondary mb-1">Receita Real</p> | |
| <p class="text-2xl font-bold text-primary" data-summary="revenue-real">R$ 633.592,54</p> | |
| <p class="text-sm">100%</p> | |
| </div> | |
| <div class="p-4 bg-red-50 rounded-lg"> | |
| <p class="text-sm text-secondary mb-1">Despesa Real</p> | |
| <p class="text-2xl font-bold text-danger" data-summary="expenses-real">R$ 509.423,64</p> | |
| <p class="text-sm">80,39%</p> | |
| </div> | |
| <div class="p-4 bg-green-50 rounded-lg"> | |
| <p class="text-sm text-secondary mb-1">Diferença Real</p> | |
| <p class="text-2xl font-bold positive" data-summary="difference-real">R$ 124.168,90</p> | |
| <p class="text-sm positive" data-summary="difference-real-percentage">19,61%</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Gráfico Pizza - Despesas por Categoria --> | |
| <div class="card bg-white rounded-xl shadow-md p-6 mb-12" data-aos="fade-up"> | |
| <h2 class="text-xl font-semibold text-dark mb-6 flex items-center"> | |
| <i data-feather="pie-chart" class="mr-2"></i> Despesas por Categoria | |
| </h2> | |
| <div class="h-80"> | |
| <canvas id="pieChart"></canvas> | |
| </div> | |
| </div> | |
| <!-- Gráfico por Centro de Custo - Versão Simplificada --> | |
| <div class="card bg-white rounded-xl shadow-md p-6" data-aos="fade-up"> | |
| <h2 class="text-xl font-semibold text-dark mb-6 flex items-center"> | |
| <i data-feather="bar-chart-2" class="mr-2"></i> Análise por Centro de Custo | |
| </h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <!-- Gráfico de Receitas por Centro de Custo --> | |
| <div> | |
| <h3 class="text-lg font-medium text-primary mb-4">Receitas</h3> | |
| <div class="h-64"> | |
| <canvas id="revenueChart"></canvas> | |
| </div> | |
| </div> | |
| <!-- Gráfico de Despesas por Centro de Custo --> | |
| <div> | |
| <h3 class="text-lg font-medium text-danger mb-4">Despesas</h3> | |
| <div class="h-64"> | |
| <canvas id="expensesChart"></canvas> | |
| </div> | |
| </div> | |
| <!-- Tabela de Diferenças --> | |
| <div class="md:col-span-2"> | |
| <h3 class="text-lg font-medium text-dark mb-4">Resultado Líquido (Diferença)</h3> | |
| <div class="overflow-x-auto"> | |
| <table class="w-full text-sm text-left"> | |
| <thead class="bg-gray-100"> | |
| <tr> | |
| <th class="px-4 py-2">Centro de Custo</th> | |
| <th class="px-4 py-2">Diferença</th> | |
| <th class="px-4 py-2">Diferença Real</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr class="border-b"> | |
| <td class="px-4 py-2 font-medium">ADMINISTRATIVO</td> | |
| <td class="px-4 py-2 negative">R$ -170.129,37<br><span class="text-xs">(-214,2%)</span></td> | |
| <td class="px-4 py-2 negative">R$ -57.049,33<br><span class="text-xs">(-280,0%)</span></td> | |
| </tr> | |
| <tr class="border-b"> | |
| <td class="px-4 py-2 font-medium">CRIAÇÃO DE GADO</td> | |
| <td class="px-4 py-2 negative">R$ -10.604,53<br><span class="text-xs">(-100%)</span></td> | |
| <td class="px-4 py-2">R$ 0,00<br><span class="text-xs">(0%)</span></td> | |
| </tr> | |
| <tr class="border-b"> | |
| <td class="px-4 py-2 font-medium">FRETE</td> | |
| <td class="px-4 py-2 positive">R$ 27.310,78<br><span class="text-xs">(15,7%)</span></td> | |
| <td class="px-4 py-2 positive">R$ 39.624,49<br><span class="text-xs">(22,7%)</span></td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2 font-medium">PRODUÇÃO</td> | |
| <td class="px-4 py-2 positive">R$ 152.198,27<br><span class="text-xs">(33,2%)</span></td> | |
| <td class="px-4 py-2 positive">R$ 152.198,27<br><span class="text-xs">(33,2%)</span></td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Resultado Analítico do Centro de Custo Frete --> | |
| <div class="card bg-white rounded-xl shadow-md p-6 mt-12" data-aos="fade-up"> | |
| <h2 class="text-xl font-semibold text-dark mb-6 flex items-center"> | |
| <i data-feather="truck" class="mr-2"></i> Resultado Analítico do Centro de Custo Frete | |
| </h2> | |
| <div class="overflow-x-auto"> | |
| <table class="w-full text-sm text-left"> | |
| <thead class="bg-gray-100"> | |
| <tr> | |
| <th class="px-4 py-2">Veículo</th> | |
| <th class="px-4 py-2">Receita</th> | |
| <th class="px-4 py-2">Despesa</th> | |
| <th class="px-4 py-2">Diferença</th> | |
| <th class="px-4 py-2">Ações</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr class="border-b"> | |
| <td class="px-4 py-2 font-medium">PMW CAMINHAO 9-160</td> | |
| <td class="px-4 py-2">R$ 6.124,00</td> | |
| <td class="px-4 py-2 negative">R$ -17.125,03</td> | |
| <td class="px-4 py-2 negative">R$ -11.001,03</td> | |
| <td class="px-4 py-2"> | |
| <button onclick="showDetails('9-160')" class="text-primary hover:text-blue-700 flex items-center"> | |
| <i data-feather="eye" class="w-4 h-4 mr-1"></i> Detalhes | |
| </button> | |
| </td> | |
| </tr> | |
| <tr class="border-b"> | |
| <td class="px-4 py-2 font-medium">PMW HYUNDAI</td> | |
| <td class="px-4 py-2">R$ 7.101,14</td> | |
| <td class="px-4 py-2 negative">R$ -10.485,46</td> | |
| <td class="px-4 py-2 negative">R$ -3.384,32</td> | |
| <td class="px-4 py-2"> | |
| <button onclick="showDetails('hyundai')" class="text-primary hover:text-blue-700 flex items-center"> | |
| <i data-feather="eye" class="w-4 h-4 mr-1"></i> Detalhes | |
| </button> | |
| </td> | |
| </tr> | |
| <tr class="border-b"> | |
| <td class="px-4 py-2 font-medium">PMW CARRETA ACTROS</td> | |
| <td class="px-4 py-2">R$ 89.993,97</td> | |
| <td class="px-4 py-2 negative">R$ -59.388,41</td> | |
| <td class="px-4 py-2 positive">R$ 30.605,56</td> | |
| <td class="px-4 py-2"> | |
| <button onclick="showDetails('actros')" class="text-primary hover:text-blue-700 flex items-center"> | |
| <i data-feather="eye" class="w-4 h-4 mr-1"></i> Detalhes | |
| </button> | |
| </td> | |
| </tr> | |
| <tr class="border-b"> | |
| <td class="px-4 py-2 font-medium">PMW CAMINHÃO VM</td> | |
| <td class="px-4 py-2">R$ 0,00</td> | |
| <td class="px-4 py-2 negative">R$ -173,99</td> | |
| <td class="px-4 py-2 negative">R$ -173,99</td> | |
| <td class="px-4 py-2"> | |
| <button onclick="showDetails('vm')" class="text-primary hover:text-blue-700 flex items-center"> | |
| <i data-feather="eye" class="w-4 h-4 mr-1"></i> Detalhes | |
| </button> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2 font-medium">PMW IVECO</td> | |
| <td class="px-4 py-2">R$ 71.206,04</td> | |
| <td class="px-4 py-2 negative">R$ -51.324,86</td> | |
| <td class="px-4 py-2 positive">R$ 19.881,18</td> | |
| <td class="px-4 py-2"> | |
| <button onclick="showDetails('iveco')" class="text-primary hover:text-blue-700 flex items-center"> | |
| <i data-feather="eye" class="w-4 h-4 mr-1"></i> Detalhes | |
| </button> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| <!-- Modal de Detalhes --> | |
| <div id="detailsModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50"> | |
| <div class="bg-white rounded-xl p-6 max-w-4xl w-full mx-4 max-h-[80vh] overflow-y-auto"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-lg font-semibold" id="modalTitle">Detalhes do Veículo</h3> | |
| <button onclick="hideDetails()" class="text-gray-500 hover:text-gray-700"> | |
| <i data-feather="x"></i> | |
| </button> | |
| </div> | |
| <div id="modalContent"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Dados detalhados por veículo | |
| const vehicleDetails = { | |
| '9-160': { | |
| title: 'PMW CAMINHAO 9-160 - Detalhamento de Despesas', | |
| items: [ | |
| { description: 'Alimentação (9-160)', value: -30.00 }, | |
| { description: 'Combustivel (9-160)', value: -5533.93 }, | |
| { description: 'PEÇAS (9-160)', value: -90.09 }, | |
| { description: 'Pedagios (9-160)', value: -691.95 }, | |
| { description: 'PNEU (9-160)', value: -2370.43 }, | |
| { description: 'Manutenção de veiculo (9-160)', value: -1356.83 }, | |
| { description: 'Seguro de Veiculo (9-160)', value: -3000.14 }, | |
| { description: 'IMPOSTOS (9-160)', value: -187.86 }, | |
| { description: 'Salario (9-160)', value: -1894.00 }, | |
| { description: 'Mao de obra terceirizada (9-160)', value: -1050.00 }, | |
| { description: 'Seguro de vida (9-160)', value: -40.00 }, | |
| { description: 'INVESTIMENTO (9-160)', value: -879.80 } | |
| ], | |
| total: -17125.03 | |
| }, | |
| 'hyundai': { | |
| title: 'PMW HYUNDAI - Detalhamento de Despesas', | |
| items: [ | |
| { description: 'Alimentação (HYUNDAI)', value: -250.00 }, | |
| { description: 'Seguro de Veiculos (HYUNDAI)', value: -3534.08 }, | |
| { description: 'Combustivel (HYUNDAI)', value: -2906.55 }, | |
| { description: 'Peças (HYUNDAI)', value: -786.00 }, | |
| { description: 'Pedagios (HYUNDAI)', value: -390.14 }, | |
| { description: 'Pneu (HYUNDAI)', value: -774.92 }, | |
| { description: 'Salario (HYUNDAI)', value: -1800.00 }, | |
| { description: 'Seguro de vida (HYUNDAI)', value: -43.77 } | |
| ], | |
| total: -10485.46 | |
| }, | |
| 'actros': { | |
| title: 'PMW CARRETA ACTROS - Detalhamento de Despesas', | |
| items: [ | |
| { description: 'COMBUSTIVEL ACTROS', value: -27213.57 }, | |
| { description: 'PEDAGIOS ACTROS', value: -925.12 }, | |
| { description: 'PEÇAS ACTROS', value: -6364.23 }, | |
| { description: 'PNEU ACTROS', value: -2596.14 }, | |
| { description: 'MANUTENÇÃO DE VEICULOS ACTROS', value: -7232.55 }, | |
| { description: 'SEGURO DE VEÍCULOS ACTROS', value: -2369.89 }, | |
| { description: 'Multas de Transito (ACTROS)', value: -104.13 }, | |
| { description: 'IMPOSTO ACTROS', value: -1694.31 }, | |
| { description: 'SALARIO ACTROS', value: -9974.00 }, | |
| { description: 'MAO DE OBRA TERCERIZADA ACTROS', value: -300.00 }, | |
| { description: 'SEGURO DE VIDA ACTROS', value: -43.50 }, | |
| { description: 'INVESTIMENTO ACTROS', value: -570.97 } | |
| ], | |
| total: -59388.41 | |
| }, | |
| 'vm': { | |
| title: 'PMW CAMINHÃO VM - Detalhamento de Despesas', | |
| items: [ | |
| { description: 'SEGURO DE VEÍCULO VM', value: -173.99 } | |
| ], | |
| total: -173.99 | |
| }, | |
| 'iveco': { | |
| title: 'PMW IVECO - Detalhamento de Despesas', | |
| items: [ | |
| { description: 'COMBUSTIVEL IVECO', value: -19714.09 }, | |
| { description: 'PEÇAS IVECO', value: -1052.98 }, | |
| { description: 'PEDAGIOS IVECO', value: -293.40 }, | |
| { description: 'PNEUS IVECO', value: -4242.90 }, | |
| { description: 'SEGURO DE VEICULOS IVECO', value: -441.68 }, | |
| { description: 'IMPOSTO IVECO', value: -756.87 }, | |
| { description: 'SALARIO IVECO', value: -13960.00 }, | |
| { description: 'INVESTIMENTO EVECO', value: -10862.94 } | |
| ], | |
| total: -51324.86 | |
| } | |
| }; | |
| function showDetails(vehicle) { | |
| const modal = document.getElementById('detailsModal'); | |
| const title = document.getElementById('modalTitle'); | |
| const content = document.getElementById('modalContent'); | |
| const data = vehicleDetails[vehicle]; | |
| title.textContent = data.title; | |
| // Ordenar itens por valor (decrescente) | |
| const sortedItems = [...data.items].sort((a, b) => Math.abs(b.value) - Math.abs(a.value)); | |
| let html = ` | |
| <div class="overflow-x-auto"> | |
| <table class="w-full text-sm"> | |
| <thead class="bg-gray-100"> | |
| <tr> | |
| <th class="px-4 py-2 text-left">Descrição</th> | |
| <th class="px-4 py-2 text-right">Valor</th> | |
| <th class="px-4 py-2 text-right">% do Total</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| `; | |
| sortedItems.forEach(item => { | |
| const percentage = ((Math.abs(item.value) / Math.abs(data.total)) * 100).toFixed(1); | |
| html += ` | |
| <tr class="border-b"> | |
| <td class="px-4 py-2">${item.description}</td> | |
| <td class="px-4 py-2 text-right ${item.value < 0 ? 'negative' : 'positive'}"> | |
| R$ ${Math.abs(item.value).toLocaleString('pt-BR', {minimumFractionDigits: 2})} | |
| </td> | |
| <td class="px-4 py-2 text-right text-secondary"> | |
| ${percentage}% | |
| </td> | |
| </tr> | |
| `; | |
| }); | |
| html += ` | |
| </tbody> | |
| <tfoot class="bg-gray-50"> | |
| <tr> | |
| <td class="px-4 py-2 font-semibold">Total Despesas</td> | |
| <td class="px-4 py-2 text-right font-semibold negative"> | |
| R$ ${Math.abs(data.total).toLocaleString('pt-BR', {minimumFractionDigits: 2})} | |
| </td> | |
| <td class="px-4 py-2 text-right font-semibold">100%</td> | |
| </tr> | |
| </tfoot> | |
| </table> | |
| </div> | |
| `; | |
| content.innerHTML = html; | |
| modal.classList.remove('hidden'); | |
| modal.classList.add('flex'); | |
| feather.replace(); | |
| } | |
| function hideDetails() { | |
| const modal = document.getElementById('detailsModal'); | |
| modal.classList.remove('flex'); | |
| modal.classList.add('hidden'); | |
| } | |
| // Inicializar AOS e Feather Icons | |
| document.addEventListener('DOMContentLoaded', function() { | |
| AOS.init({ | |
| duration: 800, | |
| easing: 'ease-in-out', | |
| once: true | |
| }); | |
| feather.replace(); | |
| // Dados para os gráficos | |
| const pieValues = [208094.81, 99710.82, 41514.57, 17328.39, 858.65, 267900.15]; | |
| const pieLabels = [ | |
| '2.01-GASTOS ADMINISTRATIVOS', | |
| '2.02-GASTOS COM PESSOAL', | |
| '2.03-GASTOS FINANCEIROS', | |
| '2.04-GASTOS TRIBUTARIOS', | |
| '2.05-INVESTIMENTOS', | |
| '2.08-CUSTO MATERIA PRIMA' | |
| ]; | |
| // Calcular totais e porcentagens | |
| const totalPie = pieValues.reduce((sum, value) => sum + value, 0); | |
| const piePercentages = pieValues.map(value => ((value / totalPie) * 100).toFixed(1)); | |
| // Ordenar dados em ordem decrescente | |
| const pieDataSorted = pieLabels.map((label, index) => ({ | |
| label, | |
| value: pieValues[index], | |
| percentage: piePercentages[index] | |
| })).sort((a, b) => b.value - a.value); | |
| const pieData = { | |
| labels: pieDataSorted.map(item => `${item.label} (${item.percentage}%)`), | |
| datasets: [{ | |
| data: pieDataSorted.map(item => item.value), | |
| backgroundColor: [ | |
| '#3b82f6', '#ef4444', '#f59e0b', '#10b981', '#8b5cf6', '#ec4899' | |
| ], | |
| borderWidth: 2, | |
| borderColor: '#ffffff' | |
| }] | |
| }; | |
| const revenueData = { | |
| labels: ['ADMINISTRATIVO', 'CRIAÇÃO DE GADO', 'FRETE', 'PRODUÇÃO'], | |
| datasets: [{ | |
| label: 'Receita', | |
| data: [793.81, 0, 174425.15, 458963.58], | |
| backgroundColor: '#3b82f6', | |
| borderColor: '#2563eb', | |
| borderWidth: 1 | |
| }] | |
| }; | |
| const expensesData = { | |
| labels: ['ADMINISTRATIVO', 'CRIAÇÃO DE GADO', 'FRETE', 'PRODUÇÃO'], | |
| datasets: [{ | |
| label: 'Despesa', | |
| data: [170923.18, 10604.53, 147114.37, 306765.31], | |
| backgroundColor: '#ef4444', | |
| borderColor: '#dc2626', | |
| borderWidth: 1 | |
| }] | |
| }; | |
| // Configurações dos gráficos | |
| const pieConfig = { | |
| type: 'pie', | |
| data: pieData, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| legend: { | |
| position: 'right', | |
| labels: { | |
| font: { | |
| size: 12 | |
| }, | |
| padding: 20 | |
| } | |
| }, | |
| tooltip: { | |
| callbacks: { | |
| label: function(context) { | |
| return context.label + ': R$ ' + context.raw.toLocaleString('pt-BR'); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }; | |
| const revenueConfig = { | |
| type: 'bar', | |
| data: revenueData, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| scales: { | |
| y: { | |
| beginAtZero: true, | |
| ticks: { | |
| callback: function(value) { | |
| return 'R$ ' + value.toLocaleString('pt-BR'); | |
| } | |
| } | |
| } | |
| }, | |
| plugins: { | |
| legend: { | |
| display: false | |
| }, | |
| tooltip: { | |
| callbacks: { | |
| label: function(context) { | |
| return 'Receita: R$ ' + context.raw.toLocaleString('pt-BR'); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }; | |
| const expensesConfig = { | |
| type: 'bar', | |
| data: expensesData, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| scales: { | |
| y: { | |
| beginAtZero: true, | |
| ticks: { | |
| callback: function(value) { | |
| return 'R$ ' + value.toLocaleString('pt-BR'); | |
| } | |
| } | |
| } | |
| }, | |
| plugins: { | |
| legend: { | |
| display: false | |
| }, | |
| tooltip: { | |
| callbacks: { | |
| label: function(context) { | |
| return 'Despesa: R$ ' + context.raw.toLocaleString('pt-BR'); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }; | |
| // Criar os gráficos | |
| const pieChart = new Chart(document.getElementById('pieChart'), pieConfig); | |
| const revenueChart = new Chart(document.getElementById('revenueChart'), revenueConfig); | |
| const expensesChart = new Chart(document.getElementById('expensesChart'), expensesConfig); | |
| // Carregar dados iniciais | |
| loadData(); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |