added volume & Count metrics
All checks were successful
Deployment / deploy-docker (push) Successful in 16s
All checks were successful
Deployment / deploy-docker (push) Successful in 16s
This commit is contained in:
@@ -318,6 +318,7 @@
|
|||||||
<option value="volume">Trade Volume (€)</option>
|
<option value="volume">Trade Volume (€)</option>
|
||||||
<option value="count">Number of Trades</option>
|
<option value="count">Number of Trades</option>
|
||||||
<option value="avg_price">Average Performance</option>
|
<option value="avg_price">Average Performance</option>
|
||||||
|
<option value="all">Volume & Count (Dual Axis)</option>
|
||||||
</select>
|
</select>
|
||||||
<div id="summary-step4" class="step-summary"></div>
|
<div id="summary-step4" class="step-summary"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -562,32 +563,95 @@
|
|||||||
let seriesNames = [...new Set(data.map(r => r[1]))];
|
let seriesNames = [...new Set(data.map(r => r[1]))];
|
||||||
seriesNames.forEach((name, idx) => {
|
seriesNames.forEach((name, idx) => {
|
||||||
const hue = (idx * 137.5) % 360;
|
const hue = (idx * 137.5) % 360;
|
||||||
datasets.push({
|
|
||||||
label: name,
|
if (y === 'all') {
|
||||||
data: labels.map(l => {
|
// Dual axis for breakdown
|
||||||
const row = data.find(r => r[0] === l && r[1] === name);
|
// Volume Dataset
|
||||||
return row ? row[2] : 0;
|
datasets.push({
|
||||||
}),
|
label: `${name} (Vol)`,
|
||||||
backgroundColor: `hsla(${hue}, 75%, 50%, 0.7)`,
|
data: labels.map(l => {
|
||||||
borderColor: `hsla(${hue}, 75%, 50%, 1)`,
|
const row = data.find(r => r[0] === l && r[1] === name);
|
||||||
borderWidth: 2,
|
return row ? row[3] : 0; // value_volume is index 3
|
||||||
fill: currentChartType === 'line',
|
}),
|
||||||
tension: 0.3
|
backgroundColor: `hsla(${hue}, 75%, 50%, 0.7)`,
|
||||||
});
|
borderColor: `hsla(${hue}, 75%, 50%, 1)`,
|
||||||
|
borderWidth: 2,
|
||||||
|
yAxisID: 'y',
|
||||||
|
type: 'bar'
|
||||||
|
});
|
||||||
|
// Count Dataset
|
||||||
|
datasets.push({
|
||||||
|
label: `${name} (Cnt)`,
|
||||||
|
data: labels.map(l => {
|
||||||
|
const row = data.find(r => r[0] === l && r[1] === name);
|
||||||
|
return row ? row[2] : 0; // value_count is index 2
|
||||||
|
}),
|
||||||
|
backgroundColor: `hsla(${hue}, 75%, 30%, 0.7)`,
|
||||||
|
borderColor: `hsla(${hue}, 75%, 30%, 1)`,
|
||||||
|
borderWidth: 2,
|
||||||
|
yAxisID: 'y1',
|
||||||
|
type: 'line', // Always line for count to distinguish
|
||||||
|
pointStyle: 'rectRot'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Standard single metric breakdown
|
||||||
|
datasets.push({
|
||||||
|
label: name,
|
||||||
|
data: labels.map(l => {
|
||||||
|
const row = data.find(r => r[0] === l && r[1] === name);
|
||||||
|
return row ? row[2] : 0;
|
||||||
|
}),
|
||||||
|
backgroundColor: `hsla(${hue}, 75%, 50%, 0.7)`,
|
||||||
|
borderColor: `hsla(${hue}, 75%, 50%, 1)`,
|
||||||
|
borderWidth: 2,
|
||||||
|
fill: currentChartType === 'line',
|
||||||
|
tension: 0.3,
|
||||||
|
yAxisID: 'y'
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
datasets.push({
|
if (y === 'all') {
|
||||||
label: y.toUpperCase(),
|
// Standard dual axis without breakdown
|
||||||
data: labels.map(l => {
|
datasets.push({
|
||||||
const row = data.find(r => r[0] === l);
|
label: 'Volume (€)',
|
||||||
return row ? row[1] : 0;
|
data: labels.map(l => {
|
||||||
}),
|
const row = data.find(r => r[0] === l);
|
||||||
backgroundColor: '#38bdf866',
|
return row ? row[2] : 0; // value_volume
|
||||||
borderColor: '#38bdf8',
|
}),
|
||||||
borderWidth: 2,
|
backgroundColor: '#38bdf866',
|
||||||
fill: currentChartType === 'line',
|
borderColor: '#38bdf8',
|
||||||
tension: 0.3
|
borderWidth: 2,
|
||||||
});
|
yAxisID: 'y',
|
||||||
|
type: 'bar'
|
||||||
|
});
|
||||||
|
datasets.push({
|
||||||
|
label: 'Count',
|
||||||
|
data: labels.map(l => {
|
||||||
|
const row = data.find(r => r[0] === l);
|
||||||
|
return row ? row[1] : 0; // value_count
|
||||||
|
}),
|
||||||
|
backgroundColor: '#fbbf2466',
|
||||||
|
borderColor: '#fbbf24',
|
||||||
|
borderWidth: 2,
|
||||||
|
yAxisID: 'y1',
|
||||||
|
type: 'line'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
datasets.push({
|
||||||
|
label: y.toUpperCase(),
|
||||||
|
data: labels.map(l => {
|
||||||
|
const row = data.find(r => r[0] === l);
|
||||||
|
return row ? row[1] : 0;
|
||||||
|
}),
|
||||||
|
backgroundColor: '#38bdf866',
|
||||||
|
borderColor: '#38bdf8',
|
||||||
|
borderWidth: 2,
|
||||||
|
fill: currentChartType === 'line',
|
||||||
|
tension: 0.3,
|
||||||
|
yAxisID: 'y'
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (charts.analytics) charts.analytics.destroy();
|
if (charts.analytics) charts.analytics.destroy();
|
||||||
@@ -599,9 +663,22 @@
|
|||||||
animation: { duration: 800, easing: 'easeOutQuart' },
|
animation: { duration: 800, easing: 'easeOutQuart' },
|
||||||
scales: {
|
scales: {
|
||||||
y: {
|
y: {
|
||||||
|
type: 'linear',
|
||||||
|
display: true,
|
||||||
|
position: 'left',
|
||||||
stacked: false,
|
stacked: false,
|
||||||
grid: { color: 'rgba(255,255,255,0.05)' },
|
grid: { color: 'rgba(255,255,255,0.05)' },
|
||||||
ticks: { color: '#64748b' }
|
ticks: { color: '#64748b' },
|
||||||
|
title: { display: true, text: 'Volume (€)', color: '#38bdf8' }
|
||||||
|
},
|
||||||
|
y1: {
|
||||||
|
type: 'linear',
|
||||||
|
display: y === 'all',
|
||||||
|
position: 'right',
|
||||||
|
stacked: false,
|
||||||
|
grid: { drawOnChartArea: false }, // only want the grid lines for one axis to show up
|
||||||
|
ticks: { color: '#fbbf24' },
|
||||||
|
title: { display: true, text: 'Trade Count', color: '#fbbf24' }
|
||||||
},
|
},
|
||||||
x: {
|
x: {
|
||||||
stacked: false,
|
stacked: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user