Guide

Chart Builder 3.6.0 — Release Notes

Tracking issue: #1539 Release: Chart Builder 3.6.0 · PRC Platform 1.5 Work period: March 2026 Scope: prc-chart-builder


Overview

Chart Builder 3.6.0 is a focused patch release that ships the server-side PNG export service end-to-end. Charts can now be automatically screenshotted via ScreenshotOne, stored as WordPress media attachments, and served as a static fallback image on the frontend. The release also fixes rendering and layout issues in the chart viewer toolbar and for synced (ref) charts.


What's New

1. Server-Side PNG Export Service (Issue #1539)

Charts can now be exported to PNG entirely on the server, with no client-side dependency.

How it works:

  1. When a chart post is saved or a WP-CLI backfill is triggered, an Action Scheduler job is queued for that post.
  2. The job calls PNG_Export::generate_png(), which builds the chart's public URL, calls the ScreenshotOne API with the chart's pixel dimensions, and receives a binary PNG.
  3. The PNG is sideloaded into the WordPress media library, attached to the chart post and set as its featured image.
  4. The attachment ID, public URL, and a hash of the current chart attributes are written to post meta (_chart_png_attachment_id, _chart_png_url, _chart_attributes_hash). The hash is used on subsequent saves to skip regeneration when nothing has changed.
  5. Old attachments are deleted automatically when a new PNG is generated.

CLI backfill:

# Dry run (default) — shows what would be processed
wp prc chart-builder backfill_pngs

# Execute against production
wp prc chart-builder backfill_pngs --dry-run=false

# Target a specific multisite URL
wp prc chart-builder backfill_pngs --dry-run=false --url=alpha.pewresearch.org/pewresearch-org

# Use a remote export URL for local testing
wp prc chart-builder backfill_pngs --dry-run=false --export-url=https://alpha.pewresearch.org/pewresearch-org

Relevant constants (set in vip-config/keys-and-tokens.php):

  • PRC_PLATFORM_SCREENSHOTONE_ACCESS_KEY
  • PRC_PLATFORM_SCREENSHOTONE_SECRET_KEY

2. Static Fallback Image on the Frontend

The chart block now renders a proper fallback when a PNG is available and JavaScript has not yet hydrated (or is unavailable).

  • PNG available — renders <img class="chart-fallback chart-fallback--png"> sized to the chart's configured layout width.
  • PNG not yet generated — renders <div class="chart-fallback chart-fallback--placeholder"> with a light-gray background and the chart's configured minimum height (or 200px).

When the PNG fallback is displayed, duplicate metadata (title, subtitle, note, tag, divider) is hidden via a CSS :has() rule so they aren't shown twice alongside the image.


3. Synced Chart (refId) Support

Synced chart instances — where a chart block references another chart post via refId — now correctly resolve PNG meta from the source chart post rather than the post they are embedded in.

  • The controller block passes refId as block context when rendering the inner chart block server-side.
  • class-chart.php uses $block->context['refId'] ?? get_the_ID() when looking up _chart_png_url, so the fallback image and Download button always point to the canonical chart.
  • The controller's Download button similarly uses $chart_ref_id (the resolved refId) when reading featured image / PNG URL meta.

Changed

  • Viewer toolbar layout — Chart/Data tabs are grouped on the left; Download image and Share are grouped on the right using flex + space-between. The Download image button is conditionally shown only when a PNG URL exists.
  • Active tab display.wp-chart-builder-chart.active and .wp-chart-builder-table.active changed from display: inline-block to display: block, removing the phantom line-box gap that appeared above the toolbar.
  • Figure marginfigure.wp-chart-builder { margin: 0; } added to strip the browser default figure margin.
  • Subtitle / note spacingmargin-bottom on .cb__subtitle and margin-top on .cb__note reduced to 4px.

Fixed

  • WP-CLI backfill_pngs processed 0 charts — The subcommand uses an underscore (backfill_pngs), not a hyphen; multisite targeting requires --url=<site-url>.
  • Export URL built from local permalink on alphagenerate_png() now accepts an optional $base_url and $export_url_override; the CLI passes --export-url through correctly so ScreenshotOne always hits the intended environment.
  • $export_url overwritten in CLI loop — Renamed the per-iteration display variable to $display_export_url so the caller-supplied --export-url override is preserved across all iterations.

Security / Logging

  • Removed the temporary do_action( 'qm/debug', ... ) alpha-testing block from generate_png().
  • Removed the success error_log call that fired on every PNG generation. Failure-path error logs are retained for Action Scheduler job debugging.

Was this helpful?