Guide

Chart Builder 3.8.0 — Release Notes

Release: Chart Builder 3.8.0 · PRC Platform 1.5 Work period: April 2026 Scope: prc-chart-builder, prc-charting-library


Overview

Chart Builder 3.8.0 is a broad quality-of-life release focused on data integrity, editor ergonomics, and chart expressiveness. Five major features land together:

  1. Table data validation & typed columns — the Power Table block gains per-column data types and live validation, and Chart Builder registers named schemas (geo maps, time series) that gate chart sync on clean data.
  2. Multi-user editor presence & locking — see who's editing a chart alongside you, and prevent accidental conflict writes.
  3. Error bars on dot plots — per-point uncertainty visualization with full styling control.
  4. Net value labels for diverging bar charts — show the net total on each side of a diverging bar without manual label math.
  5. Chart/Data view toggle — switch the editor between chart view, data view, or both-at-once on a per-user, per-block basis.

Also in the box: automatic publishing of draft chart CPTs when a referencing post publishes, JSON-LD improvements for search-engine discoverability, a treemap refresh, a substantial Pie chart refactor, and removal of the legacy editor-side PNG generation flow.


What's New

1. Table data validation & typed columns

Background

Chart Builder has always been downstream of whatever is in the chart's source table — if the table contained a stray "N/A" in a number column, or a malformed ISO-3 country code on a choropleth map, the chart would silently render garbage (or nothing at all), and the error would only be caught by a human reviewer. This was especially painful for map charts, which require tightly formatted geographic codes, and for time-series charts, which need a real date column.

3.8.0 adds a real data-validation layer at the table level and wires it into Chart Builder so that bad data is caught in the editor, before anything is pushed to the chart.

Per-column data types

The Power Table block (core/table replacement in prc-block-library) now supports a columnMeta[].dataType attribute with the following values:

TypeAcceptsExample
autoAnything (default — infers type)
textAnything"United States"
numberIntegers or decimals, with optional commas and %1,234.56, 42%
dateISO 8601, US (M/D/YYYY), EU (D.M.YYYY), or year-only2024-01-15, 1/15/24, 2024
currencyNumbers with $, , £, ¥, or symbol$1,234.56
percentageNumber followed by %42%
urlhttp:// or https:// URLhttps://example.com
fips2-digit US state or 5-digit US county FIPS code06, 06075
iso3alphaISO 3166-1 alpha-3 country code (incl. PRC map extensions like XKX for Kosovo)USA, DEU, XKX
iso3numericISO 3166-1 numeric country code (zero-padded or not)840, 276, 383

Column type is set from the table's block-toolbar "Column type" menu on a per-column basis. Empty cells always pass validation.

Live cell validation

Every cell is validated on edit. Invalid cells pick up a .is-cell-invalid style in the editor so producers can see exactly which cells failed before they dig into the inspector panel.

Validation inspector panel

A new "Data validation" inspector panel surfaces all current validation errors with row and column coordinates and a human-readable message — e.g. body row 4 col 2: Expected an ISO 3166-1 alpha-3 country code (e.g. USA). The panel caps visible errors at five with an overflow count so a badly malformed paste doesn't blow out the sidebar.

Toolbar error-count button

A new block-toolbar button shows the current error count and, on click, jumps the user straight to the first invalid cell. This makes validation discoverable even when the inspector isn't open.

Named validation schemas

The table block exposes a PHP filter prc_table_validation_schemas so any plugin can register a named schema — a set of requiredTypes that must be present on at least one column. Registered schemas are surfaced to the editor via window.prcTableValidationSchemas and appear in the Data validation panel's schema dropdown.

Chart Builder registers five schemas out of the box:

SlugLabelRequired column types
geo-stateUS State Mapfips
geo-countyUS County Mapfips
geo-countryWorld Map (Alpha-3)iso3alpha
geo-country-numericWorld Map (Numeric)iso3numeric
timeseriesTime Seriesdate, number

Chart sync gating

