You are here

public function Highcharts::buildVariables in Charts 8.3

Creates a JSON Object formatted for Highcharts JavaScript to use.

Parameters

array $options: Options.

array $categories: Categories.

array $seriesData: Series data.

array $attachmentDisplayOptions: Attachment display options.

array $variables: Variables.

string $chartId: Chart ID.

array $customOptions: Overrides.

Overrides ChartInterface::buildVariables

File

modules/charts_highcharts/src/Plugin/chart/Highcharts.php, line 532

Class

Highcharts
Defines a concrete class for a Highcharts.

Namespace

Drupal\charts_highcharts\Plugin\chart

Code

public function buildVariables(array $options, array $categories = [], array $seriesData = [], array $attachmentDisplayOptions = [], array &$variables, $chartId, array $customOptions = []) {
  $noAttachmentDisplays = count($attachmentDisplayOptions) === 0;

  // @todo: make this so that it happens if any display uses donut.
  if ($options['type'] == 'donut') {
    $options['type'] = 'pie';

    // Remove donut from seriesData.
    foreach ($seriesData as &$value) {
      $value = str_replace('donut', 'pie', $value);
    }

    // Add innerSize to differentiate between donut and pie.
    foreach ($seriesData as &$value) {
      if ($options['type'] == 'pie') {
        $innerSize['showInLegend'] = 'true';
        $innerSize['innerSize'] = '40%';
        $chartPlacement = array_search($value, $seriesData);
        $seriesData[$chartPlacement] = array_merge($innerSize, $seriesData[$chartPlacement]);
      }
    }
  }
  $yAxes = [];
  $xAxisOptions = $this
    ->buildXaxis($options, $seriesData, $categories);
  $yaxisLabels = $this
    ->buildYaxisLabels($options);
  $chartYaxis = $this
    ->buildYaxis($options['yaxis_title'], $yaxisLabels, $options, $seriesData, $categories);
  array_push($yAxes, $chartYaxis);

  // Chart libraries tend to support only one secondary axis.
  if (!$noAttachmentDisplays && $attachmentDisplayOptions[0]['inherit_yaxis'] == 0) {
    $chartYaxisSecondary = $this
      ->buildSecondaryYaxis($attachmentDisplayOptions);
    array_push($yAxes, $chartYaxisSecondary);
  }

  // Set plot options.
  $plotOptions = $this
    ->buildPlotOptions($options);
  $chartCredits = $this
    ->buildCredits($options);

  // Set charts legend.
  $chartLegend = $this
    ->buildChartLegend($options);

  // Set exporting options.
  $exporting = new ExportingOptions();
  $highchart = new HighchartsOptions();
  $highchart
    ->setChart($this
    ->buildChartType($options));
  $highchart
    ->setTitle($this
    ->buildChartTitle($options));
  if (!empty($options['subtitle'])) {
    $subtitleText = new \stdClass();
    $subtitleText->text = $options['subtitle'];
    $highchart
      ->setSubtitle($subtitleText);
  }
  $highchart
    ->setAxisX($xAxisOptions);
  $highchart
    ->setAxisY($yAxes);
  if ($options['type'] == 'gauge') {
    $pane = new Pane();
    $highchart
      ->setPane($pane);
  }
  $highchart
    ->setTooltip($this
    ->buildToolTip($options));
  $highchart
    ->setPlotOptions($plotOptions);
  $highchart
    ->setCredits($chartCredits);
  $highchart
    ->setLegend($chartLegend);

  // Usually just set the series with seriesData.
  if (($options['type'] == 'pie' || $options['type'] == 'donut') && count($seriesData[0]['data']) == 1) {
    for ($i = 0; $i < count($seriesData); $i++) {
      if (is_array($seriesData[$i]['data'][0]) && isset($seriesData[$i]['data'][0]['y'])) {
        foreach ($seriesData[$i]['data'][0] as $key => $value) {
          $seriesData[$i][$key] = $value;
        }
      }
      else {
        $seriesData[$i]['y'] = $seriesData[$i]['data'][0];
      }
      unset($seriesData[$i]['data']);
    }
    $chartData = [
      'data' => $seriesData,
    ];
    $highchart
      ->setSeries([
      $chartData,
    ]);
  }
  elseif ($options['type'] == 'scatter') {

    // You probably want to enable and use the ScatterField in charts_fields.
    $data = $seriesData[0]['data'];
    $xAxisCategories['categories'] = [];
    for ($i = 0; $i < count($categories); $i++) {
      $seriesData[$i]['name'] = $categories[$i];
      $seriesData[$i]['data'] = [
        $data[$i],
      ];

      // You may need additional colors for a scatter plot. This assumes a
      // comma-separated list of colors.
      if (!empty($options['scatter_colors'])) {
        $colors = explode(",", $options['scatter_colors']);
        $seriesData[$i]['color'] = $colors[$i];
      }
      array_push($xAxisCategories['categories'], $data[$i][0]);
    }
    $xAxisOptions = $this
      ->buildXaxis($options, $seriesData, $xAxisCategories);
    $highchart
      ->setAxisX($xAxisOptions);
    $highchart
      ->setSeries($seriesData);
  }
  elseif (!empty($options['reverse_series']) && $options['reverse_series'] == 1) {
    for ($i = 0; $i < count($categories); $i++) {
      $seriesData[$i]['name'] = $categories[$i];
      for ($j = 0; $j < count($seriesData); $j++) {
        $seriesData[$i]['data'][$j] = $seriesData[$j]['data'][0];
      }
    }
    $seriesData = array_slice($seriesData, 0, count($categories));
    $highchart
      ->setSeries($seriesData);
  }
  else {
    $highchart
      ->setSeries($seriesData);
  }
  $highchart
    ->setExporting($exporting);

  // Override Highchart classes. These will only override what is in
  // charts_highcharts/src/Settings/Highcharts/HighchartsOptions.php
  // but you can use more of the Highcharts API, as you are not constrained
  // to what is in this class. See:
  // charts_highcharts/src/Plugin/override/HighchartsOverrides.php
  foreach ($customOptions as $option => $key) {
    $setter = 'set' . ucfirst($option);
    if (method_exists($highchart, $setter)) {
      $highchart
        ->{$setter}($customOptions[$option]);
    }
  }
  $variables['chart_type'] = 'highcharts';
  $variables['content_attributes']['data-chart'][] = json_encode($highchart);
  $variables['attributes']['id'][0] = $chartId;
  $variables['attributes']['class'][] = 'charts-highchart';
}