This commit is contained in:
@@ -117,45 +117,55 @@
|
||||
.report-step {
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
padding: 1rem;
|
||||
padding: 1.5rem;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
max-height: 500px;
|
||||
max-height: 1000px;
|
||||
margin-bottom: 1.5rem;
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.step-active {
|
||||
background: rgba(56, 189, 248, 0.05);
|
||||
border: 1px solid rgba(56, 189, 248, 0.2);
|
||||
opacity: 1 !important;
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.step-completed {
|
||||
max-height: 50px;
|
||||
opacity: 0.6;
|
||||
max-height: 80px;
|
||||
opacity: 0.7;
|
||||
cursor: pointer;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
}
|
||||
|
||||
.step-completed:hover {
|
||||
opacity: 1;
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border-color: rgba(56, 189, 248, 0.3);
|
||||
}
|
||||
|
||||
.step-completed select,
|
||||
.step-completed input {
|
||||
display: none;
|
||||
.step-completed input,
|
||||
.step-completed .relative,
|
||||
.step-completed .pt-8,
|
||||
.step-completed .grid {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.step-summary {
|
||||
font-size: 0.8rem;
|
||||
font-size: 0.85rem;
|
||||
color: #38bdf8;
|
||||
font-weight: 700;
|
||||
margin-top: -2px;
|
||||
margin-top: 0.5rem;
|
||||
background: rgba(56, 189, 248, 0.1);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
padding: 6px 12px;
|
||||
border-radius: 8px;
|
||||
display: block;
|
||||
width: fit-content;
|
||||
border: 1px solid rgba(56, 189, 248, 0.2);
|
||||
}
|
||||
|
||||
.spinner {
|
||||
@@ -292,6 +302,7 @@
|
||||
<label class="field-label">3. Secondary Breakdown (Series)</label>
|
||||
<select id="axisSub" class="input-glass" onchange="updateUrlParams(); proceedToStep(4)">
|
||||
<option value="">None (Unified)</option>
|
||||
<option value="isin">By Company / ISIN</option>
|
||||
<option value="exchange">By Exchange</option>
|
||||
<option value="continent">By Continent</option>
|
||||
<option value="sector">By Sector</option>
|
||||
@@ -520,14 +531,22 @@
|
||||
btn.disabled = true;
|
||||
loader.classList.remove('hidden');
|
||||
errBox.classList.add('hidden');
|
||||
|
||||
let url = `${API}/analytics?metric=${y}&group_by=${x}`;
|
||||
if (sub) url += `&sub_group_by=${sub}`;
|
||||
if (dates.from) url += `&date_from=${dates.from}`;
|
||||
if (dates.to) url += `&date_to=${dates.to}`;
|
||||
if (isins) url += `&isins=${isins}`;
|
||||
|
||||
try {
|
||||
// If multiple ISINs are selected but no breakdown is chosen,
|
||||
// we automatically breakdown by ISIN to give them different colors.
|
||||
let effectiveSub = sub;
|
||||
if (!sub && store.pinnedIsins.length > 1 && x !== 'isin') {
|
||||
effectiveSub = 'isin';
|
||||
url += `&sub_group_by=isin`;
|
||||
} else if (sub) {
|
||||
url += `&sub_group_by=${sub}`;
|
||||
}
|
||||
|
||||
const res = await fetch(url).then(r => {
|
||||
if (!r.ok) throw new Error(`Server Error: ${r.status}`);
|
||||
return r.json();
|
||||
@@ -539,7 +558,7 @@
|
||||
if (x === 'day' || x === 'month') labels.sort((a, b) => new Date(a) - new Date(b));
|
||||
|
||||
let datasets = [];
|
||||
if (sub) {
|
||||
if (effectiveSub) {
|
||||
let seriesNames = [...new Set(data.map(r => r[1]))];
|
||||
seriesNames.forEach((name, idx) => {
|
||||
const hue = (idx * 137.5) % 360;
|
||||
@@ -552,7 +571,8 @@
|
||||
backgroundColor: `hsla(${hue}, 75%, 50%, 0.7)`,
|
||||
borderColor: `hsla(${hue}, 75%, 50%, 1)`,
|
||||
borderWidth: 2,
|
||||
fill: currentChartType === 'line'
|
||||
fill: currentChartType === 'line',
|
||||
tension: 0.3
|
||||
});
|
||||
});
|
||||
} else {
|
||||
@@ -565,7 +585,8 @@
|
||||
backgroundColor: '#38bdf866',
|
||||
borderColor: '#38bdf8',
|
||||
borderWidth: 2,
|
||||
fill: currentChartType === 'line'
|
||||
fill: currentChartType === 'line',
|
||||
tension: 0.3
|
||||
});
|
||||
}
|
||||
|
||||
@@ -576,10 +597,31 @@
|
||||
options: {
|
||||
responsive: true, maintainAspectRatio: false,
|
||||
animation: { duration: 800, easing: 'easeOutQuart' },
|
||||
scales: { y: { stacked: true, grid: { color: 'rgba(255,255,255,0.05)' } }, x: { stacked: true, grid: { display: false } } },
|
||||
scales: {
|
||||
y: {
|
||||
stacked: (currentChartType === 'bar'),
|
||||
grid: { color: 'rgba(255,255,255,0.05)' },
|
||||
ticks: { color: '#64748b' }
|
||||
},
|
||||
x: {
|
||||
stacked: (currentChartType === 'bar'),
|
||||
grid: { display: false },
|
||||
ticks: { color: '#64748b' }
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: { position: 'bottom', labels: { color: '#94a3b8', boxWidth: 12, usePointStyle: true } },
|
||||
tooltip: { backgroundColor: '#1e293b', titleColor: '#38bdf8' }
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'bottom',
|
||||
labels: { color: '#94a3b8', boxWidth: 12, usePointStyle: true, padding: 20 }
|
||||
},
|
||||
tooltip: {
|
||||
backgroundColor: '#1e293b',
|
||||
titleColor: '#38bdf8',
|
||||
bodyColor: '#e2e8f0',
|
||||
borderColor: 'rgba(255,255,255,0.1)',
|
||||
borderWidth: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -626,18 +668,32 @@
|
||||
function proceedToStep(n) {
|
||||
document.querySelectorAll('.report-step').forEach((s, idx) => {
|
||||
const stepNum = idx + 1;
|
||||
// Active step is the one currently being configured
|
||||
s.classList.toggle('step-active', stepNum === n);
|
||||
s.classList.toggle('step-completed', stepNum < n);
|
||||
if (stepNum > n) s.classList.add('hidden', 'opacity-50');
|
||||
else s.classList.remove('hidden');
|
||||
// Completed steps are those before the current one, but NOT if they are active
|
||||
s.classList.toggle('step-completed', stepNum < n && stepNum !== n);
|
||||
|
||||
// Show all steps but fade future ones slightly
|
||||
s.classList.remove('hidden');
|
||||
if (stepNum > n) {
|
||||
s.classList.add('opacity-50');
|
||||
} else {
|
||||
s.classList.remove('opacity-50');
|
||||
}
|
||||
|
||||
const summary = document.getElementById(`summary-step${stepNum}`);
|
||||
if (summary) {
|
||||
if (stepNum < n) {
|
||||
// Only show summary for non-active steps that have a selection
|
||||
if (stepNum !== n) {
|
||||
const input = s.querySelector('select, input');
|
||||
let val = input ? (input.options && input.selectedIndex >= 0 ? input.options[input.selectedIndex].text : input.value) : '';
|
||||
if (val && val !== 'Select...') {
|
||||
summary.innerText = val;
|
||||
summary.classList.remove('hidden');
|
||||
} else {
|
||||
summary.classList.add('hidden');
|
||||
}
|
||||
// Allow clicking headers of any step to go back/forward
|
||||
s.onclick = () => proceedToStep(stepNum);
|
||||
} else {
|
||||
summary.classList.add('hidden');
|
||||
|
||||
Reference in New Issue
Block a user