Skip to content

Premium Analytics: add the Subscribers chart widget#50064

Open
kangzj wants to merge 9 commits into
trunkfrom
add/WOOA7S-1514-subscribers-chart
Open

Premium Analytics: add the Subscribers chart widget#50064
kangzj wants to merge 9 commits into
trunkfrom
add/WOOA7S-1514-subscribers-chart

Conversation

@kangzj

@kangzj kangzj commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Proposed changes

Ports the Jetpack Stats Subscribers chart card into a registered Premium Analytics widget, jpa/subscribers-chart, in the Subscribers section — and extracts the metric-cards + comparative-chart composition into a reusable toolkit component.

Why: WOOA7S-1458 is migrating the Jetpack Stats cards into the Premium Analytics dashboard. The legacy interval segmented control becomes an in-body Group by dropdown, and (per the redesign) the previous period is overlaid as a dashed line.

MetricTabsChart (reusable, widgets-toolkit)

Following the analytics-at-a-glance pattern: a row of selectable metric cards (each a headline value + period-over-period delta) over a comparative line chart, where selecting a card focuses the chart on that metric — its current solid line plus a same-colour dashed previous-period overlay. It owns selection, series building (current + type: 'comparison' dashed overlay with a transparent fill), and layout; consumers just supply per-metric data + headline values and an optional header control slot. Built so the traffic chart (WOOA7S-1504) can reuse it directly.

jpa/subscribers-chart widget

  • Two metric cards: Subscribers and Paid subscribers (the latter only when the site has paid subscribers, derived from the data).
  • Group by dropdown — day / week / month, driving the unit query param.
  • Data via the designated useStatsSubscribers hook (current + immediately-preceding window) in a small use-subscribers-chart view hook; headline value = the window's latest cumulative total, delta = period-over-period.
  • No direct proxy/apiFetch; no reinvented chart/helpers; no hardcoded colours (grouped series get a stable theme colour). Adds a stats/subscribers Storybook mock (same pattern as the existing stats/followers handler).

Related product discussion/links

Does this pull request change what data or activity we track or use?

No. It reads existing Jetpack Stats subscribers data through the established Premium Analytics proxy; no new tracking.

Testing instructions

  • jetpack build packages/premium-analytics, open Storybook → Packages/Premium Analytics/Widgets/SubscribersChart.
    • Default: two cards (Subscribers, Paid subscribers) with values + deltas; selecting a card switches the chart to that metric with its dashed previous-period overlay; the Group by dropdown changes granularity.
    • WidgetDashboardWithWidget: renders in the real WidgetDashboard as a framed "Subscribers" card.
  • On a connected dashboard (?page=jetpack-premium-analytics-wp-admin): Customize → Add widget → Subscribers in the Subscribers tab. Confirm it loads, cards switch the chart, and the console is clean.
  • /widget-audit subscribers-chart, eslint, and tsgo all pass.

Latest screenshot (two-card layout) in the comment below.

Port the Jetpack Stats subscribers chart into a registered jpa/subscribers-chart
widget: subscriber growth over time with a same-colour dashed previous-period
overlay and paid subscribers, a period-over-period delta headline, and an
in-body Group by (day/week/month) granularity dropdown. Fetches via the
designated useStatsSubscribers hook (current + preceding window) and composes
the widgets-toolkit MetricWithComparison + ComparativeLineChart primitives using
the charts group + type:'comparison' pattern. Adds a stats/subscribers Storybook
mock so the stories render.
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!

