You are here

class C3 in Charts 5.0.x

Same name and namespace in other branches
  1. 8.4 modules/charts_c3/src/Plugin/chart/Library/C3.php \Drupal\charts_c3\Plugin\chart\Library\C3

Define a concrete class for a Chart.

Plugin annotation


@Chart(
  id = "c3",
  name = @Translation("C3")
)

Hierarchy

Expanded class hierarchy of C3

File

modules/charts_c3/src/Plugin/chart/Library/C3.php, line 20

Namespace

Drupal\charts_c3\Plugin\chart\Library
View source
class C3 extends ChartBase {

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);
    $form['placeholder'] = [
      '#title' => $this
        ->t('Placeholder'),
      '#type' => 'fieldset',
      '#description' => $this
        ->t('This is a placeholder for C3.js-specific library options. If you would like to help build this out, please work from <a href="@issue_link">this issue</a>.', [
        '@issue_link' => Url::fromUri('https://www.drupal.org/project/charts/issues/3046982')
          ->toString(),
      ]),
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function preRender(array $element) {

    // Populate chart settings.
    $chart_definition = [];
    $chart_definition = $this
      ->populateOptions($element, $chart_definition);
    $chart_definition = $this
      ->populateData($element, $chart_definition);
    $chart_definition = $this
      ->populateAxes($element, $chart_definition);
    if (!isset($element['#id'])) {
      $element['#id'] = Html::getUniqueId('chart-c3');
    }
    $chart_definition['bindto'] = '#' . $element['#id'];
    $element['#attached']['library'][] = 'charts_c3/c3';
    $element['#attributes']['class'][] = 'charts-c3';
    $element['#chart_definition'] = $chart_definition;
    return $element;
  }

  /**
   * The chart type.
   *
   * @param string $chart_type
   *   The chart type.
   * @param bool $is_polar
   *   Whether polar is checked.
   *
   * @return string
   *   Return the type.
   */
  protected function getType($chart_type, $is_polar = FALSE) {

    // If Polar is checked, then convert to Radar chart type.
    if ($is_polar) {
      $type = 'radar';
    }
    else {
      $type = $chart_type == 'column' ? 'bar' : $chart_type;
    }
    return $type;
  }

  /**
   * Get options by type.
   *
   * @param string $type
   *   The chart type.
   * @param array $element
   *   The element.
   *
   * @return array
   *   Return options.
   */
  protected function getOptionsByType($type, array $element) {
    $options = $this
      ->getOptionsByCustomProperty($element, $type);
    if ($type === 'bar') {
      $options['width'] = $element['#width'];
    }
    return $options;
  }

  /**
   * Get options by custom property.
   *
   * @param array $element
   *   The element.
   * @param string $type
   *   The chart type.
   *
   * @return array
   *   Return options.
   */
  protected function getOptionsByCustomProperty(array $element, $type) {
    $options = [];
    $properties = Element::properties($element);

    // Remove properties which are not related to this chart type.
    $properties = array_filter($properties, function ($property) use ($type) {
      $query = '#chart_' . $type . '_';
      return substr($property, 0, strlen($query)) === $query;
    });
    foreach ($properties as $property) {
      $query = '#chart_' . $type . '_';
      $option_key = substr($property, strlen($query), strlen($property));
      $options[$option_key] = $element[$property];
    }
    return $options;
  }

  /**
   * Populate options.
   *
   * @param array $element
   *   The element.
   * @param array $chart_definition
   *   The chart definition.
   *
   * @return array
   *   Return the chart definition.
   */
  private function populateOptions(array $element, array $chart_definition) {
    $type = $this
      ->getType($element['#chart_type']);
    $chart_definition['title']['text'] = $element['#title'] ? $element['#title'] : '';
    $chart_definition['legend']['show'] = !empty($element['#legend_position']);
    if ($type !== 'scatter') {
      $chart_definition['axis']['x']['type'] = 'category';
    }
    $chart_definition['data']['labels'] = (bool) $element['#data_labels'];
    if ($type === 'pie' || $type === 'donut') {
    }
    elseif ($type === 'gauge') {
      $chart_definition['gauge']['min'] = $element['#gauge']['min'];
      $chart_definition['gauge']['max'] = $element['#gauge']['max'];
      $chart_definition['color']['pattern'] = [
        'red',
        'yellow',
        'green',
      ];
      $chart_definition['color']['threshold']['values'] = [
        $element['#gauge']['red_from'],
        $element['#gauge']['yellow_from'],
        $element['#gauge']['green_from'],
      ];
    }
    elseif ($type === 'line' || $type === 'spline') {
      $chart_definition['point']['show'] = !empty($element['#data_markers']);
    }
    else {

      /*
       * Billboard does not use bar, so column must be used. Since 'column'
       * is changed
       * to 'bar' in getType(), we need to use the value from the element.
       */
      if ($element['#chart_type'] === 'bar') {
        $chart_definition['axis']['rotated'] = TRUE;
      }
      elseif ($element['#chart_type'] === 'column') {
        $type = 'bar';
        $chart_definition['axis']['rotated'] = FALSE;
      }
    }
    $chart_definition['data']['type'] = $type;

    // Merge in chart raw options.
    if (!empty($element['#raw_options'])) {
      $chart_definition = NestedArray::mergeDeepArray([
        $element['#raw_options'],
        $chart_definition,
      ]);
    }
    return $chart_definition;
  }

  /**
   * Populate axes.
   *
   * @param array $element
   *   The element.
   * @param array $chart_definition
   *   The chart definition.
   *
   * @return array
   *   Return chart definition.
   */
  private function populateAxes(array $element, array $chart_definition) {

    /** @var \Drupal\Core\Render\ElementInfoManagerInterface $element_info */
    $element_info = \Drupal::service('element_info');
    $children = Element::children($element);
    $axes = array_filter($children, function ($child) use ($element) {
      $type = $element[$child]['#type'];
      return $type === 'chart_xaxis' || $type === 'chart_yaxis';
    });
    $chart_type = $this
      ->getType($element['#chart_type']);
    if ($axes) {
      foreach ($axes as $key) {

        // Make sure defaults are loaded.
        if (empty($element[$key]['#defaults_loaded'])) {
          $element[$key] += $element_info
            ->getInfo($element[$key]['#type']);
        }
        $axis_type = $element[$key]['#type'] === 'chart_xaxis' ? 'x' : 'y';
        if ($axis_type === 'x') {
          $categories = $element[$key]['#labels'] ? array_map('strip_tags', $element[$key]['#labels']) : [];
          if (!in_array($chart_type, [
            'pie',
            'donut',
          ])) {
            if ($chart_type === 'scatter') {

              //
            }
            else {
              $chart_definition['data']['columns'][] = [
                'x',
              ];
              $chart_definition['data']['x'] = 'x';
              $categories_keys = array_keys($chart_definition['data']['columns']);
              $categories_key = end($categories_keys);
              foreach ($categories as $category) {
                $chart_definition['data']['columns'][$categories_key][] = $category;
              }
            }
          }
          else {
            $chart_definition['data']['columns'] = array_map(NULL, $categories, $chart_definition['data']['columns']);
          }
        }
      }
    }
    return $chart_definition;
  }

  /**
   * Populate data.
   *
   * @param array $element
   *   The element.
   * @param array $chart_definition
   *   The chart definition.
   *
   * @return array
   *   Return the chart definition.
   */
  private function populateData(array &$element, array $chart_definition) {
    $type = $this
      ->getType($element['#chart_type']);
    $types = [];

    /** @var \Drupal\Core\Render\ElementInfoManagerInterface $element_info */
    $element_info = \Drupal::service('element_info');
    $children = Element::children($element);
    $children = array_filter($children, function ($child) use ($element) {
      return $element[$child]['#type'] === 'chart_data';
    });
    $columns = $chart_definition['data']['columns'] ?? [];
    $column_keys = array_keys($columns);
    $columns_key_start = $columns ? end($column_keys) + 1 : 0;
    foreach ($children as $key) {
      $child_element = $element[$key];

      // Make sure defaults are loaded.
      if (empty($child_element['#defaults_loaded'])) {
        $child_element += $element_info
          ->getInfo($child_element['#type']);
      }
      if ($child_element['#color'] && $type !== 'gauge') {
        $chart_definition['color']['pattern'][] = $child_element['#color'];
      }
      if (!in_array($type, [
        'pie',
        'donut',
      ])) {
        $series_title = strip_tags($child_element['#title']);
        $types[$series_title] = $child_element['#chart_type'] ? $this
          ->getType($child_element['#chart_type']) : $type;
        if ($type !== 'scatter') {
          $columns[$columns_key_start][] = $series_title;
          foreach ($child_element['#data'] as $datum) {
            if (gettype($datum) === 'array') {
              if ($type === 'gauge') {
                array_shift($datum);
              }
              $columns[$columns_key_start][] = array_map('strip_tags', $datum);
            }
            else {
              $columns[$columns_key_start][] = strip_tags($datum);
            }
          }
        }
        else {
          $row = [];
          $row[$series_title][0] = $series_title;
          $row[$series_title . '_x'][0] = $series_title . '_x';
          foreach ($child_element['#data'] as $datum) {
            $row[$series_title][] = $datum[0];
            $row[$series_title . '_x'][] = $datum[1];
          }
          $chart_definition['data']['xs'][$series_title] = $series_title . '_x';
          foreach ($row as $value) {
            $columns[] = $value;
          }
          $columns = array_values($columns);
        }
      }
      else {
        foreach ($child_element['#data'] as $datum) {
          $columns[] = $datum;
        }
      }
      $columns_key_start++;
    }
    if ($element['#stacking']) {
      $chart_definition['data']['groups'] = [
        array_keys($types),
      ];
    }
    $chart_definition['data']['types'] = $types;
    $chart_definition['data']['columns'] = $columns;
    return $chart_definition;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
C3::buildConfigurationForm public function Form constructor. Overrides ChartBase::buildConfigurationForm
C3::getOptionsByCustomProperty protected function Get options by custom property.
C3::getOptionsByType protected function Get options by type.
C3::getType protected function The chart type.
C3::populateAxes private function Populate axes.
C3::populateData private function Populate data.
C3::populateOptions private function Populate options.
C3::preRender public function Pre render. Overrides ChartInterface::preRender
ChartBase::defaultConfiguration public function Gets default configuration for this plugin. Overrides ConfigurableInterface::defaultConfiguration 1
ChartBase::getChartName public function Return the name of the chart. Overrides ChartInterface::getChartName
ChartBase::getConfiguration public function Gets this plugin's configuration. Overrides ConfigurableInterface::getConfiguration
ChartBase::getDefaultColors public static function Gets the default hex colors.
ChartBase::getDefaultSettings public static function Gets defaults settings.
ChartBase::getOptionsFromElementProperties protected function Gets options properties.
ChartBase::setConfiguration public function Sets the configuration for this plugin instance. Overrides ConfigurableInterface::setConfiguration
ChartBase::submitConfigurationForm public function Form submission handler. Overrides PluginFormInterface::submitConfigurationForm 2
ChartBase::validateConfigurationForm public function Form validation handler. Overrides PluginFormInterface::validateConfigurationForm
ChartInterface::DUAL_AXIS constant Used to define a dual axis.
ChartInterface::SINGLE_AXIS constant Used to define a single axis.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 2
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginBase::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. 98
StringTranslationTrait::$stringTranslation protected property The string translation service. 4
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.