Shadow DOM and Web Components

From 8.4.1 a chart works inside a shadow root, which is where a custom element, a Lit component or any other web component renders its content. Nothing needs configuring: create the chart on an element inside the root, as you would anywhere else.

class SalesChart extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({ mode: 'open' }).innerHTML = '<div class="chart"></div>'
  }

  connectedCallback() {
    this.chart = new ApexCharts(this.shadowRoot.querySelector('.chart'), {
      chart: { type: 'bar', height: 300 },
      colors: ['var(--brand)'],
      series: [{ name: 'Sales', data: [30, 40, 35, 50] }],
      xaxis: { categories: ['Q1', 'Q2', 'Q3', 'Q4'] }
    })
    this.chart.render()
  }

  disconnectedCallback() {
    this.chart.destroy()
  }
}

customElements.define('sales-chart', SalesChart)
sales-chart {
  --brand: #1e88e5;
}

What changed in 8.4.1

Before 8.4.1 a chart inside a shadow root drew, but several parts of it looked at the document instead of the root, saw the shadow host where the chart's own nodes were, and gave up. These now work in an open shadow root, and in a root nested inside another:

  • Styles. The chart's stylesheet is injected into the root the chart renders in, not only into the document <head>, which never styles a shadow tree. It is placed first, so your rules win, and it is removed when the last chart in that root is destroyed. chart.injectStyleSheet and its nonce work the same way.
  • CSS variable colours. colors: ['var(--brand)'] resolves against the chart, so a variable set on the host element, or on any ancestor outside the root, reaches it. Treemap and heatmap shades, which are computed from the colour, used to come out grey or black when the variable was not on :root.
  • Exports. An SVG or PNG export replaces each var() colour with its live value, because outside the page the variable has nothing to resolve against. @font-face rules declared inside the root are embedded too.
  • Interaction. The export menu closes on a press outside it, context menu items run, Ctrl + Z undoes, the ink note editor stays open while you format, and storyboard finds beats that sit in the same root as the chart.

Destroy the chart with its element

Call destroy() when the element leaves the page, as in disconnectedCallback above. That releases the chart's hold on the stylesheet in its root, so the last chart to go takes the sheet with it.

The other Apex libraries

ApexGrid 3.6, ApexTree 2.2, ApexGantt 3.19 and ApexSankey 1.13 added shadow root support in the same week: their styles, tooltips and keyboard focus stay inside the root they render in. In ApexGrid, --ag-* theme tokens set on any ancestor, the shadow host included, now reach the grid; see ApexGrid styles and themes.