This is the piece that matters most for chart quality: when a chart block detects that its source table has any column type other than auto declared or an active validation schema, it flips into "validated mode." In that mode, the chart refuses to sync data from the table into the chart attributes while isValid is false. Producers see an inline Notice warning them that their data is invalid and the chart is showing a stale render. Fixing the data immediately unblocks the sync. No more silently shipping a chart with bad geography codes or mixed numeric/text columns.

Tables that haven't opted into typed columns continue to work exactly as before — validation is opt-in per column.

For plugin authors

Other plugins can register their own schemas:

add_filter( 'prc_table_validation_schemas', function( $schemas ) {
    $schemas[] = array(
        'slug'          => 'my-custom-schema',
        'label'         => 'My Custom Schema',
        'requiredTypes' => array( 'number', 'percentage' ),
    );
    return $schemas;
} );

The table block itself registers zero schemas — it only provides the infrastructure. Chart Builder happens to be the first consumer; other chart types, map plugins, or report builders can register their own.


2. Multi-user editor presence & locking

Background

Chart Builder's editor has a few panels that are easy to stomp on when two people open the same chart at once — data entry, category ordering, label customizations. With WordPress Real-Time Collaboration rolling out across PRC sites, the chart editor needed first-class presence awareness so editors can see who else is in the chart and avoid overwriting each other's work.

What shipped

  • Presence declaration — each chart editor session publishes a lightweight presence record via the new useDeclarePresence hook (from @prc/hooks). The record includes the current user, the post ID, and which inspector panel they currently have focused.
  • Presence consumptionusePresenceUsers subscribes to all active presence records for a given chart and returns the other users currently editing it.
  • Block-level lock — the chart controller wires both hooks together in use-chart-editor-presence.js. When another user's presence is detected on the same chart, the block switches into a read-only visual state and writes to attributes are disabled. The authoring user sees who has the lock.
  • Inspector panel focus — panels in the chart block (Data, Style, Labels, Axes, etc.) broadcast their focused state so collaborators can see exactly which section another user is working in. The existing inspector-focus-context.js was extended to carry that metadata.
  • Synced chart presencesynced-chart blocks participate in the same presence model, so a user editing a synced chart preview also shows up as active on the underlying chart post.

Hook renames

Two @prc/hooks exports were renamed to better reflect intent:

Old nameNew name
usePublishPresenceuseDeclarePresence
usePresenceFeltusePresenceUsers

Existing callers across the platform were updated in the same PR; no plugin outside the monorepo consumes these directly.


3. Error bars on dot plots

Background

Dot plots are the natural home for point-estimate-plus-uncertainty visualizations (survey margins of error, confidence intervals, etc.), but until now there was no supported way to render error bars in Chart Builder. Researchers either exported the chart type as a scatter plot with post-hoc annotations or dropped back to Illustrator.

What shipped

  • ShapePanel → Error Bars — a new ErrorBarPanel inside the per-point ShapePanel popover lets editors set:
    • Lower and upper bound values (numeric, independent of the y value)
    • Stroke color (with theme token support)
    • Stroke width
    • Opacity
    • Dash array (for styled "approximate" error bars)
  • State management — a new useErrorBarCustomizations hook stores per-point error-bar config under the existing shapes attribute structure, using the same stable keying scheme as the rest of the ShapePanel customizations. No new top-level attribute was added.
  • Rendering — the DotPlot component now draws whiskered error bars under each point, in both light and dark contexts. Error bars respect the same color-interpolation rules as other label elements (the standardized getLabelFill helper).
  • Hit-test improvements — a voronoi hit model was added to DotPlot to keep hover/tooltip and label-drag targets accurate even when error-bar whiskers extend beyond the point itself.

4. Net value labels for diverging bar charts

Background

Diverging bar charts (two categories fanning out from a central axis — e.g., Favorable vs. Unfavorable) often need a "net" label summarizing each side — the sum of values, or the difference between the two sides, anchored to the end of each bar group. Authors used to add these manually with the DraggableLabel block; now Chart Builder renders them.

