cdfsf
This commit is contained in:
@@ -1731,42 +1731,31 @@
|
|||||||
const overviewCharts = useMemo(() => {
|
const overviewCharts = useMemo(() => {
|
||||||
const overviewWindowDays = Number(payload?.bootstrap_meta?.overview_window_days || 15);
|
const overviewWindowDays = Number(payload?.bootstrap_meta?.overview_window_days || 15);
|
||||||
const overviewRows = recentMeasurementWindow(measurements, overviewWindowDays);
|
const overviewRows = recentMeasurementWindow(measurements, overviewWindowDays);
|
||||||
const chartCoinCurrency = String(currentSettings.crypto_currency || 'DOGE').toUpperCase();
|
const performanceByDay = new Map();
|
||||||
const comparisonRows = overviewRows.filter((row) => {
|
|
||||||
const miningRate = Number(row.doge_per_hour_per_mh_interval);
|
overviewRows.forEach((row) => {
|
||||||
const price = Number(row.effective_price_per_coin ?? row.price_per_coin);
|
const rate = Number(row.doge_per_day_interval);
|
||||||
return Number.isFinite(miningRate) && miningRate > 0 && Number.isFinite(price) && price > 0;
|
const dayKey = String(row.measured_date || '').trim() || String(row.measured_at || '').slice(0, 10);
|
||||||
|
if (!dayKey || !Number.isFinite(rate) || rate < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const existing = performanceByDay.get(dayKey) || { sum: 0, count: 0, label: fmtDate(dayKey) };
|
||||||
|
existing.sum += rate;
|
||||||
|
existing.count += 1;
|
||||||
|
performanceByDay.set(dayKey, existing);
|
||||||
});
|
});
|
||||||
const baseComparison = comparisonRows[0] || null;
|
|
||||||
const baseMining = baseComparison ? Number(baseComparison.doge_per_hour_per_mh_interval) : null;
|
|
||||||
const basePrice = baseComparison ? Number(baseComparison.effective_price_per_coin ?? baseComparison.price_per_coin) : null;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mining: overviewRows.map((row) => ({ x: fmtDate(row.measured_at), y: row.coins_total })),
|
performance: Array.from(performanceByDay.entries())
|
||||||
performance: overviewRows.filter((row) => row.doge_per_day_interval !== null)
|
.sort((left, right) => String(left[0]).localeCompare(String(right[0])))
|
||||||
.map((row) => ({ x: fmtDate(row.measured_at), y: row.doge_per_day_interval })),
|
.map(([, entry]) => ({
|
||||||
|
x: entry.label,
|
||||||
|
y: entry.count > 0 ? (entry.sum / entry.count) : null,
|
||||||
|
}))
|
||||||
|
.filter((point) => Number.isFinite(Number(point.y))),
|
||||||
pricing: overviewRows.filter((row) => row.price_per_coin !== null)
|
pricing: overviewRows.filter((row) => row.price_per_coin !== null)
|
||||||
.map((row) => ({ x: fmtDate(row.measured_at), y: row.price_per_coin })),
|
.map((row) => ({ x: fmtDate(row.measured_at), y: row.price_per_coin })),
|
||||||
miningVsPrice: baseMining && basePrice ? [
|
|
||||||
{
|
|
||||||
key: 'mining-rate',
|
|
||||||
label: `${chartCoinCurrency}/h je MH/s Index`,
|
|
||||||
color: '#2dd4bf',
|
|
||||||
data: comparisonRows.map((row) => ({
|
|
||||||
x: fmtDate(row.measured_at),
|
|
||||||
y: (Number(row.doge_per_hour_per_mh_interval) / baseMining) * 100,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'doge-price',
|
|
||||||
label: `${chartCoinCurrency}-Kurs Index`,
|
|
||||||
color: '#f59e0b',
|
|
||||||
data: comparisonRows.map((row) => ({
|
|
||||||
x: fmtDate(row.measured_at),
|
|
||||||
y: (Number(row.effective_price_per_coin ?? row.price_per_coin) / basePrice) * 100,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
] : [],
|
|
||||||
};
|
};
|
||||||
}, [currentSettings.crypto_currency, measurements, payload?.bootstrap_meta?.overview_window_days]);
|
}, [currentSettings.crypto_currency, measurements, payload?.bootstrap_meta?.overview_window_days]);
|
||||||
|
|
||||||
@@ -2756,6 +2745,9 @@
|
|||||||
const totalEarnedOverall = latest && latest.growth_since_baseline !== null && latest.growth_since_baseline !== undefined
|
const totalEarnedOverall = latest && latest.growth_since_baseline !== null && latest.growth_since_baseline !== undefined
|
||||||
? Number(latest.growth_since_baseline)
|
? Number(latest.growth_since_baseline)
|
||||||
: null;
|
: null;
|
||||||
|
const totalEarnedOverallFiat = latest && totalEarnedOverall !== null
|
||||||
|
? convertMeasurementMoney(latest, totalEarnedOverall, reportCurrency)
|
||||||
|
: null;
|
||||||
const totalSpentOverallCurrentAsset = latest
|
const totalSpentOverallCurrentAsset = latest
|
||||||
? convertMeasurementMoney(
|
? convertMeasurementMoney(
|
||||||
latest,
|
latest,
|
||||||
@@ -2763,6 +2755,30 @@
|
|||||||
currentCoinCurrency
|
currentCoinCurrency
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
|
const totalSpentOverallFiat = latest && totalSpentOverallCurrentAsset !== null
|
||||||
|
? convertMeasurementMoney(latest, totalSpentOverallCurrentAsset, reportCurrency)
|
||||||
|
: null;
|
||||||
|
const spentByType = activeMinerRows.reduce((summary, row) => {
|
||||||
|
const amount = Number(row?.effective_amount);
|
||||||
|
const currency = String(row?.effective_currency || '').toUpperCase();
|
||||||
|
if (!Number.isFinite(amount) || amount <= 0 || !currency) {
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.payment_type === 'crypto') {
|
||||||
|
const converted = convertCurrencyValue(amount, currency, currentCoinCurrency);
|
||||||
|
if (Number.isFinite(converted)) {
|
||||||
|
summary.crypto += converted;
|
||||||
|
}
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
const converted = convertCurrencyValue(amount, currency, reportCurrency);
|
||||||
|
if (Number.isFinite(converted)) {
|
||||||
|
summary.fiat += converted;
|
||||||
|
}
|
||||||
|
return summary;
|
||||||
|
}, { crypto: 0, fiat: 0 });
|
||||||
const breakEvenReached = breakEvenRemainingAmount !== null && breakEvenRemainingAmount <= 0;
|
const breakEvenReached = breakEvenRemainingAmount !== null && breakEvenRemainingAmount <= 0;
|
||||||
const breakEvenEta = latest && latest.break_even_eta_at ? fmtDate(latest.break_even_eta_at) : null;
|
const breakEvenEta = latest && latest.break_even_eta_at ? fmtDate(latest.break_even_eta_at) : null;
|
||||||
const walletBalanceCurrentAsset = payload?.summary?.payouts?.wallet_balance_current_asset;
|
const walletBalanceCurrentAsset = payload?.summary?.payouts?.wallet_balance_current_asset;
|
||||||
@@ -2805,15 +2821,20 @@
|
|||||||
key: 'earned-overall',
|
key: 'earned-overall',
|
||||||
label: `Bisher verdient gesamt ${currentCoinCurrency}`,
|
label: `Bisher verdient gesamt ${currentCoinCurrency}`,
|
||||||
value: totalEarnedOverall !== null ? fmtNumber(totalEarnedOverall, 6) : 'n/a',
|
value: totalEarnedOverall !== null ? fmtNumber(totalEarnedOverall, 6) : 'n/a',
|
||||||
sub: currentSettings?.baseline_measured_at
|
sub: [
|
||||||
? `Seit Baseline ${fmtDate(currentSettings.baseline_measured_at)}`
|
totalEarnedOverallFiat !== null ? `≈ ${fmtMoney(totalEarnedOverallFiat, reportCurrency)}` : null,
|
||||||
: 'Benötigt Baseline',
|
currentSettings?.baseline_measured_at ? `Seit Baseline ${fmtDate(currentSettings.baseline_measured_at)}` : 'Benötigt Baseline',
|
||||||
|
].filter(Boolean).join(' · '),
|
||||||
}),
|
}),
|
||||||
h(StatCard, {
|
h(StatCard, {
|
||||||
key: 'spent-overall',
|
key: 'spent-overall',
|
||||||
label: `Bisher ausgegeben gesamt ${currentCoinCurrency}`,
|
label: `Bisher ausgegeben gesamt ${currentCoinCurrency}`,
|
||||||
value: totalSpentOverallCurrentAsset !== null ? fmtNumber(totalSpentOverallCurrentAsset, 6) : 'n/a',
|
value: totalSpentOverallCurrentAsset !== null ? fmtNumber(totalSpentOverallCurrentAsset, 6) : 'n/a',
|
||||||
sub: 'FIAT und Krypto auf die aktuelle Mining-Währung reduziert',
|
sub: [
|
||||||
|
totalSpentOverallFiat !== null ? `≈ ${fmtMoney(totalSpentOverallFiat, reportCurrency)}` : null,
|
||||||
|
`Krypto ${fmtNumber(spentByType.crypto, 6)} ${currentCoinCurrency}`,
|
||||||
|
`FIAT ${fmtMoney(spentByType.fiat, reportCurrency)}`,
|
||||||
|
].filter(Boolean).join(' · '),
|
||||||
}),
|
}),
|
||||||
h(StatCard, {
|
h(StatCard, {
|
||||||
key: 'perday',
|
key: 'perday',
|
||||||
@@ -2865,13 +2886,8 @@
|
|||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
h('div', { key: 'charts', className: 'mc-overview-grid' }, [
|
h('div', { key: 'charts', className: 'mc-overview-grid' }, [
|
||||||
panel('Mining-Verlauf', 'Coins total der letzten 15 Tage.', h(SimpleChart, { type: 'line', data: overviewCharts.mining })),
|
panel('Performance-Verlauf', `${perDayLabel}-Raten der letzten 15 Tage als Tagesdurchschnitt ohne negative Ausreißer.`, h(SimpleChart, { type: 'area', data: overviewCharts.performance })),
|
||||||
panel('Performance-Verlauf', `${perDayLabel}-Raten der letzten 15 Tage.`, h(SimpleChart, { type: 'area', data: overviewCharts.performance })),
|
|
||||||
panel('Kurs-Verlauf', 'Preiswerte der letzten 15 Tage.', h(SimpleChart, { type: 'line', data: overviewCharts.pricing })),
|
panel('Kurs-Verlauf', 'Preiswerte der letzten 15 Tage.', h(SimpleChart, { type: 'line', data: overviewCharts.pricing })),
|
||||||
panel('Mining vs. Kurs', `Index-Vergleich der letzten 15 Tage. Mining wird auf ${currentCoinCurrency} pro Stunde je MH/s normalisiert, beide Reihen starten bei 100.`, h(SimpleChart, {
|
|
||||||
type: 'line',
|
|
||||||
series: overviewCharts.miningVsPrice,
|
|
||||||
})),
|
|
||||||
]),
|
]),
|
||||||
panel('Zielmonitor', `Rest-${currentCoinCurrency} und Resttage werden gegen den letzten verfuegbaren Kurs je Zielwaehrung berechnet.`,
|
panel('Zielmonitor', `Rest-${currentCoinCurrency} und Resttage werden gegen den letzten verfuegbaren Kurs je Zielwaehrung berechnet.`,
|
||||||
h('div', { className: 'mc-target-grid' },
|
h('div', { className: 'mc-target-grid' },
|
||||||
|
|||||||
Reference in New Issue
Block a user