feat(statistics): keep large totals precise in gigabytes
This commit is contained in:
@@ -32,7 +32,7 @@ const rangeItems: Array<{ id: StatisticsRange; label: string }> = [
|
|||||||
|
|
||||||
const numberFormatter = new Intl.NumberFormat("de-DE", { maximumFractionDigits: 1 });
|
const numberFormatter = new Intl.NumberFormat("de-DE", { maximumFractionDigits: 1 });
|
||||||
|
|
||||||
function formatBytes(bytes: number): string {
|
function formatBytes(bytes: number, maximumUnitIndex = Number.POSITIVE_INFINITY): string {
|
||||||
const safe = Math.max(0, Number.isFinite(bytes) ? bytes : 0);
|
const safe = Math.max(0, Number.isFinite(bytes) ? bytes : 0);
|
||||||
if (safe < 1024) {
|
if (safe < 1024) {
|
||||||
return `${Math.round(safe)} B`;
|
return `${Math.round(safe)} B`;
|
||||||
@@ -40,7 +40,7 @@ function formatBytes(bytes: number): string {
|
|||||||
const units = ["KB", "MB", "GB", "TB", "PB"];
|
const units = ["KB", "MB", "GB", "TB", "PB"];
|
||||||
let value = safe / 1024;
|
let value = safe / 1024;
|
||||||
let unitIndex = 0;
|
let unitIndex = 0;
|
||||||
while (value >= 1024 && unitIndex < units.length - 1) {
|
while (value >= 1024 && unitIndex < units.length - 1 && unitIndex < maximumUnitIndex) {
|
||||||
value /= 1024;
|
value /= 1024;
|
||||||
unitIndex += 1;
|
unitIndex += 1;
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ function formatMetric(metric: StatisticsMetric, kind: "bytes" | "count" | "perce
|
|||||||
return "–";
|
return "–";
|
||||||
}
|
}
|
||||||
if (kind === "bytes") {
|
if (kind === "bytes") {
|
||||||
return formatBytes(metric.value);
|
return formatBytes(metric.value, 2);
|
||||||
}
|
}
|
||||||
if (kind === "speed") {
|
if (kind === "speed") {
|
||||||
return `${formatBytes(metric.value)}/s`;
|
return `${formatBytes(metric.value)}/s`;
|
||||||
|
|||||||
@@ -392,6 +392,21 @@ describe("statistics model", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("statistics view", () => {
|
describe("statistics view", () => {
|
||||||
|
it("keeps large statistic data volumes precise in gigabytes instead of rounding to terabytes", () => {
|
||||||
|
const snapshot = createSnapshot();
|
||||||
|
let ledger = createStatisticsLedger(now);
|
||||||
|
ledger = recordStatisticsBytes(ledger, "realdebrid", 1_250 * 1024 ** 3, now);
|
||||||
|
snapshot.stats.statistics = ledger;
|
||||||
|
const model = buildStatisticsViewModel(snapshot, "today", now);
|
||||||
|
const html = renderToStaticMarkup(<>
|
||||||
|
<StatisticsSidebarStatus model={model} />
|
||||||
|
<StatisticsContent actions={createActions()} chart={<div />} model={model} />
|
||||||
|
</>);
|
||||||
|
|
||||||
|
expect(html.match(/1\.250 GB/g)).toHaveLength(2);
|
||||||
|
expect(html).toContain("1,2 TB");
|
||||||
|
});
|
||||||
|
|
||||||
it("marks statistic ranges for one measured vertical selection indicator", () => {
|
it("marks statistic ranges for one measured vertical selection indicator", () => {
|
||||||
const model = buildStatisticsViewModel(createSnapshot(), "today", now);
|
const model = buildStatisticsViewModel(createSnapshot(), "today", now);
|
||||||
const html = renderToStaticMarkup(<StatisticsSidebar actions={createActions()} model={model} />);
|
const html = renderToStaticMarkup(<StatisticsSidebar actions={createActions()} model={model} />);
|
||||||
|
|||||||
Reference in New Issue
Block a user