What shipped

  • NetValueLabels component — a new component renders net totals at each end of every diverging bar row (horizontal) or column (vertical). Values are computed from the chart's rendered data, so they track edits automatically.
  • Inspector controls — a new net-value-controls.jsx panel exposes:
    • Enable/disable per side (left/right, or top/bottom for vertical)
    • Per-side text color, font size, and offset
    • Label format (sum, difference, custom prefix/suffix)
  • Dark-mode aware — labels use the standardized getLabelFill helper so they contrast correctly against the chart background regardless of theme.
  • DraggableLabel updatesDraggableLabel was tightened in the same work so net-value labels and draggable labels share positioning logic.

5. Chart / Data view toggle

Background

The block-editor view of a chart has historically shown both the chart and the data table stacked together. That works well for quick checks, but for long data sets or narrow viewports it clutters the editor. Authors needed a way to focus on one or the other.

What shipped

  • Block toolbar button — a new "Switch to data / Switch to chart" button in the block toolbar toggles between chart-only and data-only views.
  • Inspector "Show both" toggle — a new view-mode-controls.jsx inspector panel adds an explicit three-way choice: chart-only, data-only, or both.
  • Controller Redux store — view state is held in a new chart-controller Redux store, keyed by controllerId, so the chart block, data table block, and controller wrapper stay in sync without attribute round-trips. This prevents view-mode toggling from dirtying the post.
  • Editor-only preference — view mode is a per-user authoring preference. It does not persist to the database and does not affect the published front-end output.
  • Removal of hide-table-handler.jsx — the previous ad-hoc table hiding logic was removed in favor of the new store-based flow.

6. Synced chart auto-publish

Background

The synced-chart block lets posts reference a chart CPT. Before this release, if a producer embedded a draft chart in a post and published the post, the chart itself stayed in draft — and the front-end silently rendered nothing. A separate manual "publish the chart first" step was required.

What shipped

A new Synced_Chart_Auto_Publish class hooks into the platform-wide prc_platform_on_publish and prc_platform_on_update actions. When a post publishes (or updates), the handler:

  1. Scans the post's rendered blocks for synced-chart references.
  2. For each referenced chart CPT that is still in draft, pending, or future, transitions it to publish.
  3. Logs the transition for audit.

This makes the chart lifecycle follow the parent post's lifecycle by default, matching how editors already think about it.


7. JSON-LD improvements

Dataset.description prefers alt_text

Chart CPTs emit schema.org/Dataset JSON-LD for search-engine discoverability. The description field now prefers the chart's alt_text (authored for accessibility) and falls back to the subtitle-derived description only when alt_text is empty. This gives search engines the best short summary available.

New isPartOf field

Dataset JSON-LD now includes an isPartOf array listing every published post that references the chart CPT. This surfaces the chart → story relationship to crawlers and structured-data consumers.

Synced chart reference panel filters revisions

The synced-chart inspector panel previously listed post revisions alongside the canonical post when showing "where this chart is used." Revisions are now filtered out, so the list matches what front-end users actually see.


8. Treemap sort and label refinements

The treemap variation template was updated — sort order, label rendering, and category handling were all refined. data-controls.jsx was reorganized so treemap-specific controls live together. No attribute migration was required; existing treemaps pick up the new behavior automatically.


