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

Issue fork charts-3426704

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jwilson3 created an issue. See original summary.

jwilson3’s picture

Title: Ability disable some chart types » Ability to disable some chart types
jwilson3’s picture

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'];
    // Ensure the configured default value is also available, if it happens
    // to differ from the ones we're designating as "valid" here.
    if ($default_type = $element['config']['#default_value']['type']) {
      $valid_chart_types = array_unique(array_merge($valid_chart_types, [$default_type]));
    }
    // Ensure existing content that uses any "undesired" chart types
    // do not all of a sudden break on the website.
    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;
}
andileco’s picture

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

nikathone made their first commit to this issue’s fork.

  • andileco committed 3b1e2deb on 5.0.x
    Issue #3426704 by andileco, nikathone, jwilson3: Ability to disable some...
andileco’s picture

Status: Active » Fixed

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';
  }
}
jwilson3’s picture

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.

Status: Fixed » Closed (fixed)

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