Path: C:\
<?php
date_default_timezone_set('America/Sao_Paulo');
$fileData = 'quali3x_data.json';
if (file_exists($fileData)) {
$dataJSON = json_decode(file_get_contents($fileData), true);
} else {
die("Dados do relatório não encontrados. Por favor, gere o relatório novamente.");
}
$rt1 = 'Rodolfo Max Welendorf';
$crf1 = 'CRF89988';
$labelsRaw = $dataJSON['labels'];
$tempRaw = $dataJSON['temp'];
$umidRaw = $dataJSON['umid'];
// Formatar timestamps Unix para datas legíveis - intervalo de 1h20 (4800s), sempre mostrando o último
$formattedLabels = [];
$totalRaw = count($labelsRaw);
$intervalo = 3600; // 1 hora em segundos
$ultimoMostrado = -999999;
$ultimoMostradoIdx = -1;
foreach ($labelsRaw as $idx => $ts) {
$tsInt = (int) $ts;
$ehUltimo = ($idx === $totalRaw - 1);
$currentIndex = count($formattedLabels);
if ($ehUltimo) {
if ($ultimoMostradoIdx !== -1 && ($tsInt - $ultimoMostrado) < ($intervalo * 0.8)) {
$formattedLabels[$ultimoMostradoIdx] = '';
}
$formattedLabels[] = date('d/m H:i', $tsInt);
} elseif (($tsInt - $ultimoMostrado) >= $intervalo) {
$formattedLabels[] = date('d/m H:i', $tsInt);
$ultimoMostrado = $tsInt;
$ultimoMostradoIdx = $currentIndex;
} else {
$formattedLabels[] = '';
}
}
// Decimação desativada para manter todos os pontos (aumentado para 5000 para não quebrar)
$maxPoints = 5000;
$totalPoints = count($formattedLabels);
if ($totalPoints > $maxPoints) {
$step = ceil($totalPoints / $maxPoints);
$decimatedLabels = [];
$decimatedTemp = [];
$decimatedUmid = [];
for ($i = 0; $i < $totalPoints; $i += $step) {
$decimatedLabels[] = $formattedLabels[$i];
$decimatedTemp[] = (float) $tempRaw[$i];
$decimatedUmid[] = (float) $umidRaw[$i];
}
$formattedLabels = $decimatedLabels;
$tempRaw = $decimatedTemp;
$umidRaw = $decimatedUmid;
}
$labelsJSON = json_encode($formattedLabels);
// Ensure values are formatted correctly for chart.js
$_tempVals = [];
foreach ($tempRaw as $v) {
$_tempVals[] = (float) $v;
}
$tempJSON = json_encode($_tempVals);
$_umidVals = [];
foreach ($umidRaw as $v) {
$_umidVals[] = (float) $v;
}
$umidJSON = json_encode($_umidVals);
// ── Limites de temperatura (definidos pelo usuário no formulário) ──
$tMinNum = isset($dataJSON['min']) && $dataJSON['min'] !== '' ? (float) $dataJSON['min'] : null;
$tMaxNum = isset($dataJSON['max']) && $dataJSON['max'] !== '' ? (float) $dataJSON['max'] : null;
$limitMinJSON = json_encode($tMinNum !== null ? array_fill(0, count($_tempVals), $tMinNum) : []);
$limitMaxJSON = json_encode($tMaxNum !== null ? array_fill(0, count($_tempVals), $tMaxNum) : []);
// Parse dates for display
$inicioDisplay = str_replace('-', '/', $dataJSON['inicio']) . ' às ' . $dataJSON['hrini'];
$fimDisplay = str_replace('-', '/', $dataJSON['fim']) . ' às ' . $dataJSON['hrfim'];
?>
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Relatório Térmico – <?= htmlspecialchars($dataJSON['veiculo']) ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
@page {
size: auto;
margin: 0mm;
}
@media print {
.no-print {
display: none !important;
}
body {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
padding: 5mm;
}
.report-container {
box-shadow: none;
margin: 0;
padding: 10px 15px;
}
.report-header {
margin-bottom: 10px !important;
padding-bottom: 5px !important;
}
}
body {
background: #e9ecef;
font-family: Arial, sans-serif;
}
.report-container {
max-width: 960px;
margin: 20px auto;
background: #fff;
padding: 30px 35px;
box-shadow: 0 4px 20px rgba(0, 0, 0, .12);
border-radius: 6px;
}
.report-header {
border-bottom: 3px solid #084b8a;
padding-bottom: 15px;
margin-bottom: 20px;
}
.chart-box {
position: relative;
height: 240px;
margin: 10px 0 15px;
}
.stat-table th {
background: #084b8a;
color: #fff;
text-align: center;
}
.signature-line {
border-top: 1px solid #333;
text-align: center;
}
.info-label {
font-weight: bold;
color: #084b8a;
}
</style>
</head>
<body>
<!-- Barra de ações (não imprime) -->
<div class="no-print bg-dark py-2 text-center">
<button onclick="window.print()" class="btn btn-light btn-sm me-2">
<i class="bi bi-printer"></i> Imprimir / Salvar PDF
</button>
<button onclick="window.close()" class="btn btn-secondary btn-sm">Fechar</button>
</div>
<div class="report-container">
<!-- ═══ CABEÇALHO ═══ -->
<div class="report-header row align-items-center">
<div class="col-3">
<img src="logo.png" alt="Logo" style="max-width:100%; max-height:70px;">
</div>
<div class="col-5 text-center">
<h3 class="mb-0 fw-bold">RELATÓRIO TÉRMICO</h3>
</div>
<div class="col-4 text-end" style="font-size:.85rem;">
<p class="mb-0"><strong>Código:</strong> FO.13.01.RT</p>
<p class="mb-0"><strong>Revisão:</strong> 02</p>
<p class="mb-0"><strong>Efetivado em:</strong> 02/03/2026</p>
</div>
</div>
<!-- Elaborado / Aprovado / Validado -->
<div class="row text-center mb-3" style="font-size:.85rem;">
<div class="col-4 border py-1"><strong>ELABORADO POR:</strong><br>EDNA LOPES</div>
<div class="col-4 border py-1"><strong>APROVADO POR:</strong><br>RODOLFO WELENDORF</div>
<div class="col-4 border py-1"><strong>VALIDADO POR:</strong><br>CRISTIANO LOPES</div>
</div>
<!-- ═══ INFORMAÇÕES DO VEÍCULO ═══ -->
<div class="row mb-1">
<div class="col-12">
<table class="table table-bordered table-sm mb-0">
<thead>
<tr style="background:#a4a4a4; color:#000; text-align:center; font-size:12px;">
<th>ORDEM DE COLETA</th>
<th>PLACA</th>
<th>CARRETA</th>
<th>MOTORISTA</th>
<th>INÍCIO DO FILTRO</th>
<th>FIM DO FILTRO</th>
</tr>
</thead>
<tbody>
<tr class="text-center fw-bold" style="font-size:13px;">
<td><?= htmlspecialchars($dataJSON['coleta']) ?></td>
<td><?= htmlspecialchars($dataJSON['veiculo']) ?></td>
<td><?= htmlspecialchars($dataJSON['carreta']) ?></td>
<td><?= htmlspecialchars($dataJSON['motorista']) ?></td>
<td><?= $inicioDisplay ?></td>
<td><?= $fimDisplay ?></td>
</tr>
</tbody>
</table>
</div>
</div>
<?php
$tMin = isset($dataJSON['min']) ? number_format((float) $dataJSON['min'], 1, ',', '.') : '--';
$tMax = isset($dataJSON['max']) ? number_format((float) $dataJSON['max'], 1, ',', '.') : '--';
if ($tMin !== '--' || $tMax !== '--'):
?>
<div class="text-center mb-3 fw-bold border alert alert-success col-8 mx-auto" style="font-size: 18px;">
Temperatura Mínima <?= $tMin ?> ºC | Temperatura Máxima <?= $tMax ?> ºC
</div>
<?php else: ?>
<div class="mb-3"></div>
<?php endif; ?>
<!-- ═══ GRÁFICO DE TEMPERATURA ═══ -->
<h5 class="text-center fw-bold mt-2"><i class="bi bi-thermometer-half text-success"></i> Temperatura (ºC)</h5>
<div class="chart-box">
<canvas id="chartTemp"></canvas>
</div>
<!-- ═══ GRÁFICO DE UMIDADE ═══ -->
<h5 class="text-center fw-bold mt-2"><i class="bi bi-droplet-half text-primary"></i> Umidade (%)</h5>
<div class="chart-box">
<canvas id="chartUmid"></canvas>
</div>
<!-- ═══ ESTATÍSTICAS ═══ -->
<div class="row mt-3">
<div class="col-6">
<table class="table table-bordered table-sm stat-table">
<tr>
<th colspan="2">Umidade</th>
</tr>
<tr>
<td class="info-label">Mínima:</td>
<td class="text-center"><?= number_format((float) $dataJSON['Uminima'], 1, ',', '.') ?> %</td>
</tr>
<tr>
<td class="info-label">Máxima:</td>
<td class="text-center"><?= number_format((float) $dataJSON['Umaxima'], 1, ',', '.') ?> %</td>
</tr>
<tr>
<td class="info-label">Média:</td>
<td class="text-center"><?= number_format((float) $dataJSON['Umedia'], 1, ',', '.') ?> %</td>
</tr>
</table>
</div>
<div class="col-6">
<table class="table table-bordered table-sm stat-table">
<tr>
<th colspan="2">Temperatura</th>
</tr>
<tr>
<td class="info-label">Mínima:</td>
<td class="text-center"><?= number_format((float) $dataJSON['minima'], 1, ',', '.') ?> ºC</td>
</tr>
<tr>
<td class="info-label">Máxima:</td>
<td class="text-center"><?= number_format((float) $dataJSON['maxima'], 1, ',', '.') ?> ºC</td>
</tr>
<tr>
<td class="info-label">Média:</td>
<td class="text-center"><?= number_format((float) $dataJSON['media'], 1, ',', '.') ?> ºC</td>
</tr>
</table>
</div>
</div>
<!-- ═══ ASSINATURAS ═══ -->
<div class="row">
<div class="col-6 text-center">
<img src="images/ass_rodo.png" width="140" style="height: auto; text-align: center !important;"
alt="assinatura_rodolfo">
<div class="signature-line">
<strong>Rodolfo Max Welendorf</strong><br>
<small>Gestor da Qualidade/RT - CRF89988</small>
</div>
</div>
<div class="col-6 text-center mt-1">
<img src="images/edna.png" width="180" style="height: auto;" alt="assinatura_edna">
<div class="signature-line">
<strong>Edna Silva Lopes</strong><br>
<small>Garantia da Qualidade</small>
</div>
</div>
</div>
</div><!-- /report-container -->
<script>
// ── Temperatura ──
new Chart(document.getElementById('chartTemp'), {
type: 'line',
data: {
labels: <?= $labelsJSON ?>,
datasets: [
{
label: 'Leitura (ºC)',
data: <?= $tempJSON ?>,
borderColor: 'rgb(40, 167, 69)',
backgroundColor: 'rgba(40, 167, 69, 0.08)',
borderWidth: 2,
pointRadius: 0,
tension: 0.2,
fill: true
}
<?php if ($tMinNum !== null): ?>
,{
label: 'Limite Mínimo (<?= number_format($tMinNum, 1, ',', '.') ?> ºC)',
data: <?= $limitMinJSON ?>,
borderColor: '#0d6efd',
borderWidth: 2,
pointRadius: 0,
fill: false,
tension: 0
}
<?php endif; ?>
<?php if ($tMaxNum !== null): ?>
,{
label: 'Limite Máximo (<?= number_format($tMaxNum, 1, ',', '.') ?> ºC)',
data: <?= $limitMaxJSON ?>,
borderColor: '#dc3545',
borderWidth: 2,
pointRadius: 0,
fill: false,
tension: 0
}
<?php endif; ?>
]
},
options: {
layout: { padding: { right: 30 } },
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
title: { display: false, text: 'Data / Hora' },
ticks: { autoSkip: false, maxRotation: 45, minRotation: 45, font: { size: 7 } }
},
y: {
suggestedMin: <?= isset($dataJSON['min']) && $dataJSON['min'] !== '' ? ((float) $dataJSON['min'] - 2) : 0 ?>,
suggestedMax: <?= isset($dataJSON['max']) && $dataJSON['max'] !== '' ? ((float) $dataJSON['max'] + 2) : 30 ?>,
title: { display: true, text: 'Temperatura (ºC)' }
}
},
plugins: { legend: { display: true, position: 'top' } }
}
});
// ── Umidade ──
new Chart(document.getElementById('chartUmid'), {
type: 'line',
data: {
labels: <?= $labelsJSON ?>,
datasets: [{
label: 'Leitura (%)',
data: <?= $umidJSON ?>,
borderColor: 'rgb(54, 162, 235)',
backgroundColor: 'rgba(54, 162, 235, 0.08)',
borderWidth: 2,
pointRadius: 0,
tension: 0.4,
fill: true
}]
},
options: {
layout: { padding: { right: 30 } },
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
title: { display: false, text: 'Data / Hora' },
ticks: { autoSkip: false, maxRotation: 45, minRotation: 45, font: { size: 7 } }
},
y: { min: 30, max: 100, title: { display: true, text: 'Umidade (%)' } }
},
plugins: { legend: { display: true, position: 'top' } }
}
});
</script>
</body>
</html>