query(" SELECT ft.filamentName, ft.brand, ft.material, ft.color, ft.amazonUrl, fp.price, fp.recordedAt FROM filamentTracker ft JOIN filamentPriceHistory fp ON ft.id = fp.filamentId JOIN ( SELECT filamentId, recordedAt FROM ( SELECT filamentId, recordedAt, ROW_NUMBER() OVER (PARTITION BY filamentId ORDER BY recordedAt DESC) as rn FROM filamentPriceHistory ) ranked WHERE rn <= 180 ) filtered ON fp.filamentId = filtered.filamentId AND fp.recordedAt = filtered.recordedAt ORDER BY ft.filamentName, fp.recordedAt ASC "); $filaments = $stmt->fetchAll(PDO::FETCH_ASSOC); $result = []; // Format data for charts (grouped by filament) foreach ($filaments as $filament) { $name = $filament['filamentName']; if (!isset($result[$name])) { $result[$name] = [ 'brand' => $filament['brand'], 'material' => $filament['material'], 'color' => $filament['color'], 'amazonUrl' => $filament['amazonUrl'], 'prices' => [] ]; } $result[$name]['prices'][] = [ 'price' => $filament['price'], 'recordedAt' => $filament['recordedAt'] ]; } // Return as JSON echo json_encode([ 'status' => 'success', 'data' => $result ], JSON_PRETTY_PRINT); } catch (PDOException $e) { echo json_encode([ 'status' => 'error', 'message' => 'Failed to fetch filament prices: ' . $e->getMessage() ]); } ?>