feat: black unknown color and progressive report configuration UI
All checks were successful
Deployment / deploy-docker (push) Successful in 15s
All checks were successful
Deployment / deploy-docker (push) Successful in 15s
This commit is contained in:
@@ -91,7 +91,12 @@
|
||||
|
||||
.field-label {
|
||||
display: block;
|
||||
text-xs font-bold text-slate-500 uppercase tracking-widest mb-3;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
color: #64748b;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.input-glass {
|
||||
@@ -177,30 +182,34 @@
|
||||
|
||||
<!-- REPORT BUILDER VIEW -->
|
||||
<div id="view-analytics" class="view hidden flex-1 flex overflow-hidden">
|
||||
<div class="config-sidebar p-8 space-y-8 overflow-y-auto bg-slate-900/30">
|
||||
<h3 class="text-sky-400 font-bold text-xs uppercase tracking-tighter mb-4">Report Configuration</h3>
|
||||
<!-- Configuration Sidebar -->
|
||||
<div class="config-sidebar p-8 space-y-6 overflow-y-auto bg-slate-900/30" id="reportConfig">
|
||||
<h3 class="text-sky-400 font-bold text-xs uppercase tracking-tighter mb-4">Step-by-Step Configuration
|
||||
</h3>
|
||||
|
||||
<!-- Time Selection -->
|
||||
<div>
|
||||
<label class="field-label">Time Period</label>
|
||||
<select id="timeRangePreset" class="input-glass mb-2" onchange="handlePresetChange()">
|
||||
<!-- Step 1: Time Range -->
|
||||
<div class="report-step" id="step1">
|
||||
<label class="field-label">1. Choose Analysis Period</label>
|
||||
<select id="timeRangePreset" class="input-glass" onchange="proceedToStep(2)">
|
||||
<option value="" disabled selected>Select... </option>
|
||||
<option value="1">Today</option>
|
||||
<option value="7" selected>Last 7 Days</option>
|
||||
<option value="7">Last 7 Days</option>
|
||||
<option value="30">Last 30 Days</option>
|
||||
<option value="ytd">Year to Date (YTD)</option>
|
||||
<option value="year">Full Year 2026</option>
|
||||
<option value="custom">Custom Date Range...</option>
|
||||
<option value="custom">Custom Range...</option>
|
||||
</select>
|
||||
<div id="customDates" class="hidden grid grid-cols-2 gap-2 mt-2">
|
||||
<input type="date" id="dateFrom" class="input-glass text-xs p-2">
|
||||
<input type="date" id="dateTo" class="input-glass text-xs p-2">
|
||||
<input type="date" id="dateFrom" class="input-glass text-xs p-2" onchange="checkCustomDates()">
|
||||
<input type="date" id="dateTo" class="input-glass text-xs p-2" onchange="checkCustomDates()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dimension Selection (X) -->
|
||||
<div>
|
||||
<label class="field-label">Group By (X-Axis)</label>
|
||||
<select id="axisX" class="input-glass" onchange="updateSubGroupOptions()">
|
||||
<!-- Step 2: X-Axis -->
|
||||
<div class="report-step hidden opacity-50" id="step2">
|
||||
<label class="field-label">2. Primary Grouping (X-Axis)</label>
|
||||
<select id="axisX" class="input-glass" onchange="proceedToStep(3); updateSubGroupOptions();">
|
||||
<option value="" disabled selected>Select... </option>
|
||||
<option value="day">Time (Daily)</option>
|
||||
<option value="month">Time (Monthly)</option>
|
||||
<option value="exchange">Exchange Origin</option>
|
||||
@@ -210,40 +219,45 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Breakdown Selection (Series) -->
|
||||
<div id="subGroupContainer">
|
||||
<label class="field-label">Breakdown by (Series)</label>
|
||||
<select id="axisSub" class="input-glass">
|
||||
<option value="">None (Single Series)</option>
|
||||
<option value="exchange">Exchange</option>
|
||||
<option value="continent">Continent</option>
|
||||
<option value="sector">Sector</option>
|
||||
<!-- Step 3: Breakdown -->
|
||||
<div class="report-step hidden opacity-50" id="step3">
|
||||
<label class="field-label">3. Secondary Breakdown (Series)</label>
|
||||
<select id="axisSub" class="input-glass" onchange="proceedToStep(4)">
|
||||
<option value="">None (Unified)</option>
|
||||
<option value="exchange">By Exchange</option>
|
||||
<option value="continent">By Continent</option>
|
||||
<option value="sector">By Sector</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Metric Selection (Y) -->
|
||||
<div>
|
||||
<label class="field-label">Measurement (Y-Axis)</label>
|
||||
<select id="axisY" class="input-glass">
|
||||
<!-- Step 4: Y-Axis -->
|
||||
<div class="report-step hidden opacity-50" id="step4">
|
||||
<label class="field-label">4. Select Metric (Y-Axis)</label>
|
||||
<select id="axisY" class="input-glass" onchange="proceedToStep(5)">
|
||||
<option value="" disabled selected>Select... </option>
|
||||
<option value="volume">Trade Volume (€)</option>
|
||||
<option value="count">Number of Trades</option>
|
||||
<option value="avg_price">Average Price</option>
|
||||
<option value="avg_price">Average Performance</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Search & Filter -->
|
||||
<!-- Step 5: Filters -->
|
||||
<div class="report-step hidden opacity-50" id="step5">
|
||||
<div class="relative">
|
||||
<label class="field-label">Filter to Companies</label>
|
||||
<label class="field-label">5. Optional Company Filters</label>
|
||||
<input type="text" id="isinSearch" autocomplete="off" placeholder="Search ISIN or Name..."
|
||||
class="input-glass" onkeyup="handleSearch(event)">
|
||||
<div id="suggestions" class="suggestion-box hidden"></div>
|
||||
<div id="filterChips" class="flex flex-wrap gap-2 mt-4"></div>
|
||||
</div>
|
||||
|
||||
<div class="pt-4">
|
||||
<button onclick="renderAnalyticsReport()" class="btn-primary w-full">GENERATE REPORT</button>
|
||||
<p class="text-[10px] text-slate-500 mt-4 text-center">Charts are automatically optimized (Line vs
|
||||
Bar) based on selected grouping.</p>
|
||||
<div class="pt-8 space-y-3">
|
||||
<button onclick="renderAnalyticsReport()"
|
||||
class="btn-primary w-full shadow-sky-500/20">REGENERATE G-DRIVE REPORT</button>
|
||||
<button onclick="resetReportConfig()"
|
||||
class="w-full text-xs text-slate-500 hover:text-white transition">Reset
|
||||
Configuration</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -481,22 +495,25 @@
|
||||
|
||||
const contCtx = document.getElementById('continentChart').getContext('2d');
|
||||
if (charts.continent) charts.continent.destroy();
|
||||
charts.continent = new Chart(contCtx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: store.summary.map(r => r[0]),
|
||||
datasets: [{
|
||||
data: store.summary.map(r => r[2]),
|
||||
backgroundColor: [
|
||||
const labels = store.summary.map(r => r[0]);
|
||||
const baseColors = [
|
||||
'#38bdf8', // Blue
|
||||
'#f43f5e', // Red
|
||||
'#10b981', // Green
|
||||
'#fbbf24', // Yellow
|
||||
'#8b5cf6', // Purple
|
||||
'#f97316', // Orange
|
||||
'#475569', // Slate (for Unknown - high contrast)
|
||||
'#ec4899' // Pink
|
||||
],
|
||||
'#ec4899', // Pink
|
||||
'#475569' // Slate
|
||||
];
|
||||
|
||||
charts.continent = new Chart(contCtx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
data: store.summary.map(r => r[2]),
|
||||
backgroundColor: labels.map((l, i) => l.toLowerCase() === 'unknown' ? '#000000' : baseColors[i % baseColors.length]),
|
||||
borderWidth: 0
|
||||
}]
|
||||
},
|
||||
@@ -504,6 +521,34 @@
|
||||
});
|
||||
}
|
||||
|
||||
// --- Progressive Report Configuration ---
|
||||
function proceedToStep(n) {
|
||||
const step = document.getElementById(`step${n}`);
|
||||
if (step) {
|
||||
step.classList.remove('hidden');
|
||||
setTimeout(() => step.classList.remove('opacity-50'), 50);
|
||||
}
|
||||
if (n === 2) handlePresetChange();
|
||||
}
|
||||
|
||||
function checkCustomDates() {
|
||||
const from = document.getElementById('dateFrom').value;
|
||||
const to = document.getElementById('dateTo').value;
|
||||
if (from && to) proceedToStep(2);
|
||||
}
|
||||
|
||||
function resetReportConfig() {
|
||||
document.querySelectorAll('.report-step').forEach((s, i) => {
|
||||
if (i > 0) s.classList.add('hidden', 'opacity-50');
|
||||
});
|
||||
document.getElementById('timeRangePreset').value = '';
|
||||
document.getElementById('axisX').value = '';
|
||||
document.getElementById('axisSub').value = '';
|
||||
document.getElementById('axisY').value = '';
|
||||
store.pinnedIsins = [];
|
||||
updateFilterChips();
|
||||
}
|
||||
|
||||
function fillMetadataTable() {
|
||||
const tbody = document.getElementById('metadataRows');
|
||||
tbody.innerHTML = store.metadata.map(r => `
|
||||
|
||||
Reference in New Issue
Block a user