9. Behind the scenes

  • Label fill resolution consolidated — every chart component now uses a single getLabelFill helper. The older resolveLabelFill helper was folded into it. This gives consistent dark-mode label contrast across all chart types.
  • Pie chart refactorPie.tsx was rewritten, dropping from ~1280 to ~530 lines by consolidating rendering paths and deduplicating slice/label logic. No user-visible behavior change.
  • Chart block migration tweaks — small adjustments to the v1 → v2 migration path around label controls and contrast values.
  • Editor-side PNG generation removedchart-png-panel.js and the editor-side createPNG flow were deleted (#2818). The server-side PNG pipeline introduced in 3.6.0 is now the sole path for chart images. image-exports.js was trimmed to match.
  • Version constant alignedPRC_CHART_BUILDER_VERSION bumped from the stale 3.1.0 to 3.8.0 to match the plugin header.

Files Changed (high level)

AreaChange
prc-block-library/src/table/utils/validation.tsNew — validation engine with per-type validators, FIPS / ISO-3 alpha / ISO-3 numeric datasets
prc-block-library/src/table/utils/column-meta.tsNew — resolves effective ColumnMeta and bridges legacy parallel arrays
prc-block-library/src/table/settings/table-validation-settings.tsxNew — inspector panel
prc-block-library/src/table/settings/table-validation-toolbar.tsxNew — block-toolbar error-count button
prc-block-library/src/table/class-table.phpCollects prc_table_validation_schemas filter output and localizes it to window.prcTableValidationSchemas
prc-block-library/src/table/block.jsonNew columnMeta, validationSchema, isValid attributes
prc-chart-builder/src/controller/class-controller.phpRegisters five built-in schemas via prc_table_validation_schemas filter
prc-chart-builder/src/chart/edit/index.jsxReads tableIsValid / tableValidationSchema from table context; gates chart sync; renders inline warning
@prc/hooksRenamed usePublishPresenceuseDeclarePresence, usePresenceFeltusePresenceUsers
src/controller/use-chart-editor-presence.jsNew — controller-level presence + lock wiring
src/chart/edit/inspector-focus-context.jsExtended to broadcast panel focus
src/synced-chart/use-chart-presence.jsNew — synced-chart participation in presence model
src/chart/edit/popover/ErrorBarPanel.jsxNew — per-point error-bar controls
src/chart/edit/popover/hooks/useErrorBarCustomizations.jsNew — error-bar state hook
prc-charting-library/src/.../DotPlot.tsxError-bar rendering + voronoi hit model
prc-charting-library/src/.../NetValueLabels.tsxNew — net value label component
src/chart/edit/inspector/net-value-controls.jsxNew — net label inspector panel
src/chart/edit/inspector/view-mode-controls.jsxNew — view mode inspector toggle
src/controller/Edit.jsx / src/controller/block.jsonController view-mode store + toolbar button
src/chart/edit/hide-table-handler.jsxRemoved
includes/class-synced-chart-auto-publish.phpNew — auto-publish class
includes/class-json-ld.php (or equivalent)alt_text preference, isPartOf field, revision filter
src/variations/treemap.js + data-controls.jsxTreemap sort/label updates
prc-charting-library/src/.../getLabelFill.tsConsolidation of resolveLabelFill
prc-charting-library/src/.../Pie.tsxFull refactor
src/chart/edit/chart-png-panel.jsRemoved
src/chart/edit/image-exports.jsTrimmed
prc-chart-builder.phpPRC_CHART_BUILDER_VERSION3.8.0

Upgrade Notes

  • No database migrations. All new attributes are additive with sensible defaults.
  • No breaking changes for published content. Existing charts continue to render identically.
  • Table validation is opt-in. Tables with every column set to auto behave exactly as before. The chart-sync gate only activates when a table declares a non-auto column type or picks an active validation schema.
  • Plugin authors: the prc_table_validation_schemas filter is public API. Any plugin that embeds the Power Table and has schema requirements should register them via this filter rather than reimplementing validation.
  • Presence hooks renamed. The two renames (usePublishPresenceuseDeclarePresence, usePresenceFeltusePresenceUsers) only affect intra-monorepo callers, which were updated in the same PR. External plugins should not be consuming these.
  • Editor-side PNG generation is gone. If any custom integration relied on createPNG from the chart editor, migrate to the server-side PNG endpoint introduced in 3.6.0.
  • Synced chart auto-publish is on by default. Draft charts referenced by a publishing post will transition to publish automatically. Posts that reference charts they don't intend to publish should hold the referencing post as draft.

Tracked Issues

  • #2565 — Table data validation, typed columns, schemas, chart sync gate
  • #2850 — Editor presence & locking
  • #2121 — Dot plot error bars
  • #2745 — Net value labels for diverging bars
  • #2808 — Chart / Data view toggle
  • #2814 — JSON-LD improvements
  • #2818 — Unhook editor-side PNG generation
  • #2873 — Treemap refinements
  • #2807 — 3.8.0 tracking / label fill consolidation / Pie refactor

Was this helpful?