Skip to content
Snippets Groups Projects
Commit 077d8527 authored by Nia Kathoni's avatar Nia Kathoni Committed by Daniel Cothran
Browse files

Issue #3390738 by andileco, nikathone: Dynamically hide chart types that are...

Issue #3390738 by andileco, nikathone: Dynamically hide chart types that are not available for the selected library
parent ef069da1
No related branches found
No related tags found
No related merge requests found
Pipeline #25873 canceled
Showing
with 157 additions and 19 deletions
......@@ -40,6 +40,15 @@ additional features, such as radar charts.
animations, it requires a commercial license. It's free for non-commercial
use. See http://www.highcharts.com
## Chart Types
Each charting library has its own set of chart types. The Charts module
focuses on chart types that are available in *most* of the libraries.
To avoid a confusing user interface, the Charts module no longer includes
chart types that are not supported by the selected library in the Chart
Type selection. For example, if you select the Chart.js library, you will
not see the "Gauge" chart type.
## Installing Libraries
All the Charts submodules default to using a content delivery network (CDN) to
......
......@@ -2,11 +2,11 @@
namespace Drupal\charts_api_example\Controller;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Extension\ModuleExtensionList;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Component\Uuid\UuidInterface;
/**
* Charts Api Example.
......
......@@ -17,7 +17,19 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*
* @Chart(
* id = "billboard",
* name = @Translation("Billboard.js")
* name = @Translation("Billboard.js"),
* types = {
* "area",
* "bar",
* "bubble",
* "column",
* "donut",
* "gauge",
* "line",
* "pie",
* "scatter",
* "spline",
* },
* )
*/
class Billboard extends ChartBase implements ContainerFactoryPluginInterface {
......
......@@ -17,7 +17,19 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*
* @Chart(
* id = "c3",
* name = @Translation("C3")
* name = @Translation("C3"),
* types = {
* "area",
* "bar",
* "bubble",
* "column",
* "donut",
* "gauge",
* "line",
* "pie",
* "scatter",
* "spline",
* },
* )
*/
class C3 extends ChartBase implements ContainerFactoryPluginInterface {
......
......@@ -15,7 +15,18 @@ use Drupal\Core\Url;
*
* @Chart(
* id = "chartjs",
* name = @Translation("Chart.js")
* name = @Translation("Chart.js"),
* types = {
* "area",
* "bar",
* "bubble",
* "column",
* "donut",
* "line",
* "pie",
* "scatter",
* "spline",
* },
* )
*/
class Chartjs extends ChartBase {
......
......@@ -20,7 +20,19 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*
* @Chart(
* id = "google",
* name = @Translation("Google")
* name = @Translation("Google"),
* types = {
* "area",
* "bar",
* "bubble",
* "column",
* "donut",
* "gauge",
* "line",
* "pie",
* "scatter",
* "spline",
* },
* )
*/
class Google extends ChartBase implements ContainerFactoryPluginInterface {
......
......@@ -21,7 +21,19 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*
* @Chart(
* id = "highcharts",
* name = @Translation("Highcharts")
* name = @Translation("Highcharts"),
* types = {
* "area",
* "bar",
* "bubble",
* "column",
* "donut",
* "gauge",
* "line",
* "pie",
* "scatter",
* "spline",
* },
* )
*/
class Highcharts extends ChartBase implements ContainerFactoryPluginInterface {
......
......@@ -5,7 +5,7 @@ namespace Drupal\charts\Annotation;
use Drupal\Component\Annotation\Plugin;
/**
* Defines an Chart annotation object.
* Defines a Chart annotation object.
*
* @Annotation
*/
......@@ -25,4 +25,11 @@ class Chart extends Plugin {
*/
public $name;
/**
* An array of chart types the chart library supports.
*
* @var array
*/
public $types = [];
}
......@@ -127,6 +127,7 @@ class BaseSettings extends FormElement {
'#type' => 'value',
'#value' => $element['#library'],
];
$selected_library = $element['#library'];
}
else {
$element['library'] = [
......@@ -142,13 +143,14 @@ class BaseSettings extends FormElement {
'wrapper' => $wrapper_id,
],
];
$selected_library = $options['library'];
}
$element['type'] = [
'#title' => new TranslatableMarkup('Chart type'),
'#type' => 'radios',
'#default_value' => $options['type'],
'#options' => self::getChartTypes(),
'#options' => self::getChartTypes($selected_library),
'#required' => $required,
'#attributes' => [
'class' => [
......@@ -586,16 +588,31 @@ class BaseSettings extends FormElement {
/**
* The types of chart.
*
* @param string $library
* The library.
*
* @return array
* The type options.
*/
public static function getChartTypes() {
$plugin_manager = \Drupal::service('plugin.manager.charts_type');
$plugin_definitions = $plugin_manager->getDefinitions();
public static function getChartTypes(string $library = ''): array {
if (!$library) {
\Drupal::logger('charts')->warning('Update your custom code to pass the library in getChartTypes().');
return [];
}
$chart_type_plugin_manager = \Drupal::service('plugin.manager.charts_type');
$chart_plugin_manager = \Drupal::service('plugin.manager.charts');
/** @var \Drupal\charts\Plugin\chart\Library\ChartInterface $chart_plugin */
$chart_plugin = $chart_plugin_manager->createInstance($library, []);
$chart_type_plugin_definitions = $chart_type_plugin_manager->getDefinitions();
$types_options = [];
foreach ($plugin_definitions as $plugin_definition) {
$types_options[$plugin_definition['id']] = $plugin_definition['label'];
foreach ($chart_type_plugin_definitions as $plugin_definition) {
$chart_type_id = $plugin_definition['id'];
if ($chart_plugin->isSupportedChartType($chart_type_id)) {
$types_options[$chart_type_id] = $plugin_definition['label'];
}
}
return $types_options;
}
......
......@@ -199,7 +199,17 @@ class Chart extends RenderElement implements ContainerFactoryPluginInterface {
$element['#chart_library'] = $library;
$charts_settings = $this->configFactory->get('charts.settings');
$plugin_configuration = $charts_settings->get('charts_default_settings.library_config') ?? [];
/** @var \Drupal\charts\Plugin\chart\Library\ChartInterface $plugin */
$plugin = $this->chartsManager->createInstance($library, $plugin_configuration);
if (!$plugin->isSupportedChartType($type_name)) {
return [
'#markup' => $this->t('Chart type @type not supported by @plugin', [
'@type' => $type_name,
'@plugin' => $plugin->getChartName(),
]),
];
}
$element = $plugin->preRender($element);
if (!empty($element['#chart_definition'])) {
......
......@@ -21,6 +21,21 @@ abstract class ChartBase extends PluginBase implements ChartInterface {
return $this->pluginDefinition['name'];
}
/**
* {@inheritdoc}
*/
public function getSupportedChartTypes() {
return $this->pluginDefinition['types'];
}
/**
* {@inheritdoc}
*/
public function isSupportedChartType(string $chart_type_id) {
$supported_chart_types = $this->getSupportedChartTypes();
return !$supported_chart_types || in_array($chart_type_id, $supported_chart_types);
}
/**
* {@inheritdoc}
*/
......
......@@ -47,4 +47,23 @@ interface ChartInterface extends PluginInspectionInterface, PluginFormInterface,
*/
public function getChartName();
/**
* Gets the supported chart types.
*
* @return array
* The supported chart types.
*/
public function getSupportedChartTypes();
/**
* Checks if a chart type is supported.
*
* @param string $chart_type_id
* The chart type ID.
*
* @return bool
* TRUE if the chart type is supported, FALSE otherwise.
*/
public function isSupportedChartType(string $chart_type_id);
}
......@@ -36,13 +36,14 @@ class ExposedChartType extends FieldPluginBase {
public function buildExposedForm(&$form, FormStateInterface $form_state) {
$label = $this->options['label'] ? $this->options['label'] : 'Chart Type';
$selected_options = $this->options['chart_types'];
$all_types = BaseSettings::getChartTypes();
$style_plugin = $this->view->style_plugin;
$settings = $style_plugin->options['chart_settings'] ?? [];
$all_types = BaseSettings::getChartTypes($settings['library']);
$options = array_filter($all_types, function ($key) use ($selected_options) {
return in_array($key, $selected_options, TRUE);
}, ARRAY_FILTER_USE_KEY);
$style_plugin = $this->view->style_plugin;
$settings = $style_plugin->options['chart_settings'] ?? [];
$chart_plugin_selected_type = $settings['type'] ?? '';
if ($chart_plugin_selected_type) {
// Move the selected.
......@@ -97,16 +98,17 @@ class ExposedChartType extends FieldPluginBase {
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$style_plugin = $this->view->style_plugin;
$settings = $style_plugin->options['chart_settings'] ?? [];
$form['chart_types'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Chart Type Options'),
'#description' => $this->t('Pick the chart type options to be exposed. You may need to disable your Views cache.'),
'#options' => BaseSettings::getChartTypes(),
'#options' => BaseSettings::getChartTypes($settings['library']),
'#default_value' => $this->options['chart_types'],
];
$style_plugin = $this->view->style_plugin;
$settings = $style_plugin->options['chart_settings'] ?? [];
if (!empty($settings['type'])) {
$form['chart_types'][$settings['type']] = [
'#default_value' => $settings['type'],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment