diff --git a/modules/charts_api_example/templates/charts_api_example.html.twig b/modules/charts_api_example/templates/charts_api_example.html.twig index 49e1b816e4b992245dacc0acf47e9906a4e40d5b..561c1e10949264e284722b59bcd0be867430b9a6 100644 --- a/modules/charts_api_example/templates/charts_api_example.html.twig +++ b/modules/charts_api_example/templates/charts_api_example.html.twig @@ -1,6 +1,6 @@ -{% set library = 'charts_' ~ chart_type ~ '/' ~ chart_type %} +{% set library, height, width = 'charts_' ~ chart_type ~ '/' ~ chart_type, options.height, options.width %} {{ attach_library("#{ library }") }} <p>Edit charts_api_example.html.twig to delete this message. To change the library used by this file, change the <a href="{{ url('charts.settings',{}) }}">default settings</a>. </p> -<div {{ attributes }} {{ content_attributes }} style="width:100%; height:400px;"></div> +<div {{ attributes }} {{ content_attributes }} style="width:{{ width }};height:{{ height }};"></div> diff --git a/modules/charts_blocks/charts_blocks.info.yml b/modules/charts_blocks/charts_blocks.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..72a3c879f13809c78d36883e35c583ccbfa741b8 --- /dev/null +++ b/modules/charts_blocks/charts_blocks.info.yml @@ -0,0 +1,7 @@ +name: Charts Blocks +type: module +description: Create Charts blocks without the need for Views. +core: 8.x +package: Charts +dependencies: + - charts diff --git a/modules/charts_blocks/charts_blocks.module b/modules/charts_blocks/charts_blocks.module new file mode 100644 index 0000000000000000000000000000000000000000..ac9f68180d8383c6c789f1c5f9b84c2ac5ee54d9 --- /dev/null +++ b/modules/charts_blocks/charts_blocks.module @@ -0,0 +1,69 @@ +<?php + +/** + * @file + * Contains chart_block_example.module. + */ + +use Drupal\block\Entity\Block; +use Drupal\charts\Charts\ModuleSelector; +use Drupal\Core\Routing\RouteMatchInterface; + + +/** + * Implements hook_help(). + */ +function charts_blocks_help($route_name, RouteMatchInterface $route_match) { + switch ($route_name) { + // Main module help for the charts_blocks module. + case 'help.page.charts_blocks': + $output = ''; + $output .= '<h3>' . t('About') . '</h3>'; + $output .= '<p>' . t('Create Charts blocks without the need for Views.') . '</p>'; + return $output; + + default: + } +} + +/** + * Implements hook_theme(). + */ +function charts_blocks_theme() { + return [ + 'charts_blocks' => [ + 'template' => 'charts-block', + 'variables' => [ + 'library' => '', + 'categories' => '', + 'seriesData' => '', + 'options' => '', + 'id' => '', + ] + ], + ]; +} + +/** + * Implements template_preprocess_page + * + * @param $variables + */ +function template_preprocess_charts_blocks(&$variables) { + $plugin_manager = \Drupal::service('plugin.manager.charts'); + $plugin = $plugin_manager->createInstance($variables['library']); + $plugin->buildVariables($variables['options'], $variables['categories'], $variables['seriesData'], [], $variables, $variables['id']); +} + +///** +// * Implements template_preprocess_page +// * +// * @param $variables +// */ +//function charts_blocks_preprocess_block(&$variables) { +// if($variables['plugin_id'] == 'charts_block') { +// $plugin_manager = \Drupal::service('plugin.manager.charts'); +// $plugin = $plugin_manager->createInstance($variables['content']['#library']); +// $plugin->buildVariables($variables['content']['#options'], $variables['content']['#categories'], $variables['content']['#seriesData'], [], $variables['content']['#options'], 'id'); +// } +//} \ No newline at end of file diff --git a/modules/charts_blocks/src/Plugin/Block/ChartsBlock.php b/modules/charts_blocks/src/Plugin/Block/ChartsBlock.php new file mode 100644 index 0000000000000000000000000000000000000000..7703275978626e2f28b4b59f859c4a12137d7f4b --- /dev/null +++ b/modules/charts_blocks/src/Plugin/Block/ChartsBlock.php @@ -0,0 +1,259 @@ +<?php + +namespace Drupal\charts_blocks\Plugin\Block; + +use Drupal\Core\Block\BlockBase; +use Drupal\Core\Form\FormStateInterface; +use Drupal\charts\Form\ChartsConfigForm; +use Drupal\Core\Language\LanguageInterface; + +\Drupal::moduleHandler()->loadInclude('charts', 'inc', 'includes/charts.pages'); + +/** + * Provides a 'ChartsBlock' block. + * + * @Block( + * id = "charts_block", + * admin_label = @Translation("Charts block"), + * ) + */ +class ChartsBlock extends BlockBase { + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + + // Get the default chart values. + $defaults = \Drupal::state()->get('charts_default_settings', []); + + $defaults += charts_default_settings(); + foreach ($defaults as $default_key => $default_value) { + $options[$default_key]['default'] = $default_value; + } + + return $defaults; + + } + + /** + * {@inheritdoc} + */ + public function blockForm($form, FormStateInterface $form_state) { + parent::blockForm($form, $form_state); + + // Merge in the global chart settings form. + $field_options = []; + $parents = ['charts_default_settings']; + $form = charts_settings_form($form, $this->defaultConfiguration(), $field_options, $parents); + + /** + * @todo figure out why the block label field does not respect weight. + */ + // Reposition the block form fields to the top. + $form['label']['#weight'] = '-26'; + $form['label_display']['#weight'] = '-25'; + + // Check if chart will be a series. + $form['series'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Series'), + '#description' => $this->t('Does this chart graph more than a single series?'), + '#default_value' => $this->configuration['series'], + '#weight' => '-22', + ]; + + // If a single series. + $form['data'] = [ + '#type' => 'textarea', + '#title' => $this->t('Data (single series)'), + '#description' => $this->t('Enter the data for your chart, separated by comma: 1,3,5,7'), + '#default_value' => $this->configuration['data'], + '#weight' => '-19', + '#states' => [ + 'invisible' => [ + ':input[name="settings[series]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['series_label'] = [ + '#type' => 'textarea', + '#title' => $this->t('Series label (single series)'), + '#description' => $this->t('Provide a label for your legend'), + '#default_value' => $this->configuration['series_label'], + '#weight' => '-18', + '#states' => [ + 'invisible' => [ + ':input[name="settings[series]"]' => ['checked' => TRUE], + ], + ], + ]; + + // If making a series chart, the API requires this format. + $form['data_series'] = [ + '#type' => 'textarea', + '#title' => $this->t('Data (multiple series)'), + '#description' => $this->t('Enter the data for your chart using this format (must be valid JSON): {"name":"Number of players","color":"#0d233a","data":[50,60,100,132,133,234]},{"name":"Number of coaches","color":"#ff0000","data":[50,80,100,32,133,234]}'), + '#default_value' => $this->configuration['data_series'], + '#weight' => '-17', + '#states' => [ + 'invisible' => [ + ':input[name="settings[series]"]' => ['checked' => FALSE], + ], + ], + '#placeholder' => 'Check the instructions below for formatting syntax.', + ]; + $form['categories'] = [ + '#type' => 'textarea', + '#title' => $this->t('Categories'), + '#description' => $this->t('List categories. You should have as many as you have points of data in a series. They should be comma-separated: One,Two,Three,Four'), + '#default_value' => $this->configuration['categories'], + '#weight' => '-16', + ]; + + /** + * Unset the #parents element from default form, then set the + * default value. + */ + unset($form['library']['#parents']); + $form['library']['#default_value'] = $this->configuration['library']; + $form['library']['#weight'] = '-23'; + + unset($form['type']['#parents']); + $form['type']['#default_value'] = $this->configuration['type']; + $form['type']['#weight'] = '-24'; + + unset($form['display']['title']['#parents']); + $form['display']['title']['#default_value'] = $this->configuration['title']; + + unset($form['display']['title_position']['#parents']); + $form['display']['title_position']['#default_value'] = $this->configuration['title_position']; + + unset($form['display']['data_labels']['#parents']); + $form['display']['data_labels']['#default_value'] = $this->configuration['data_labels']; + + unset($form['display']['background']['#parents']); + $form['display']['background']['#default_value'] = $this->configuration['background']; + + unset($form['display']['legend_position']['#parents']); + $form['display']['legend_position']['#default_value'] = $this->configuration['legend_position']; + + unset($form['display']['tooltips']['#parents']); + $form['display']['tooltips']['#default_value'] = $this->configuration['tooltips']; + + unset($form['display']['dimensions']['height']['#parents']); + $form['display']['dimensions']['height']['#default_value'] = $this->configuration['height']; + + unset($form['display']['dimensions']['width']['#parents']); + $form['display']['dimensions']['width']['#default_value'] = $this->configuration['width']; + + /** + * @todo: complete this for the remaining form elements. + */ + + return $form; + } + + /** + * {@inheritdoc} + */ + public function blockSubmit($form, FormStateInterface $form_state) { + + $this->configuration['library'] = $form_state->getValue('library'); + $this->configuration['type'] = $form_state->getValue('type'); + $this->configuration['series'] = $form_state->getValue('series'); + $this->configuration['data'] = $form_state->getValue('data'); + $this->configuration['data_series'] = $form_state->getValue('data_series'); + $this->configuration['series_label'] = $form_state->getValue('series_label'); + $this->configuration['categories'] = $form_state->getValue('categories'); + $this->configuration['field_colors'] = $form_state->getValue('field_colors'); + $this->configuration['title'] = $form_state->getValue(['display','title']); + $this->configuration['title_position'] = $form_state->getValue(['display','title_position']); + $this->configuration['data_labels'] = $form_state->getValue(['display','data_labels']); + $this->configuration['legend'] = $form_state->getValue('legend'); + $this->configuration['legend_position'] = $form_state->getValue(['display','legend_position']); + $this->configuration['colors'] = $form_state->getValue('colors'); + $this->configuration['background'] = $form_state->getValue(['display','background']); + $this->configuration['tooltips'] = $form_state->getValue(['display','tooltips']); + $this->configuration['tooltips_use_html'] = $form_state->getValue('tooltips_use_html'); + $this->configuration['width'] = $form_state->getValue(['display','dimensions','width']); + $this->configuration['height'] = $form_state->getValue(['display','dimensions','height']); + $this->configuration['xaxis_title'] = $form_state->getValue('xaxis_title'); + $this->configuration['xaxis_labels_rotation'] = $form_state->getValue('xaxis_labels_rotation'); + $this->configuration['yaxis_title'] = $form_state->getValue('yaxis_title'); + $this->configuration['yaxis_min'] = $form_state->getValue('yaxis_min'); + $this->configuration['yaxis_max'] = $form_state->getValue('yaxis_max'); + $this->configuration['yaxis_prefix'] = $form_state->getValue('yaxis_prefix'); + $this->configuration['yaxis_suffix'] = $form_state->getValue('yaxis_suffix'); + $this->configuration['yaxis_decimal_count'] = $form_state->getValue('yaxis_decimal_count'); + $this->configuration['yaxis_labels_rotation'] = $form_state->getValue('yaxis_labels_rotation'); + + } + + /** + * {@inheritdoc} + */ + public function build() { + + $options = [ + 'library' => $this->configuration['library'], + 'type' => $this->configuration['type'], + 'field_colors'=>$this->configuration['field_colors'], + 'title'=>$this->configuration['title'], + 'title_position'=>$this->configuration['title_position'], + 'data_labels'=>$this->configuration['data_labels'], + 'legend'=>$this->configuration['legend'], + 'legend_position'=>$this->configuration['legend_position'], + 'colors'=>$this->configuration['colors'], + 'background'=>$this->configuration['background'], + 'tooltips'=>$this->configuration['tooltips'], + 'tooltips_use_html'=>$this->configuration['tooltips_use_html'], + 'width'=>$this->configuration['width'], + 'height'=>$this->configuration['height'], + 'xaxis_title'=>$this->configuration['xaxis_title'], + 'xaxis_labels_rotation'=>$this->configuration['xaxis_labels_rotation'], + 'yaxis_title'=>$this->configuration['yaxis_title'], + 'yaxis_min'=>$this->configuration['yaxis_min'], + 'yaxis_max'=>$this->configuration['yaxis_max'], + 'yaxis_prefix'=>$this->configuration['yaxis_prefix'], + 'yaxis_suffix'=>$this->configuration['yaxis_suffix'], + 'yaxis_decimal_count'=>$this->configuration['yaxis_decimal_count'], + 'yaxis_labels_rotation'=>$this->configuration['yaxis_labels_rotation'] + ]; + + $data = json_decode('[' . $this->configuration['data'] . ']', true); + + $categories = explode(",", $this->configuration['categories']); + + if(!empty($this->configuration['data_series'])) { + $seriesData = json_decode('[' . $this->configuration['data_series'] . ']', true); + } else { + $seriesData = [ + [ + 'name' => $this->configuration['series_label'], + 'color' => '#0d233a', + 'data' => $data + ], + ]; + } + + /** + * @todo: refactor the way this id is produced to ensure uniqueness. + */ + $chartId = strtolower($this->label()); + $chartId = preg_replace('/[^a-z0-9_]+/', '_', $chartId); + $chartId = preg_replace('/_+/', '_', $chartId); + + $build = [ + '#theme' => 'charts_blocks', + '#library' => $this->configuration['library'], + '#categories' => $categories, + '#seriesData' => $seriesData, + '#options' => $options, + '#id' => $chartId, + ]; + + return $build; + } + +} diff --git a/modules/charts_blocks/templates/charts-block.html.twig b/modules/charts_blocks/templates/charts-block.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..b2a89501e1b292c9d5eed8e0ed88e237a27eadea --- /dev/null +++ b/modules/charts_blocks/templates/charts-block.html.twig @@ -0,0 +1,3 @@ +{% set library, height, width = 'charts_' ~ library ~ '/' ~ library, options.height, options.width %} +{{ attach_library("#{ library }") }} +<div {{ attributes }} {{ content_attributes }} style="width:{{ width }};height:{{ height }};"></div> diff --git a/templates/views-view-charts.html.twig b/templates/views-view-charts.html.twig index 5c4f4a3449a91d2ae9f78cadf1f81b1dc55ca6c0..f46df05abfd7a0903af23385ecbc2fd085a67532 100644 --- a/templates/views-view-charts.html.twig +++ b/templates/views-view-charts.html.twig @@ -1,3 +1,3 @@ -{% set library = 'charts_' ~ chart_type ~ '/' ~ chart_type %} +{% set library, height, width = 'charts_' ~ chart_type ~ '/' ~ chart_type, options.height, options.width %} {{ attach_library("#{ library }") }} -<div {{ attributes }} {{ content_attributes }} style="width:100%; height:400px;"></div> +<div {{ attributes }} {{ content_attributes }} style="width:{{ width }};height:{{ height }};"></div>