Charts & Plugins

Charts, calendars and maps are optional add-ons. In Drupal you attach them as libraries — define them in *.libraries.yml and load them with #attached in a render array or {{ attach_library() }} in Twig — then initialise them against an element you placed in the content region.

The theme's own library

AdminLTE attaches one global library on every page via adminlte.info.yml (libraries: - adminlte/global-styling). That library bundles Bootstrap, AdminLTE and Bootstrap Icons, with Drupal core dependencies:

# adminlte.libraries.yml
global-styling:
  version: 4.0.2
  css:
    theme:
      css/vendor/bootstrap-icons.min.css: { minified: true }
      css/adminlte.css: { minified: false }
      css/adminlte-drupal.css: {}
  js:
    js/vendor/bootstrap.bundle.min.js: { minified: true }
    js/adminlte.js: {}
    js/adminlte-drupal.js: {}
  dependencies:
    - core/drupal
    - core/drupalSettings
    - core/once

Defining a plugin library

Add your chart library to your sub-theme's (or module's) *.libraries.yml. Use it for ApexCharts, Chart.js, FullCalendar, jsVectorMap, etc.:

# mytheme.libraries.yml
dashboard-charts:
  js:
    https://cdn.jsdelivr.net/npm/apexcharts@3.37.1/dist/apexcharts.min.js: { type: external, minified: true }
    js/dashboard-charts.js: {}
  css:
    theme:
      https://cdn.jsdelivr.net/npm/apexcharts@3.37.1/dist/apexcharts.css: { type: external, minified: true }
  dependencies:
    - core/drupal

Attaching from a render array

From a controller, block or preprocess hook, attach the library and pass data through drupalSettings:

$build['chart'] = [
  '#type' => 'html_tag',
  '#tag' => 'div',
  '#attributes' => ['id' => 'revenue-chart'],
  '#attached' => [
    'library' => ['mytheme/dashboard-charts'],
    'drupalSettings' => [
      'adminlte' => ['revenue' => [31, 40, 28, 51, 42, 109, 100]],
    ],
  ],
];

Attaching from Twig

{{ attach_library('mytheme/dashboard-charts') }}
<div id="revenue-chart"></div>

Initialising in a Drupal behaviour

Wrap the init in a Drupal.behaviors object and guard it with once() so it runs once per element, even after AJAX:

(Drupal, once, drupalSettings) => {
  Drupal.behaviors.dashboardCharts = {
    attach(context) {
      once('revenue-chart', '#revenue-chart', context).forEach((el) => {
        const data = drupalSettings.adminlte?.revenue ?? [];
        new ApexCharts(el, {
          chart: { type: 'area', height: 300 },
          series: [{ name: 'Revenue', data }],
        }).render();
      });
    },
  };
})(Drupal, once, drupalSettings);

For self-contained sites, download the plugin into your sub-theme and reference a local path instead of a CDN URL (drop the { type: external } flag). After adding or changing a library definition, run drush cr so Drupal rebuilds the library registry.


AdminLTE 4 · Drupal port Edit on GitHub