feat(analytics): server-side totals for matrix reports (subtotals + grand total)#1779
Merged
Conversation
fix(app-shell): NavigationSyncEffect baseline race — readiness gate, sys_ filter, ADR-0010 lock filter (#1668) objectui@e95cc25b2c0d2fa680e232151721e71c19630659
queryDataset selections accept totals.groupings — dimension subsets the executor re-runs the full selection against (measure-scoped filters, derived measures, compareTo included), returning marginal aggregates on AnalyticsResult.totals. Each subtotal/grand total is the measure's true aggregate over the underlying rows, never re-derived from bucketed values (ADR-0021 governance line). Dimension display labels resolve on totals rows the same way as the primary grid. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
xuyushun441-sys
added a commit
to objectstack-ai/objectui
that referenced
this pull request
Jun 12, 2026
…#1669) Framework PR objectstack-ai/objectstack#1779 (issue #1753) added server-side totals to queryDataset. The matrix renderer now requests totals: { groupings: [rows, columns, []] } and renders the returned pre-aggregated rows: a trailing Total column per measure (row subtotals), a trailing Total row (column subtotals), and the grand total at their intersection — matched to pivot headers via the same bucketId logic. No totals in the response (older server) renders exactly as before; the client never re-aggregates (ADR-0021). Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1753.
What
queryDatasetselections now accept atotalsoption:Each grouping is a subset of
selection.dimensions; theDatasetExecutorre-runs the full selection grouped only by those dimensions and returns the marginal aggregates onAnalyticsResult.totals(one entry per grouping, in request order, same measure columns as the primary rows).Why explicit groupings
The server sees a flat
dimensionsarray — it cannot infer the matrix's rows/columns split, so the caller names the marginals it wants. A matrix report asks for per-row subtotals (group by row dims), per-column subtotals (group by column dims), and the grand total ([]).Design notes
avgtotal is the average over all underlying rows (not an average of bucket averages) andcount_distinctstays correct — the ADR-0021 governance line that made the client renderer refuse to invent totals.compareToall apply to totals identically (the pipeline is reused, not duplicated).order/limit/offsetare dropped for totals queries — totals cover the full selection, and an order key may reference a dimension the grouping drops.previewDrafts) — the in-memory evaluator already handles dimensionless queries.POST /analytics/dataset/queryendpoint passes the selection through verbatim, so no endpoint changes were needed.Consumer follow-up
objectui's
DatasetMatrixTable(packages/plugin-report/src/DatasetReportRenderer.tsx) can now requesttotals: { groupings: [rows, columns, []] }and render the supplied totals row/column — tracked as the consumer half of #1753.🤖 Generated with Claude Code