diff --git a/CLAUDE.md b/CLAUDE.md index bfe381d..eff0e13 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -485,6 +485,11 @@ section. what the columns below show, the breakdowns are ranked bars, the devices one bar of shares; every chart has its values as a table one click away. It does not poll - it reads again when the page is looked at again. +- **The breakdowns are grouped by what they count - decided by the owner.** + Page views (pages, sites, countries, devices, browsers, systems) under one + heading, requests (what was requested, crawlers) under another: the two can + be far apart, and a card counting one beside a card counting the other + read as figures that did not add up. - This is said in the README (Analytics), `/docs` (Who visits it), `platform_guide` (`analytics`), the tool's description and the privacy page - keep them the same. diff --git a/README.md b/README.md index 66642ae..850b811 100644 --- a/README.md +++ b/README.md @@ -839,6 +839,13 @@ feature's preview. believed from an agent that is Chromium's, and only where they name a browser or system that is known, so nobody writes words of their own into an owner's figures (`VisitorClassifier`). +- **Two groups in the editor, by what they count.** The pages, the referring + sites, the countries, the devices, the browsers and the systems are counted + in page views, under that heading; what was requested by path and the + crawlers in requests, under theirs. The two can be far apart - a crawler + asks for a hundred things that are no page - so a card never leaves the + reader to guess which it is. A lambda without pages people open has the + requests group only. - **Crawlers, hardened.** A program is told from a person by [crawler-user-agents](https://github.com/monperrus/crawler-user-agents) (MIT, `Resources/Crawlers`), a maintained list of about 1,500 crawlers with a diff --git a/src/Frontend/src/control/AnalyticsTab.tsx b/src/Frontend/src/control/AnalyticsTab.tsx index ff76a0d..e269f9f 100644 --- a/src/Frontend/src/control/AnalyticsTab.tsx +++ b/src/Frontend/src/control/AnalyticsTab.tsx @@ -190,35 +190,64 @@ export function AnalyticsTab({ control }: { control: Control }) { -
- - p[by] > 0)} - by={by} - mono - name={(value) => (value === '(other)' ? said.other : value)} - /> - + {/* + * In two groups by what their numbers count, since the two can be far + * apart: a person opens a page and it loads a dozen things, a crawler + * asks for a hundred that are no page at all. An app that has no pages + * people open is described by its requests alone. + */} + {by === 'views' && ( + + + p.views > 0)} + by="views" + mono + name={(value) => (value === '(other)' ? said.other : value)} + /> + + + + r.views > 0)} + by="views" + name={(value) => (value === '(other)' ? said.other : value)} + icon={} + rest={{ label: said.direct, value: Math.max(0, state.totals.views - sum(state.referrers, 'views')) }} + /> + - - r[by] > 0)} - by={by} - name={(value) => (value === '(other)' ? said.other : value)} - icon={} - rest={by === 'views' ? { label: said.direct, value: Math.max(0, state.totals.views - sum(state.referrers, 'views')) } : undefined} - /> - + + c.views > 0)} by="views" tag={tag} /> + - - c[by] > 0)} by={by} tag={tag} /> - + + + )} - - + + + (value === '(other)' ? said.other : value)} /> - + {by === 'hits' && ( + <> + + (value === '(other)' ? said.other : value)} + icon={} + /> + + + + + + + + + )} {(state.crawlers ?? []).length === 0 ? ( @@ -227,7 +256,7 @@ export function AnalyticsTab({ control }: { control: Control }) { } /> )} -
+