This page describes the high-level architecture of the patternfly-java-charts module, explaining how Java builder code connects to a separate npm package of React-based web components. The chart subsystem is architecturally distinct from every other module in this project — it does not render PatternFly HTML structures directly in Java; instead, it delegates all rendering to JavaScript web components.
For details on the individual Java chart builder APIs, see 6.2. For details on the web component implementations inside the npm package, see 6.3. For the build and publishing pipeline for the npm package, see 6.4.
All other patternfly-java modules (components, layouts, icons) generate HTML elements directly using the elemento/elemental2 DOM APIs, compiled by either GWT or J2CL. Chart rendering is a different problem: PatternFly's chart library is built on top of @patternfly/react-charts, which itself wraps the Victory charting library. This React/Victory stack cannot be transpiled by GWT or J2CL.
The solution is a hybrid architecture: Java code manages a custom HTML element, and a separately distributed npm package registers those custom elements as LitElement web components that mount React chart components internally.
| Module | Technology | Role |
|---|---|---|
patternfly-java-charts | Java (GWT/J2CL) | Fluent builder API; creates and configures custom HTML elements |
@patternfly-java/charts | LitElement + React | Registers custom elements; renders React chart components inside shadow DOM |
Sources: charts/pom.xml1-77 charts/npm/package.json1-56 charts/npm/README.md1-30
Diagram: Chart Subsystem — Java to JavaScript Bridge
Sources: charts/src/main/java/org/patternfly/chart/BaseChart.java1-170 charts/src/main/java/org/patternfly/chart/ChartElement.java1-38 charts/npm/src/react-wrapper.js1-393 charts/npm/src/components/pfj-chart-bullet.js1-196
The Java side lives entirely in the patternfly-java-charts Maven module (charts/pom.xml30-33). It follows the same fluent builder pattern used throughout the rest of patternfly-java, but instead of building DOM trees, it creates and configures custom HTML elements.
Diagram: Java Chart Class Hierarchy and Element Mapping
Sources: charts/src/main/java/org/patternfly/chart/BaseChart.java37-170 charts/src/main/java/org/patternfly/chart/ChartElement.java24-38 charts/src/main/java/org/patternfly/chart/donut/Donut.java1-66 charts/src/main/java/org/patternfly/chart/utilization/DonutUtilization.java1-98 charts/src/main/java/org/patternfly/chart/utilization/DonutThreshold.java1-81 charts/src/main/java/org/patternfly/chart/bullet/Bullet.java1-150
Each concrete chart class uses createHtmlElement from elemento to instantiate the custom element tag name. For example, Donut creates a pfj-chart-donut element (charts/src/main/java/org/patternfly/chart/donut/Donut.java40-41), and Bullet creates a pfj-chart-bullet element (charts/src/main/java/org/patternfly/chart/bullet/Bullet.java40-41).
The element() method on each builder returns the underlying ChartElement subtype. Builder methods directly set properties on it, e.g.:
This works because ChartElement and its subclasses are annotated with @JsType(isNative = true, namespace = JsPackage.GLOBAL), making them transparent proxies to the actual JavaScript DOM objects.
Sources: charts/src/main/java/org/patternfly/chart/ChartElement.java23-38 charts/src/main/java/org/patternfly/chart/donut/DonutElement.java25-29 charts/src/main/java/org/patternfly/chart/utilization/DonutUtilizationElement.java26-31
The @patternfly-java/charts npm package provides five custom elements. Each is a LitElement subclass that wraps a corresponding @patternfly/react-charts React component and renders it inside a shadow DOM.
| Custom Element Tag | Java Builder Class | React Component |
|---|---|---|
pfj-chart-donut | Donut | ChartDonut |
pfj-chart-donut-utilization | DonutUtilization | ChartDonutUtilization |
pfj-chart-donut-threshold | DonutThreshold | ChartDonutThreshold |
pfj-chart-bullet | Bullet | ChartBullet |
pfj-chart-pie | (none, HTML only) | ChartPie |
Sources: charts/npm/README.md8-15 charts/npm/package.json31-36
ReactWrapperElement (charts/npm/src/react-wrapper.js71-393) is the abstract LitElement base for all five custom elements. It is responsible for:
parseAttrValue converts HTML attribute strings to appropriate JS types (booleans, numbers, JSON objects/arrays) (charts/npm/src/react-wrapper.js23-41)._buildPropsFromAttributes reads all HTML attributes and converts dash-case names to camelCase (charts/npm/src/react-wrapper.js44-53).firstUpdated, it calls createRoot on a <div class="container"> inside the shadow DOM and calls _renderReact() (charts/npm/src/react-wrapper.js166-193).data, height, legendData) has a setter that calls _notifyChange(), which triggers a React re-render (charts/npm/src/react-wrapper.js214-342).pfj-chart-donut-utilization slotted inside a pfj-chart-donut-threshold is detected as a slotted child and delegated to the parent for rendering as a React child component (charts/npm/src/react-wrapper.js168-192).Subclasses implement getReactComponent() to return the React component class and any extra props specific to that chart type. For example, ChartBulletWebComponent.getReactComponent() returns [ChartBullet, extraProps] (charts/npm/src/components/pfj-chart-bullet.js36-93).
The connection between compiled Java and the running JavaScript web components is made via two mechanisms.
Java classes that mirror the custom element's JavaScript interface are annotated with @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "HTMLElement"). This tells the compiler that these Java types map to existing browser HTMLElement objects — they are not compiled to new JavaScript, but are transparent wrappers that allow Java code to read and write properties on the real DOM element.
For example, DonutUtilizationElement declares the properties data and thresholds that correspond to the JavaScript setters defined on ChartDonutUtilizationWebComponent (charts/src/main/java/org/patternfly/chart/utilization/DonutUtilizationElement.java26-31).
The file charts/src/main/resources/META-INF/externs/charts.externs.js1-204 provides Closure compiler externs for J2CL compilation. It declares the JavaScript constructors and property names for:
ChartElement — shared base with common props (height, width, title, legendData, etc.)DonutElement — adds dataDonutThresholdElement — adds data and thresholdsDonutUtilizationElement — adds data and thresholdsBulletElement — adds all bullet-specific data arraysData, BulletData, LegendData, LegendDataSymbol, Padding, ThresholdLabelsFnWithout these externs, the Closure compiler would rename these property accesses during advanced optimizations, breaking communication between the compiled Java and the JavaScript web components.
Diagram: JsInterop Boundary — Java Types to JavaScript Properties
Sources: charts/src/main/resources/META-INF/externs/charts.externs.js1-204 charts/src/main/java/org/patternfly/chart/ChartElement.java23-38 charts/src/main/java/org/patternfly/chart/donut/DonutElement.java25-29
Diagram: Runtime Data Flow from Java Builder to React Render
Sources: charts/npm/src/react-wrapper.js127-141 charts/npm/src/react-wrapper.js166-193 showcase/src/main/java/org/patternfly/showcase/chart/DonutChart.java43-56
Unlike all other patternfly-java modules, charts require consumers to install and import the @patternfly-java/charts npm package. The showcase application does this in showcase/src/web/main.js19:
import "@patternfly-java/charts/dist/charts";
And in showcase/package.json24:
"@patternfly-java/charts": "^0.0.13"
This is mandatory because the custom element registrations (customElements.define('pfj-chart-donut', ...)) must be executed by the browser before the Java-built application tries to use those element tags. Without this import, the custom elements are unknown to the browser and render as empty HTMLElement boxes with no chart output.
The npm package itself depends on lit, react, react-dom, and the full set of Victory chart packages — a dependency tree that would be impractical to compile through GWT or J2CL (charts/npm/package.json28-55).
Sources: showcase/src/web/main.js19 showcase/package.json22-26 charts/npm/package.json28-55
Refresh this wiki