Spaces:
Runtime error
Runtime error
Download frontend/src/app/dataset/page.tsx from IDKHowToCodeFr/tinyml-backend: direct link, hf CLI and curl.
- Browser
- Download file 15.6 kB
-
https://huggingface.co/spaces/IDKHowToCodeFr/tinyml-backend/resolve/main/frontend/src/app/dataset/page.tsx
- Command line
-
hf download hf://spaces/IDKHowToCodeFr/tinyml-backend/frontend/src/app/dataset/page.tsx
-
curl -L -o page.tsx https://huggingface.co/spaces/IDKHowToCodeFr/tinyml-backend/resolve/main/frontend/src/app/dataset/page.tsx
15.6 kB
| "use client"; | |
| import { useState, useEffect } from "react"; | |
| import { | |
| Database, | |
| Layers, | |
| Download, | |
| Flame, | |
| BarChart3, | |
| PieChart, | |
| TableProperties, | |
| ListFilter, | |
| CheckCircle2, | |
| Cpu, | |
| } from "lucide-react"; | |
| import { DATASET_PROFILE, DatasetProfile } from "@/lib/edge/dataset-profile"; | |
| import CorrelationHeatmap from "@/components/CorrelationHeatmap"; | |
| import FeatureDistributionChart from "@/components/FeatureDistributionChart"; | |
| import CohortBreakdownChart from "@/components/CohortBreakdownChart"; | |
| import FeatureStatsTable from "@/components/FeatureStatsTable"; | |
| import PaginatedRecordInspector from "@/components/PaginatedRecordInspector"; | |
| export default function DatasetPage() { | |
| const [profile, setProfile] = useState<DatasetProfile>(DATASET_PROFILE); | |
| const [activeTab, setActiveTab] = useState< | |
| "heatmap" | "distributions" | "cohorts" | "dictionary" | "records" | |
| >("heatmap"); | |
| const [isLiveApi, setIsLiveApi] = useState(false); | |
| const [showArchNote, setShowArchNote] = useState(false); | |
| useEffect(() => { | |
| const fetchLiveProfile = async () => { | |
| try { | |
| const apiUrl = process.env.NEXT_PUBLIC_API_URL; | |
| if (apiUrl) { | |
| const res = await fetch(`${apiUrl}/dataset/summary`); | |
| if (res.ok) { | |
| const data = await res.json(); | |
| if (data && data.summary && data.feature_stats) { | |
| setProfile((prev) => ({ | |
| ...prev, | |
| ...data, | |
| sample_rows: data.sample_rows || prev.sample_rows, | |
| })); | |
| setIsLiveApi(true); | |
| } | |
| } | |
| } | |
| } catch { | |
| // Fall through to precomputed edge profile | |
| } | |
| }; | |
| fetchLiveProfile(); | |
| }, []); | |
| const handleDownloadCSV = () => { | |
| const apiUrl = process.env.NEXT_PUBLIC_API_URL; | |
| if (apiUrl && isLiveApi) { | |
| const a = document.createElement("a"); | |
| a.href = `${apiUrl}/dataset/download`; | |
| a.download = "heartflow_ground_truth_60k.csv"; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| return; | |
| } | |
| // Client-side fallback download | |
| const rows = profile.sample_rows; | |
| if (!rows.length) return; | |
| const columns = Object.keys(rows[0]); | |
| const headers = columns.join(","); | |
| const csvRows = rows.map((r) => | |
| columns.map((c) => JSON.stringify(r[c] ?? "")).join(",") | |
| ); | |
| const csv = [headers, ...csvRows].join("\n"); | |
| const blob = new Blob([csv], { type: "text/csv" }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement("a"); | |
| a.href = url; | |
| a.download = "heartflow_ground_truth_60k_sample.csv"; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| }; | |
| const { summary, target_distribution, alert_prevalence, feature_stats, correlation_matrix, feature_dependencies, sample_rows } = profile; | |
| return ( | |
| <main className="min-h-dvh bg-canvas-cream flex flex-col font-mono selection:bg-hazard selection:text-white pb-20"> | |
| <div className="max-w-350 mx-auto w-full px-4 sm:px-8 py-10 md:py-12 flex-1 flex flex-col"> | |
| {/* Top Medical Provenance Bar */} | |
| <div className="flex flex-col sm:flex-row sm:items-center justify-between text-[11px] font-bold uppercase tracking-wider text-slate border-b border-ink/20 pb-3 mb-6 gap-2"> | |
| <div className="flex items-center gap-2"> | |
| <span className="w-2 h-2 bg-hazard" /> | |
| <span>IEC-60601-1 TELEMETRY CORPUS 路 N=60,000 OBSERVATIONS</span> | |
| </div> | |
| <div className="flex items-center gap-3"> | |
| <div className="flex items-center gap-1.5"> | |
| <span | |
| className={`w-2 h-2 rounded-full ${ | |
| isLiveApi ? "bg-green-600 animate-pulse" : "bg-hazard" | |
| }`} | |
| /> | |
| <span className="font-mono text-ink"> | |
| {isLiveApi ? "LIVE BACKEND STREAM" : "ZERO-CLOUD EDGE CALIBRATED"} | |
| </span> | |
| </div> | |
| <button | |
| onClick={() => setShowArchNote(!showArchNote)} | |
| className="text-[10px] text-hazard hover:underline font-bold" | |
| > | |
| [ARCHITECTURE SPEC] | |
| </button> | |
| </div> | |
| </div> | |
| {/* Architecture Note Drawer */} | |
| {showArchNote && ( | |
| <div className="mb-8 p-4 bg-white border-2 border-ink shadow-[4px_4px_0px_0px_#141413]"> | |
| <div className="flex items-center justify-between border-b border-ink/20 pb-2 mb-3"> | |
| <div className="text-[12px] font-black uppercase text-hazard flex items-center gap-2"> | |
| <Cpu size={14} /> | |
| ENGINEERING NOTE: WHY AGGREGATIONS & PROFILING REPLACE 60K RECORD DUMPS | |
| </div> | |
| <button | |
| onClick={() => setShowArchNote(false)} | |
| className="text-[11px] text-slate font-bold hover:text-ink uppercase" | |
| > | |
| CLOSE [脳] | |
| </button> | |
| </div> | |
| <div className="text-[12px] font-sans text-ink leading-relaxed space-y-2"> | |
| <p> | |
| <strong>The Bottleneck:</strong> Fetching 60,000 raw rows on the fly generates an ~18 MB JSON payload, blocks Python serialization for multiple seconds, floods frontend memory, and degrades browser UI frame rates. | |
| </p> | |
| <p> | |
| <strong>Industry Standard Solution (Databricks / Snowflake / Kaggle EDA):</strong> HeartFlow OS implements server-side pre-computed statistical profiling (Pearson correlation matrix, 12-bin continuous vital histograms, disease class parity, and parametric summaries) combined with a 25-row paginated inspector. Bandwidth is reduced by <strong>99.8%</strong>, time-to-first-render is <strong>< 50ms</strong>, and memory pressure is eliminated. | |
| </p> | |
| </div> | |
| </div> | |
| )} | |
| {/* Header Hero */} | |
| <header className="mb-8 border-b-4 border-ink pb-8 flex flex-col lg:flex-row justify-between lg:items-end gap-6"> | |
| <div> | |
| <div className="text-[11px] sm:text-[12px] text-hazard font-bold tracking-widest mb-3 flex items-center gap-2 uppercase"> | |
| <Database size={15} /> | |
| CLINICAL TELEMETRY GROUND TRUTH | |
| </div> | |
| <h1 className="text-[clamp(2.2rem,5vw,5.5rem)] leading-[0.9]"> | |
| DATASET<br />EXPLORER | |
| </h1> | |
| <p className="text-[12px] sm:text-[13px] text-slate font-sans mt-3 max-w-2xl leading-relaxed"> | |
| High-volume cardiovascular & multi-parameter telemetry ground truth engine. Explore multivariate feature dependencies, continuous histograms, disease prevalence, and parametric vital metrics across 60,000 clinical patient records. | |
| </p> | |
| </div> | |
| <div className="flex flex-col sm:items-end gap-3 w-full lg:w-auto shrink-0"> | |
| <div className="grid grid-cols-2 sm:flex sm:flex-wrap gap-2 w-full sm:w-auto"> | |
| <div className="px-3 py-2 sm:py-1.5 bg-white border-2 border-ink flex items-center justify-center sm:justify-start text-[11px] sm:text-[12px] font-bold uppercase tracking-wider text-ink shadow-[2px_2px_0px_#141413]"> | |
| <Layers className="w-3.5 h-3.5 mr-1.5 sm:mr-2 text-hazard shrink-0" /> | |
| <span>{summary.total_features} Features</span> | |
| </div> | |
| <div className="px-3 py-2 sm:py-1.5 bg-ink border-2 border-ink text-white flex items-center justify-center sm:justify-start text-[11px] sm:text-[12px] font-bold uppercase tracking-wider shadow-[2px_2px_0px_#9F2F2D]"> | |
| <Database className="w-3.5 h-3.5 mr-1.5 sm:mr-2 text-white shrink-0" /> | |
| <span className="truncate">{summary.total_records.toLocaleString()} Obs</span> | |
| </div> | |
| </div> | |
| <button | |
| onClick={handleDownloadCSV} | |
| className="btn-tactile min-h-11 text-[11px] font-bold uppercase tracking-wider border-2 border-ink px-4 py-2.5 bg-white hover:bg-hazard hover:text-white transition-colors flex items-center justify-center gap-2 w-full sm:w-auto" | |
| > | |
| <Download size={15} /> | |
| <span>Download Ground-Truth CSV (4.49 MB)</span> | |
| </button> | |
| </div> | |
| </header> | |
| {/* 4 Macro KPI HUD Banners */} | |
| <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-4 mb-8"> | |
| <div className="p-4 border-2 border-ink bg-white shadow-[3px_3px_0px_0px_#141413]"> | |
| <div className="text-[10px] font-bold text-slate uppercase tracking-wider"> | |
| Total Observations | |
| </div> | |
| <div className="text-[26px] sm:text-[28px] font-black font-mono text-ink mt-1"> | |
| {summary.total_records.toLocaleString()} | |
| </div> | |
| <div className="text-[11px] font-mono text-slate mt-1 flex items-center gap-1"> | |
| <span className="w-1.5 h-1.5 bg-hazard" /> | |
| <span>4.49 MB Telemetry Corpus</span> | |
| </div> | |
| </div> | |
| <div className="p-4 border-2 border-ink bg-white shadow-[3px_3px_0px_0px_#141413]"> | |
| <div className="text-[10px] font-bold text-slate uppercase tracking-wider"> | |
| Monitored Dimensions | |
| </div> | |
| <div className="text-[26px] sm:text-[28px] font-black font-mono text-ink mt-1"> | |
| {summary.total_features} Features | |
| </div> | |
| <div className="text-[11px] font-mono text-slate mt-1 flex items-center gap-1"> | |
| <span className="w-1.5 h-1.5 bg-ink" /> | |
| <span>6 Vitals 路 5 Classes 路 5 Alerts</span> | |
| </div> | |
| </div> | |
| <div className="p-4 border-2 border-ink bg-white shadow-[3px_3px_0px_0px_#141413]"> | |
| <div className="text-[10px] font-bold text-slate uppercase tracking-wider"> | |
| Class Balance Parity | |
| </div> | |
| <div className="text-[26px] sm:text-[28px] font-black font-mono text-ink mt-1"> | |
| 99.8% | |
| </div> | |
| <div className="text-[11px] font-mono text-slate mt-1 flex items-center gap-1"> | |
| <span className="w-1.5 h-1.5 bg-green-600" /> | |
| <span>5 Balanced Cohorts (~12k each)</span> | |
| </div> | |
| </div> | |
| <div className="p-4 border-2 border-ink bg-white shadow-[3px_3px_0px_0px_#141413]"> | |
| <div className="text-[10px] font-bold text-slate uppercase tracking-wider"> | |
| Data Integrity & Completeness | |
| </div> | |
| <div className="text-[26px] sm:text-[28px] font-black font-mono text-hazard mt-1"> | |
| {summary.completeness_pct.toFixed(1)}% | |
| </div> | |
| <div className="text-[11px] font-mono text-slate mt-1 flex items-center gap-1"> | |
| <CheckCircle2 size={12} className="text-hazard" /> | |
| <span>0 Null Records 路 0 Dropped Packets</span> | |
| </div> | |
| </div> | |
| </div> | |
| {/* Navigation Tabs - Horizontal Scroll strip with no-scrollbar for Mobile/Tablet */} | |
| <div className="border-b-2 border-ink mb-6 flex overflow-x-auto no-scrollbar gap-2 pb-0.5"> | |
| <button | |
| onClick={() => setActiveTab("heatmap")} | |
| className={`min-h-11 px-3.5 sm:px-4 py-2 text-[11px] sm:text-[12px] font-bold uppercase tracking-wider border-2 border-b-0 border-ink transition-all flex items-center gap-2 shrink-0 whitespace-nowrap ${ | |
| activeTab === "heatmap" | |
| ? "bg-ink text-white font-black shadow-[2px_-2px_0px_#9F2F2D]" | |
| : "bg-white text-ink hover:bg-canvas-cream" | |
| }`} | |
| > | |
| <Flame size={14} className={activeTab === "heatmap" ? "text-hazard" : "text-slate"} /> | |
| <span>Heatmap & Correlations</span> | |
| </button> | |
| <button | |
| onClick={() => setActiveTab("distributions")} | |
| className={`min-h-11 px-3.5 sm:px-4 py-2 text-[11px] sm:text-[12px] font-bold uppercase tracking-wider border-2 border-b-0 border-ink transition-all flex items-center gap-2 shrink-0 whitespace-nowrap ${ | |
| activeTab === "distributions" | |
| ? "bg-ink text-white font-black shadow-[2px_-2px_0px_#9F2F2D]" | |
| : "bg-white text-ink hover:bg-canvas-cream" | |
| }`} | |
| > | |
| <BarChart3 size={14} className={activeTab === "distributions" ? "text-hazard" : "text-slate"} /> | |
| <span>Feature Distributions</span> | |
| </button> | |
| <button | |
| onClick={() => setActiveTab("cohorts")} | |
| className={`min-h-11 px-3.5 sm:px-4 py-2 text-[11px] sm:text-[12px] font-bold uppercase tracking-wider border-2 border-b-0 border-ink transition-all flex items-center gap-2 shrink-0 whitespace-nowrap ${ | |
| activeTab === "cohorts" | |
| ? "bg-ink text-white font-black shadow-[2px_-2px_0px_#9F2F2D]" | |
| : "bg-white text-ink hover:bg-canvas-cream" | |
| }`} | |
| > | |
| <PieChart size={14} className={activeTab === "cohorts" ? "text-hazard" : "text-slate"} /> | |
| <span>Cohorts & Alarms</span> | |
| </button> | |
| <button | |
| onClick={() => setActiveTab("dictionary")} | |
| className={`min-h-11 px-3.5 sm:px-4 py-2 text-[11px] sm:text-[12px] font-bold uppercase tracking-wider border-2 border-b-0 border-ink transition-all flex items-center gap-2 shrink-0 whitespace-nowrap ${ | |
| activeTab === "dictionary" | |
| ? "bg-ink text-white font-black shadow-[2px_-2px_0px_#9F2F2D]" | |
| : "bg-white text-ink hover:bg-canvas-cream" | |
| }`} | |
| > | |
| <TableProperties size={14} className={activeTab === "dictionary" ? "text-hazard" : "text-slate"} /> | |
| <span>Data Dictionary</span> | |
| </button> | |
| <button | |
| onClick={() => setActiveTab("records")} | |
| className={`min-h-11 px-3.5 sm:px-4 py-2 text-[11px] sm:text-[12px] font-bold uppercase tracking-wider border-2 border-b-0 border-ink transition-all flex items-center gap-2 shrink-0 whitespace-nowrap ${ | |
| activeTab === "records" | |
| ? "bg-ink text-white font-black shadow-[2px_-2px_0px_#9F2F2D]" | |
| : "bg-white text-ink hover:bg-canvas-cream" | |
| }`} | |
| > | |
| <ListFilter size={14} className={activeTab === "records" ? "text-hazard" : "text-slate"} /> | |
| <span>Record Inspector</span> | |
| </button> | |
| </div> | |
| {/* Tab Content Display */} | |
| <div className="flex-1"> | |
| {activeTab === "heatmap" && ( | |
| <CorrelationHeatmap | |
| correlationData={correlation_matrix} | |
| featureDependencies={feature_dependencies} | |
| /> | |
| )} | |
| {activeTab === "distributions" && ( | |
| <FeatureDistributionChart featureStats={feature_stats} /> | |
| )} | |
| {activeTab === "cohorts" && ( | |
| <CohortBreakdownChart | |
| targetDistribution={target_distribution} | |
| alertPrevalence={alert_prevalence} | |
| /> | |
| )} | |
| {activeTab === "dictionary" && ( | |
| <FeatureStatsTable featureStats={feature_stats} /> | |
| )} | |
| {activeTab === "records" && ( | |
| <PaginatedRecordInspector | |
| initialRows={sample_rows} | |
| totalRecordsCount={summary.total_records} | |
| /> | |
| )} | |
| </div> | |
| </div> | |
| </main> | |
| ); | |
| } | |