diff --git a/frontend/src/AnalyticsView.vue b/frontend/src/AnalyticsView.vue
index 95e52f1..504a5bb 100644
--- a/frontend/src/AnalyticsView.vue
+++ b/frontend/src/AnalyticsView.vue
@@ -152,7 +152,7 @@ const abuseRows = computed(() => formatAbuseRows(rangeData.value?.abuse || [], c
{{ formatCount(visits.length) }} visits
{{ formatCount(totalViews) }} page views
{{ readStats.avgMinPerVisit }} min/visit
- {{ readStats.avgArticleMedianMin }} min article read
+ {{ readStats.avgArticleMedianMin }} min/read
diff --git a/frontend/src/VisitorCharts.vue b/frontend/src/VisitorCharts.vue
index 7d0084f..01f9b10 100644
--- a/frontend/src/VisitorCharts.vue
+++ b/frontend/src/VisitorCharts.vue
@@ -37,6 +37,11 @@ function freqLabel(unit) {
return unit === '5min' ? '5 min' : unit === 'hour' ? 'hourly' : 'daily'
}
+/** Vertical axis caption: "visits / 5 min" on the day view, else "hourly visits" style. */
+function axisLabel(unit, ylabel) {
+ return unit === '5min' ? `${ylabel} / 5 min` : `${freqLabel(unit)} ${ylabel}`
+}
+
/** Legend label for the overlaid past weeks: "Week M" or "Week M–N". */
function pastLabel(series) {
const oldest = series.at(-1).label.slice(5) // strip "Week "
@@ -63,7 +68,7 @@ const viewChart = computed(() => buildChart(viewSeries.value, now.value))
]" :key="c.ylabel">
@@ -120,8 +125,10 @@ const viewChart = computed(() => buildChart(viewSeries.value, now.value))
.chart .ylab,
.chart .xlab,
-.chart .yaxis-label {
- font-size: 12px;
+.chart .yaxis-label,
+.chart .leglab {
+ font-family: system-ui, sans-serif; /* theme fonts can be overly styled */
+ font-size: 11px;
fill: var(--muted);
}
@@ -129,11 +136,6 @@ const viewChart = computed(() => buildChart(viewSeries.value, now.value))
font-variant-numeric: tabular-nums;
}
-.chart .leglab {
- font-size: 10px;
- fill: var(--muted);
-}
-
.chart .minor {
stroke: var(--line);
stroke-width: 1;
@@ -183,7 +185,5 @@ const viewChart = computed(() => buildChart(viewSeries.value, now.value))
stroke: var(--muted);
}
-section { margin-top: 1.8rem; }
-
.empty { color: var(--muted); }
diff --git a/frontend/src/analytics/chart.js b/frontend/src/analytics/chart.js
index dcc1818..1e92d67 100644
--- a/frontend/src/analytics/chart.js
+++ b/frontend/src/analytics/chart.js
@@ -12,7 +12,7 @@ import { formatCount } from './format.js'
export const CHART_W = 720
export const CHART_H = 126
export const PAD_TOP = 14 // room above the highest point
-export const MARGIN_L = 56 // y tick labels + vertical axis label
+export const MARGIN_L = 40 // y tick labels + vertical axis label
export const MARGIN_B = 24 // x tick labels
export const VIEW_W = MARGIN_L + CHART_W + 8
export const VIEW_H = CHART_H + MARGIN_B
@@ -156,7 +156,7 @@ export function spline(pts) {
const c1y = clampY(p1.y + (p2.y - p0.y) / 6)
const c2y = clampY(p2.y - (p3.y - p1.y) / 6)
d += `C${p1.x + (p2.x - p0.x) / 6},${c1y} `
- + `${p2.x - (p3.x - p1.x) / 6},${c2y} ${p2.x},${p2.y}`
+ + `${p2.x - (p3.x - p1.x) / 6},${c2y} ${p2.x},${p2.y}`
}
return d
}
@@ -339,7 +339,7 @@ export function xticksFor(t0, t1) {
if (span <= 4 * 365 * DAY) {
const d = new Date(t0)
let t = Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 1)
- for (; t <= t1; ) {
+ for (; t <= t1;) {
ticks.push(t)
const m = new Date(t)
t = Date.UTC(m.getUTCFullYear(), m.getUTCMonth() + 1, 1)