Ability to disable some chart types

Created on 8 March 2024, 10 months ago
Updated 9 May 2024, 8 months ago

Problem/Motivation

We have a site using the Highcharts.js submodule and request from the website admins to disable all but the Pie and Donut chart types because they do not want their teams using the more exotic charts. (Less is more on a marketing site for a University with 10s of vetted content editors and marketers).

I had a look to try to disable the chart types on my own, but quickly found that nothing I tried worked, including a hook_form_alter() and even registering a #prerender and #after_build function.

Fundamentally, the problem is that :

  • The hook_form_alter is called before #prerender has had a chance to run. Since all the extra fields are added in a #prerender there is nothing there to edit from the hook_form_alter
  • Registering a #prerender from the hook_form_alter runs before the #prerender tasks added by the charts module, so again there is nothing to alter.
  • Registering an #after_build from the hook_form_alter executes after the entire form has been rendered, so too late to be able to alter the items.

I'm looking for a documented approach to be able to disable or otherwise manipulate the Highcharts form elements, either programatically or via settings screen.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

✨ Feature request
Status

Fixed

Version

5.0

Component

Code

Created by

πŸ‡ͺπŸ‡¨Ecuador jwilson3

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @jwilson3
  • πŸ‡ͺπŸ‡¨Ecuador jwilson3

    After trying several things, this was my last attempt before giving up and writing up this ticket.

    I don't know if this was on the right path or not, but we ran out of time and budget to keep pushing on this at the end of the sprint.

    THIS CODE DOES NOT WORK.

    <?php
    
    use \Drupal\Core\Form\FormStateInterface;
    
    /**
     * @file
     * Primary module hooks for My Module module.
     */
    
    
    
    /**
     * Implements hook_field_widget_single_element_WIDGET_TYPE_form_alter
     *
     * @param array $element
     * @param FormStateInterface $form_state
     * @param array $context
     * @return void
     */
    function MY_MODULE_field_widget_single_element_chart_config_default_form_alter(array &$element, FormStateInterface $form_state, array $context) {
      $element['#after_build'][] = 'MY_MODULE_field_element_after_build';
    }
    
    /**
     * Processes the settings element.
     *
     * @param array $element
     *   The form element.
     * @param \Drupal\Core\Form\FormStateInterface $form_state
     *   The form state.
     *
     * @return array
     *   The element.
     *
     * @throws \Drupal\Component\Plugin\Exception\PluginException
     */
    function MY_MODULE_field_element_after_build(array $element, FormStateInterface $form_state) {
      if (
        !empty($element['config']['type']['#options'])
      ) {
        $valid_chart_types = ['donut', 'pie'];
        if ($default_type = $element['config']['#default_value']['type']) {
          $valid_chart_types = array_unique(array_merge($valid_chart_types, [$default_type]));
        }
        if($current_type = $element['config']['type']['#value']) {
          $valid_chart_types = array_unique(array_merge($valid_chart_types, [$current_type] ));
        }
    
        foreach ($element['config']['type']['#options'] as $key => $value) {
          if (!in_array($key, $valid_chart_types)) {
            unset($element['config']['type']['#options'][$key]);
          }
        }
        $form_state->setRebuild(TRUE);
      }
      return $element;
    }
    
  • πŸ‡ΊπŸ‡ΈUnited States andileco

    Thanks for sharing your work! We'll take a look.

  • First commit to issue fork.
  • Pipeline finished with Skipped
    8 months ago
    #155832
    • andileco β†’ committed 3b1e2deb on 5.0.x
      Issue #3426704 by andileco, nikathone, jwilson3: Ability to disable some...
  • Status changed to Fixed 8 months ago
  • πŸ‡ΊπŸ‡ΈUnited States andileco

    This is fixed. In this situation, you would use code like this in MYMODULE.module:

    function MYMODULE_charts_plugin_supported_chart_types_alter(array &$types, string $chart_plugin_id) {
      if ($chart_plugin_id === 'MYLIBRARY') {
        $types = array_diff($types, ['area', 'bar', 'bubble', 'column', 'gauge', 'line', 'scatter', 'solidgauge', 'spline',]);
      }
    }
    

    This new hook, which is added to charts.api.php, could also allow you to add additional chart types.

    function MYMODULE_charts_plugin_supported_chart_types_alter(array &$types, string $chart_plugin_id) {
      if ($chart_plugin_id === 'MYLIBRARY') {
        $types[] = 'candlestick';
      }
    }
    
  • πŸ‡ͺπŸ‡¨Ecuador jwilson3

    This is fantastic. Thank you so much for your responsiveness here and for introducing the new hook as a solution to alter the charts.

    Unfortunately there were other changes we were hoping to make to the edit forms as well. It seems like it's still impossible to alter the form presentation to do things like collapse the chart details element wrapper when data is already provided.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024