document.addEventListener("DOMContentLoaded", () => {
// --- Configurações Globais ---
const updateInterval = 2000; // 2 segundos
let intervalId = null;
let isPaused = false;
const maxDataPoints = 15; // 15 pontos * 2s = 30s de dados
// --- Elementos do DOM ---
const toggleUpdatesBtn = document.getElementById('toggleUpdatesBtn');
const statusText = document.getElementById('statusText');
// Widgets da Sidebar
const currentTempSpan = document.getElementById('currentTemp');
const currentHumiditySpan = document.getElementById('currentHumidity');
const currentWindSpan = document.getElementById('currentWind');
const currentPressureSpan = document.getElementById('currentPressure');
// Texto dos Medidores
const umidadeText = document.getElementById('umidadeText');
const uvText = document.getElementById('uvText');
// --- Configurações Globais do Chart.js para o Tema Dark ---
Chart.defaults.color = '#aaaaaa'; // Cor da fonte (eixos, legendas)
Chart.defaults.borderColor = 'rgba(255, 255, 255, 0.1)'; // Cor das linhas do grid
// --- Helper para Gradiente ---
function createChartGradient(ctx, color) {
const gradient = ctx.createLinearGradient(0, 0, 0, 400);
// Pega a cor das variáveis CSS. Ex: 'var(--temp-color)'
let colorHex = getComputedStyle(document.documentElement).getPropertyValue(color.match(/\((.*?)\)/)[1]).trim();
// Converte hex para rgba
const r = parseInt(colorHex.slice(1, 3), 16);
const g = parseInt(colorHex.slice(3, 5), 16);
const b = parseInt(colorHex.slice(5, 7), 16);
gradient.addColorStop(0, `rgba(${r}, ${g}, ${b}, 0.6)`);
gradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 0.05)`);
return gradient;
}
// --- PARTE 1: SIMULAÇÃO DA API ---
// QUANDO FOR USAR A API REAL, VOCÊ VAI APAGAR ESTA FUNÇÃO
function simularApiDaEstacao() {
const temperatura = (Math.random() * 10 + 15).toFixed(1); // 15.0 - 25.0
const umidade = (Math.random() * 30 + 50).toFixed(0); // 50 - 80
const vento = (Math.random() * 15 + 5).toFixed(1); // 5.0 - 20.0
const pressao = (Math.random() * 20 + 1000).toFixed(0); // 1000 - 1020
const uv = Math.floor(Math.random() * 11); // 0 - 10
const visibilidade = (Math.random() * 15 + 5).toFixed(1); // 5.0 - 20.0
return {
timestamp: new Date(),
temperatura: parseFloat(temperatura),
umidade: parseInt(umidade),
vento: parseFloat(vento),
pressao: parseInt(pressao),
uv: parseInt(uv),
visibilidade: parseFloat(visibilidade)
};
}
// API REAL
/*
async function fetchApiReal() {
const url = 'http://URL_DA_SUA_API_PYTHON/dados';
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Erro na API: ${response.statusText}`);
}
const data = await response.json();
// Adiciona o timestamp, já que a API pode não mandar
data.timestamp = new Date();
return data;
} catch (error) {
console.error("Falha ao buscar dados da API", error);
// Retorna nulo para não quebrar o dashboard
return null;
}
}
*/
// --- PARTE 2: INICIALIZAÇÃO DOS GRÁFICOS ---
// // 1. Gráfico de Linha (Temperatura & Pressão) - 2 eixos Y
// const ctxTempPressao = document.getElementById('graficoTempPressao').getContext('2d');
// const graficoTempPressao = new Chart(ctxTempPressao, {
// type: 'line',
// data: {
// labels: [],
// datasets: [
// {
// label: 'Temperatura',
// data: [],
// borderColor: 'var(--temp-color)',
// backgroundColor: createChartGradient(ctxTempPressao, 'var(--temp-color)'),
// fill: true,
// tension: 0.4,
// yAxisID: 'yTemp' // Associa ao eixo Y da temperatura
// },
// {
// label: 'Pressão',
// data: [],
// borderColor: 'var(--pressure-color)',
// backgroundColor: createChartGradient(ctxTempPressao, 'var(--pressure-color)'),
// fill: true,
// tension: 0.4,
// yAxisID: 'yPressure' // Associa ao eixo Y da pressão
// }
// ]
// },
// options: {
// responsive: true,
// maintainAspectRatio: false,
// interaction: { mode: 'index', intersect: false },
// scales: {
// x: {
// type: 'time',
// time: { unit: 'second', displayFormats: { second: 'HH:mm:ss' } },
// ticks: { maxRotation: 0, autoSkip: true, maxTicksLimit: 6 }
// },
// yTemp: { // Eixo Y da Esquerda (Temperatura)
// type: 'linear',
// position: 'left',
// grid: { drawOnChartArea: false }, // Remove grid deste eixo
// ticks: { callback: value => `${value} °C` }
// },
// yPressure: { // Eixo Y da Direita (Pressão)
// type: 'linear',
// position: 'right',
// ticks: { callback: value => `${value} hPa` }
// }
// },
// plugins: {
// legend: { position: 'top' },
// tooltip: {
// backgroundColor: '#000',
// titleFont: { weight: 'bold' },
// bodySpacing: 4,
// padding: 10,
// borderColor: 'var(--border-color)',
// borderWidth: 1
// }
// }
// }
// });
// // 2. Medidor de Umidade (Doughnut)
// const graficoUmidade = new Chart(document.getElementById('graficoUmidade').getContext('2d'), {
// type: 'doughnut',
// data: {
// datasets: [{
// data: [0, 100], // Valor, Restante
// backgroundColor: ['var(--humidity-color)', '#2f2f2f'], // Cor da umidade, Cor do fundo
// borderWidth: 0,
// borderRadius: 5
// }]
// },
// options: {
// responsive: true,
// maintainAspectRatio: false,
// circumference: 270, // Arco de 270 graus
// rotation: 225, // Começa no canto inferior esquerdo
// cutout: '80%',
// plugins: { legend: { display: false }, tooltip: { enabled: false } }
// }
// });
// // 3. Medidor de UV (Doughnut)
// const graficoUv = new Chart(document.getElementById('graficoUv').getContext('2d'), {
// type: 'doughnut',
// data: {
// datasets: [{
// data: [0, 12], // Valor, Max (escala UV vai ~12)
// backgroundColor: ['var(--uv-color)', '#2f2f2f'], // Cor UV, Cor do fundo
// borderWidth: 0,
// borderRadius: 5
// }]
// },
// options: {
// responsive: true,
// maintainAspectRatio: false,
// circumference: 270,
// rotation: 225,
// cutout: '80%',
// plugins: { legend: { display: false }, tooltip: { enabled: false } }
// }
// });
// // 4. Gráfico de Vento (Barra Vertical)
// const graficoVento = new Chart(document.getElementById('graficoVento').getContext('2d'), {
// type: 'bar',
// data: {
// labels: ['Vento'],
// datasets: [{
// label: 'km/h',
// data: [0],
// backgroundColor: 'var(--accent-color)', // Cor de destaque
// borderRadius: 4
// }]
// },
// options: {
// responsive: true,
// maintainAspectRatio: false,
// scales: {
// x: { display: false },
// y: { beginAtZero: true, max: 30 }
// },
// plugins: { legend: { display: false } }
// }
// });
// // 5. Gráfico de Visibilidade (Barra Horizontal)
// const graficoVisibilidade = new Chart(document.getElementById('graficoVisibilidade').getContext('2d'), {
// type: 'bar',
// data: {
// labels: ['Visibilidade'],
// datasets: [{
// label: 'km',
// data: [0],
// backgroundColor: '#9c27b0', // Roxo
// borderRadius: 4
// }]
// },
// options: {
// indexAxis: 'y', // Barra horizontal
// responsive: true,
// maintainAspectRatio: false,
// scales: {
// y: { display: false },
// x: { beginAtZero: true, max: 25 }
// },
// plugins: { legend: { display: false } }
// }
// });
// // --- PARTE 3: FUNÇÃO DE ATUALIZAÇÃO ---
// // Esta função será chamada a cada X segundos
// async function atualizarDashboard() {
// // Mude aqui para usar a API real
// // const dados = await fetchApiReal();
// const dados = simularApiDaEstacao(); // Usando simulação por enquanto
// // Se a API falhar, 'dados' será nulo. Pulamos a atualização.
// if (!dados) {
// return;
// }
// // Atualiza Widgets da Sidebar
// currentTempSpan.textContent = `${dados.temperatura.toFixed(1)} °C`;
// currentHumiditySpan.textContent = `${dados.umidade} %`;
// currentWindSpan.textContent = `${dados.vento.toFixed(1)} km/h`;
// currentPressureSpan.textContent = `${dados.pressao} hPa`;
// // Atualiza Gráfico de Linha (Temp & Pressão)
// const labels = graficoTempPressao.data.labels;
// const tempAtivos = graficoTempPressao.data.datasets[0].data;
// const pressAtivos = graficoTempPressao.data.datasets[1].data;
// labels.push(dados.timestamp);
// tempAtivos.push(dados.temperatura);
// pressAtivos.push(dados.pressao);
// if (labels.length > maxDataPoints) {
// labels.shift();
// tempAtivos.shift();
// pressAtivos.shift();
// }
// graficoTempPressao.update();
// // Atualiza Medidor de Umidade
// umidadeText.textContent = `${dados.umidade}%`;
// graficoUmidade.data.datasets[0].data = [dados.umidade, 100 - dados.umidade];
// graficoUmidade.update();
// // Atualiza Medidor de UV (com cor dinâmica)
// let uvColor;
// if (dados.uv <= 2) { uvColor = '#4caf50'; } // Verde
// else if (dados.uv <= 5) { uvColor = '#fdd835'; } // Amarelo
// else if (dados.uv <= 7) { uvColor = '#ff9800'; } // Laranja
// else { uvColor = '#f44336'; } // Vermelho
// uvText.textContent = dados.uv;
// graficoUv.data.datasets[0].data = [dados.uv, 12 - dados.uv];
// graficoUv.data.datasets[0].backgroundColor[0] = uvColor;
// graficoUv.update();
// // Atualiza Gráfico de Vento
// graficoVento.data.datasets[0].data = [dados.vento];
// graficoVento.update();
// // Atualiza Gráfico de Visibilidade
// graficoVisibilidade.data.datasets[0].data = [dados.visibilidade];
// graficoVisibilidade.update();
// }
// // --- PARTE 4: CONTROLE DE ATUALIZAÇÃO ---
// toggleUpdatesBtn.addEventListener('click', () => {
// isPaused = !isPaused;
// if (isPaused) {
// clearInterval(intervalId);
// intervalId = null;
// toggleUpdatesBtn.innerHTML = ' Retomar';
// statusText.textContent = 'Pausado';
// statusText.style.color = '#ff9800';
// } else {
// startUpdates();
// toggleUpdatesBtn.innerHTML = ' Pausar';
// statusText.textContent = 'Monitorando...';
// statusText.style.color = 'var(--accent-color)';
// }
// });
// function startUpdates() {
// if (intervalId === null) {
// atualizarDashboard(); // Roda uma vez imediatamente
// intervalId = setInterval(atualizarDashboard, updateInterval);
// }
// }
// startUpdates(); // Inicia ao carregar
// });