You are here

public function Chart::preRender in Charts 5.0.x

Same name and namespace in other branches
  1. 8.4 src/Element/Chart.php \Drupal\charts\Element\Chart::preRender()

Main #pre_render callback to expand a chart element.

Parameters

array $element: The element.

Return value

array The chart element.

Throws

\Drupal\Component\Plugin\Exception\PluginException

File

src/Element/Chart.php, line 150

Class

Chart
Provides a chart render element.

Namespace

Drupal\charts\Element

Code

public function preRender(array $element) {

  /** @var \Drupal\charts\Plugin\chart\Library\ChartInterface[] $definitions */
  $definitions = $this->chartsManager
    ->getDefinitions();
  if (!$definitions) {
    $element['#type'] = 'markup';
    $element['#markup'] = $this
      ->t('No charting library found. Enable a charting module such as Google Charts or Highcharts.');
    return $element;
  }

  // Ensure there's an x and y axis to provide defaults.
  $type_name = $element['#chart_type'];

  /** @var \Drupal\charts\Plugin\chart\Type\TypeInterface $type */
  $type = $this->chartsTypeManager
    ->getDefinition($type_name);
  if ($type && $type['axis'] === ChartInterface::DUAL_AXIS) {
    foreach (Element::children($element) as $key) {
      $children_types[] = $element[$key]['#type'];
    }
    if (!in_array('chart_xaxis', $children_types)) {
      $element['xaxis'] = [
        '#type' => 'chart_xaxis',
      ];
    }
    if (!in_array('chart_yaxis', $children_types)) {
      $element['yaxis'] = [
        '#type' => 'chart_yaxis',
      ];
    }
  }
  self::castElementIntergerValues($element);

  // Generic theme function assuming it will be suitable for most chart types.
  $element['#theme'] = 'charts_chart';

  // Allow the chart to be altered - @TODO use event dispatching if needed.
  $alter_hooks = [
    'chart',
  ];
  $chart_id = $element['#chart_id'];
  if ($chart_id) {
    $alter_hooks[] = 'chart_' . $element['#chart_id'];
  }
  $this->moduleHandler
    ->alter($alter_hooks, $element, $chart_id);

  // Include the library specific render callback via their plugin manager.
  // Use the first charting library if the requested library is not available.
  $library = isset($element['#chart_library']) ? $element['#chart_library'] : '';
  $library = $this
    ->getLibrary($library);
  $element['#chart_library'] = $library;
  $library_form = $library . '_settings';
  $plugin_configuration = $this->chartSettings[$library_form] ?? [];
  $plugin = $this->chartsManager
    ->createInstance($library, $plugin_configuration);
  $element = $plugin
    ->preRender($element);
  if (!empty($element['#chart_definition'])) {
    $chart_definition = $element['#chart_definition'];
    unset($element['#chart_definition']);

    // Allow the chart definition to be altered - @TODO use event dispatching
    // if needed.
    $alter_hooks = [
      'chart_definition',
    ];
    if ($element['#chart_id']) {
      $alter_hooks[] = 'chart_definition_' . $chart_id;
    }
    $this->moduleHandler
      ->alter($alter_hooks, $chart_definition, $element, $chart_id);

    // Set the element #chart_json property as a data-attribute.
    $element['#attributes']['data-chart'] = Json::encode($chart_definition);
  }
  $element['#cache']['tags'][] = 'config:charts.settings';
  return $element;
}