@github-actions github-actions Bot added the [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. label Jun 30, 2026
@kangzj

kangzj commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

After — jpa/subscribers-chart in the dashboard

The widget rendered through the real WidgetDashboard (Storybook harness, representative mocked data): framed Subscribers card with the period-over-period delta headline, the Group by dropdown, and the subscribers + paid lines each with a same-colour dashed previous-period overlay.

Subscribers chart widget

Verified on the live dashboard too (Customize → Add widget → Subscribers): appears in the gallery, adds and renders without crashing, and the browser console stays clean. A data-populated capture comes from the Storybook WidgetDashboard harness because the local env is in offline mode (no WPCOM connection), so the live proxy returns no real subscriber data.

@jp-launch-control

Copy link
Copy Markdown

Code Coverage Summary

This PR did not change code coverage!

That could be good or bad, depending on the situation. Everything covered before, and still is? Great! Nothing was covered before? Not so great. 🤷

Full summary · PHP report

Replace the single headline number with one selectable card per metric
(Subscribers, Paid subscribers) — each showing its value + period-over-period
delta — and switch the chart to the focused metric (its current line plus the
dashed previous-period overlay), following the analytics-at-a-glance pattern.

Extract the metric-cards + comparative-line-chart composition into a reusable
MetricTabsChart component in widgets-toolkit (owns selection, current/previous
series building, and layout) so the traffic chart (WOOA7S-1504) can reuse it;
the subscribers widget now just supplies per-metric data and the granularity
dropdown.
@kangzj

kangzj commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

Update — metric cards (analytics-at-a-glance pattern)

Replaced the single headline number with one selectable card per metric. Each card shows its value + period-over-period delta; selecting a card focuses the chart on that metric (current solid line + same-colour dashed previous-period overlay). The granularity Group by dropdown stays top-right.

Subscribers chart with metric cards

This composition is the reusable MetricTabsChart in widgets-toolkit, built so the Traffic chart (WOOA7S-1504) can reuse it. Re-verified on the live dashboard (clean console); data-populated capture is from the Storybook close-up since the local env is offline.

Use the @wordpress/ui Tabs primitive (the same family the PA dashboard and
analytics-at-a-glance use) for the metric cards instead of hand-rolled buttons,
with the card content stacked (label over value + delta) and the selected card
highlighted. Add an optional per-metric description (surfaced as the card's
tooltip) and let the tab row wrap, so the component stays reusable and
customizable for the traffic chart (WOOA7S-1504), which switches 4–5 metrics.
@kangzj

kangzj commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

Update — metric cards on @wordpress/ui Tabs (reusable)

Rebuilt MetricTabsChart on the @wordpress/ui Tabs primitive (the same family the PA dashboard's own section tabs and analytics-at-a-glance use) instead of hand-rolled buttons. Each metric is a stacked card (label over value + delta); the selected card is highlighted and drives the chart (current solid line + same-colour dashed previous-period overlay).

Subscribers chart metric cards

Reusable + customizable for the Traffic chart (WOOA7S-1504): the component takes an arbitrary metrics list (label, value, previousValue, current/previous series, optional per-metric dataFormat and description tooltip), a controls header slot, controlled selection, and a loading state. The tab row wraps so all metrics stay selectable — important for the traffic chart's 4–5 switchable metrics (no width-based hiding, unlike at-a-glance's summary slicing).

@kangzj kangzj self-assigned this Jun 30, 2026
Give the metric cards real padding, a hover state, and a clear filled selected
state, and hide the component's underline indicator so the cards read as cards.
Resolve each series' style via useSeriesStyles and pass it to ComparativeLineChart
so the chart lines, legend, and tooltip glyphs all reflect the dashed
previous-period pattern (the tooltip/legend glyphs were previously solid).
@kangzj

kangzj commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

More screenshots + card polish

Polished the metric cards (padding, hover, a clear filled selected state, hid the stray underline indicator) and fixed the legend/tooltip glyphs so the dashed previous-period pattern is reflected everywhere (via useSeriesStyles).

Subscribers selected
Metric cards, Subscribers selected

Paid subscribers selected (switching focuses the chart on that metric)
Paid subscribers selected

Tooltip glyphs now match the line pattern (solid = current, dashed = previous period)
Tooltip glyphs reflect the line pattern

In the real WidgetDashboard (framed card)
Framed card in WidgetDashboard

kangzj added 3 commits June 30, 2026 16:59
Shared, reusable building blocks belong in widgets-toolkit/src/components (like
ComparativeLineChart and ReportMetricWidget); src/widgets is for domain-specific
widget compositions. Move MetricTabsChart from src/widgets to src/components and
re-export it from the components barrel accordingly.
Match the components/ convention (report-metric, chart-comparative-line, …) with
a component-level story exercising the reusable API: multiple metrics with
selection, a single metric without a previous period, and the loading state.
Default the window end to localTZDate() (site timezone) instead of new Date()
so the terminal bucket is correct regardless of the viewer's timezone, matching
the other Stats widgets (e.g. top-posts).
@kangzj kangzj marked this pull request as ready for review June 30, 2026 05:21
@kangzj kangzj requested review from a team as code owners June 30, 2026 05:21

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @kangzj I think We should refine the widget's appearance to enhance its display in small size.

Also, we're showing Subscribers" / "Subscribers (previous period)". Should we show the date range instead?

Image Image

Comment thread projects/packages/premium-analytics/widgets/subscribers-chart/render.tsx Outdated
kangzj added 2 commits June 30, 2026 20:34
- Drop the redundant StatsSubscribersResponse casts; useStatsSubscribers already
  infers the response type from the query options.
- Key the loading overlay off isFetching so switching the Group by granularity
  shows the indicator while the new window loads, instead of leaving the
  placeholder (prior-granularity) series on screen with no feedback.
On short tiles the chart was forced to 260px and clipped to a sliver under the
metric cards. Let the chart flex-shrink to the space under the cards, and use a
ResizeObserver to drop the chart entirely below a minimum tile height so only
the metric cards show (mirrors analytics-at-a-glance). Adds a Compact story.
@kangzj

kangzj commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

@chihsuan thanks for the review!

Small widget size — addressed in d6f06b6. On short tiles the chart was forced to 260px and clipped to a sliver under the cards. It now flex-shrinks to the space under the cards, and a ResizeObserver drops the chart entirely below a minimum tile height so only the metric cards show (mirrors analytics-at-a-glance). New Compact story on MetricTabsChart demonstrates it:

Small widget size: cards only, chart dropped

Legend labels vs date range — the chart shows one metric at a time and overlays its previous period, so the legend reads Subscribers / Subscribers (previous period). I kept the metric name because with two metrics (Subscribers vs Paid subscribers) a bare date range wouldn't say which metric the line is, and the selected card already frames it. The exact dates are in the hover tooltip (e.g. Jun 15, 2026 vs May 16, 2026). Happy to switch the previous-period label to the date range (or add the range as a subtitle) if you'd prefer that — easy change.

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the metric name because with two metrics (Subscribers vs Paid subscribers) a bare date range wouldn't say which metric the line is, and the selected card already frames it. The exact dates are in the hover tooltip

Understood. it seems more related to design, so I'll defer it to the design. 🙂

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Premium Analytics [Status] In Progress [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants