modelo / static /index.html
alexacido's picture
Upload 11 files
479d4dc verified
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8" />
<title>Explorador CSV Consumertec</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<!-- PapaParse para procesar CSV en el navegador -->
<script src="https://cdn.jsdelivr.net/npm/papaparse@5.4.1/papaparse.min.js"></script>
<!-- Chart.js para los gráficos de la sección 7 -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<!-- jsPDF para generar el PDF de las secciones 6 y 7 -->
<script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script>
<style>
:root{
--bg:#020617;
--card:#020617;
--border:#1f2937;
--accent:#22d3ee;
--accent2:#4ade80;
--text:#e5e7eb;
--muted:#9ca3af;
}
*{box-sizing:border-box;margin:0;padding:0;}
body{
min-height:100vh;
display:flex;
align-items:center;
justify-content:center;
font-family:system-ui,-apple-system,"Segoe UI",sans-serif;
background:radial-gradient(circle at top,#0f172a,#020617);
color:var(--text);
padding:10px;
}
.card{
width:min(1100px,100%);
max-height:96vh;
background:var(--card);
border-radius:20px;
border:1px solid var(--border);
padding:18px 20px;
box-shadow:0 22px 50px rgba(0,0,0,0.6);
display:flex;
flex-direction:column;
gap:12px;
overflow-y:auto;
}
h1{
font-size:1.7rem;
text-align:center;
margin-bottom:4px;
}
p{
font-size:0.9rem;
line-height:1.5;
color:var(--muted);
text-align:justify;
text-justify:inter-word;
}
.section-title{
font-size:1rem;
font-weight:600;
margin-bottom:4px;
margin-top:8px;
}
label{
font-size:0.85rem;
margin-bottom:4px;
display:block;
color:var(--muted);
}
input[type="file"]{
width:100%;
padding:8px;
border-radius:10px;
border:1px dashed var(--border);
background:#020617;
color:var(--muted);
font-size:0.85rem;
}
input[type="text"],
select{
width:100%;
padding:8px;
border-radius:10px;
border:1px solid var(--border);
background:#020617;
color:var(--text);
font-size:0.85rem;
}
textarea{
width:100%;
min-height:90px;
max-height:200px;
resize:vertical;
border-radius:10px;
border:1px solid var(--border);
background:#020617;
color:var(--text);
padding:8px 10px;
font-size:0.85rem;
line-height:1.4;
}
.row{
display:flex;
flex-wrap:wrap;
gap:10px;
margin-top:6px;
align-items:center;
}
.row > *{ flex:1 1 auto; }
.btn{
display:inline-flex;
align-items:center;
justify-content:center;
padding:8px 16px;
border-radius:999px;
text-decoration:none;
border:none;
background:linear-gradient(135deg,var(--accent),var(--accent2));
color:#020617;
font-weight:600;
font-size:0.85rem;
letter-spacing:0.02em;
cursor:pointer;
transition:transform 0.1s ease, filter 0.1s ease;
white-space:nowrap;
}
.btn.secondary{
background:#111827;
color:var(--muted);
border:1px solid var(--border);
}
.btn:hover{
filter:brightness(1.06);
transform:translateY(-1px);
}
.status{
font-size:0.83rem;
color:var(--muted);
margin-top:4px;
}
.output-box{
margin-top:8px;
border-radius:10px;
border:1px solid var(--border);
background:#020617;
padding:8px 10px;
font-size:0.83rem;
line-height:1.45;
max-height:260px;
overflow:auto;
white-space:pre-wrap;
}
.small{ font-size:0.8rem; color:var(--muted); }
.mode-options{
display:flex;
flex-direction:column;
gap:8px;
margin-top:4px;
flex-wrap:wrap;
}
.mode-group{
display:flex;
flex-wrap:wrap;
gap:12px;
}
.mode-group.hidden{ display:none; }
.mode-group.disabled{ opacity:0.3; pointer-events:none; }
.mode-options label{
display:flex;
align-items:center;
gap:6px;
cursor:pointer;
font-size:0.85rem;
}
.mode-options input[type="radio"]{
accent-color:#22d3ee;
width:16px;
height:16px;
}
#textOutput{
max-height:60vh;
overflow-y:auto;
}
.chart-wrapper{
margin-top:8px;
border-radius:10px;
border:1px solid var(--border);
background:#020617;
padding:8px 10px;
height:260px;
}
#chartCanvas{ width:100%; height:100%; }
</style>
</head>
<body>
<div class="card">
<h1>Explorador CSV Consumertec</h1>
<p>
Este chatbot está diseñado para trabajar con archivos <strong>OUTPUT_MAP_COMPARISONS.csv</strong> y
otros CSV derivados de los experimentos de Consumertec. Primero se <strong>sube en la sección 1</strong>
el archivo CSV que se desea analizar. A partir de su estructura, en la <strong>sección 2</strong> se
activan los <strong>prompts internos</strong> compatibles. Después se ejecuta el análisis:
la <strong>sección 5</strong> calcula un <strong>resumen numérico determinista en el navegador</strong>
(sin usar backend). Luego, ese resumen numérico se envía al <strong>backend LLM</strong> como evidencia
para generar la explicación de la <strong>sección 6</strong> (sin repetir tablas).
</p>
<!-- Estado del motor -->
<div id="llmStatus" class="status small">
ℹ️ La sección 5 se calcula de forma determinista en el navegador. Luego, ese resumen numérico se envía al backend LLM
como evidencia para construir la sección 6 (sin reimprimir tablas ni listados).
</div>
<!-- Subir CSV (SECCIÓN 1) -->
<div>
<div class="section-title">1. Subir archivo CSV</div>
<label for="csvInput" id="csvLabel">
Sube primero el CSV que quieres analizar. Según sus columnas, se activarán las opciones de análisis en la sección 2.
</label>
<input id="csvInput" type="file" accept=".csv" />
<div id="fileStatus" class="status">⚠️ Ningún archivo seleccionado.</div>
</div>
<!-- Elegir tipo de análisis + prompt interno (SECCIÓN 2) -->
<div>
<div class="section-title">2. Elegir tipo de análisis y prompt interno</div>
<p class="small">
Después de subir el CSV, se mostrarán aquí los tipos de análisis compatibles. Cada tipo activa sus
prompts internos. El prompt seleccionado se mostrará en la <strong>sección 3</strong> (puedes editarlo)
y se usará junto con la evidencia numérica determinista de la sección 5 como entrada al backend LLM.
</p>
<div class="mode-options">
<!-- Grupo Comparaciones -->
<div id="group_comparaciones" class="mode-group hidden">
<label>
<input id="mode_comparaciones_basico" type="radio" name="mode"
onclick="setMode('comparaciones','comparaciones_basico')" />
Prompt 1 — Comparación (PRODUCT_TEST vs RESPONSE)
</label>
<label>
<input id="mode_comparaciones_escenarios" type="radio" name="mode"
onclick="setMode('comparaciones','comparaciones_escenarios')" />
Prompt 5 — Comparación por escenarios y modalidades
</label>
</div>
<!-- Grupo Blancura -->
<div id="group_whiteness" class="mode-group hidden">
<label>
<input id="mode_whiteness_basico" type="radio" name="mode"
onclick="setMode('whiteness','whiteness_basico')" />
Prompt 2 — Blancura por MONITOR (métricas WI)
</label>
<label>
<input id="mode_whiteness_productos" type="radio" name="mode"
onclick="setMode('whiteness','whiteness_productos')" />
Prompt 6 — Perfil de blancura por producto
</label>
</div>
<!-- Grupo Resumen -->
<div id="group_resumen" class="mode-group hidden">
<label>
<input id="mode_resumen_basico" type="radio" name="mode"
onclick="setMode('resumen','resumen_basico')" />
Prompt 3 — Resumen general de la tabla
</label>
<label>
<input id="mode_resumen_avanzado" type="radio" name="mode"
onclick="setMode('resumen','resumen_avanzado')" />
Prompt 7 — Resumen avanzado y bloques de variables
</label>
</div>
<!-- Grupo RESPONSE vs otras columnas -->
<div id="group_response_rel" class="mode-group hidden">
<label>
<input id="mode_response_basico" type="radio" name="mode"
onclick="setMode('response_rel','response_basico')" />
Prompt 4 — Comparar RESPONSE con las demás columnas
</label>
<label>
<input id="mode_response_extremos" type="radio" name="mode"
onclick="setMode('response_rel','response_extremos')" />
Prompt 8 — RESPONSE: mejores y peores resultados
</label>
</div>
</div>
<div class="status small" id="modeStatus">
Primero sube un CSV en la sección 1. Luego se activarán aquí los tipos de análisis compatibles.
</div>
</div>
<!-- Pregunta / Prompt (SECCIÓN 3) -->
<div>
<div class="section-title">3. Prompt de análisis</div>
<label for="question">
El prompt se rellenará automáticamente según el análisis elegido, pero puedes editarlo libremente.
Este texto se enviará al <strong>backend LLM</strong> junto con el resumen numérico determinista (sección 5),
como evidencia para generar la explicación de la sección 6.
</label>
<textarea id="question" placeholder="Sube un CSV y elige un tipo de análisis; aquí aparecerá el prompt asociado, que podrás ajustar…"></textarea>
<div class="row">
<button class="btn" type="button" onclick="analizarCSV()">
4. Analizar CSV
</button>
</div>
<div id="analysisStatus" class="status">
⏳ Sube un CSV, elige un tipo de análisis en la sección 2 y luego usa el botón Analizar.
</div>
</div>
<!-- Resultados de cómputo -->
<div>
<div class="section-title">5. Resultados numéricos (resumen determinista en el navegador)</div>
<div id="numericOutput" class="output-box small">
// Sección 5 — Resumen numérico determinista (generado en el navegador).
// Ejecuta “4. Analizar CSV” para generarlo aquí.
</div>
</div>
<!-- Explicación en texto continuo -->
<div>
<div class="section-title">6. Explicación (LLM usando el resumen numérico como evidencia)</div>
<div id="textOutput" class="output-box">
// Aquí se generará la explicación producida por el LLM usando tu prompt (sección 3) + evidencia numérica (sección 5).
</div>
<div class="row">
<div>
<label for="reportTitle" class="small">
Título del reporte (se usará como título en el PDF y en el nombre del archivo)
</label>
<input id="reportTitle"
type="text"
placeholder="Ejemplo: Informe de desempeño de productos Consumertec" />
</div>
<div style="flex:0 0 auto;">
<button class="btn secondary" type="button" onclick="descargarPDF()">
Descargar secciones 6 y 7 (.pdf)
</button>
</div>
</div>
</div>
<!-- SECCIÓN 7 -->
<div>
<div class="section-title">7. Visualización gráfica de resultados (desde la sección 5)</div>
<p class="small">
Estos gráficos se generan a partir del resumen determinista de la sección 5.
El LLM no usa los gráficos; son una ayuda visual para interpretar los resultados.
</p>
<div class="row">
<div>
<label for="chartType">Tipo de gráfico</label>
<select id="chartType" onchange="cambiarTipoGrafico()">
<option value="bar">Barras</option>
<option value="line">Líneas</option>
</select>
</div>
<div id="chartStatus" class="status">
⚠️ Aún no hay datos para graficar. Ejecuta un análisis primero.
</div>
</div>
<div class="chart-wrapper">
<canvas id="chartCanvas"></canvas>
</div>
<div id="chartMultiStatus" class="status">
⚠️ Aún no hay datos para el gráfico multivariable. Ejecuta un análisis compatible (por ejemplo, Comparaciones).
</div>
<div class="chart-wrapper">
<canvas id="chartCanvasMulti"></canvas>
</div>
</div>
</div>
<!-- JS: orden importante (variables/globales -> core -> modos -> pdf) -->
<script src="static/state.js"></script>
<script src="static/core.js"></script>
<script src="static/modes/comparaciones.js"></script>
<script src="static/modes/whiteness.js"></script>
<script src="static/modes/resumen.js"></script>
<script src="static/modes/response_rel.js"></script>
<script src="static/pdf.js"></script>
</body>
</html>