[], ]; $data['charts_fields']['field_charts_fields_scatter'] = [ 'title' => t('Scatter Field'), 'help' => t('Use this field for your data field in a scatter plot.'), 'field' => [ 'id' => 'field_charts_fields_scatter', ], ]; $data['charts_fields']['field_charts_fields_bubble'] = [ 'title' => t('Bubble Field'), 'help' => t('Use this field for your data field in a bubble chart.'), 'field' => [ 'id' => 'field_charts_fields_bubble', ], ]; $data['charts_fields']['field_exposed_chart_type'] = [ 'title' => t('Exposed Chart Type'), 'help' => t('Use this field for exposing chart type.'), 'field' => [ 'id' => 'field_exposed_chart_type', ], ]; return $data; } /** * Implements hook_theme(). */ function charts_theme($existing, $type, $theme, $path) { return [ 'charts_chart' => [ 'render element' => 'element', ], ]; } /** * Implements hook_preprocess_HOOK(). */ function template_preprocess_charts_chart(&$variables) { $element = $variables['element']; $attributes = $element['#attributes']; $attributes['id'] = $element['#id']; $attributes['class'][] = 'chart'; $variables['content'] = [ '#type' => 'html_tag', '#tag' => 'div', '#attributes' => $attributes, '#value' => $element['#chart'] ?? '', ]; $variables['content_prefix'] = $element['#content_prefix']; $variables['content_suffix'] = $element['#content_suffix']; $config = \Drupal::config('charts.settings'); $variables['debug'] = []; if (!empty($config->get('advanced.debug'))) { $variables['debug'] = [ '#type' => 'details', '#title' => t('Chart JSON'), '#open' => FALSE, '#attributes' => [ 'data-charts-debug-container' => TRUE, ], '#collapsible' => TRUE, 'json' => [ '#prefix' => '
',
'#type' => 'html_tag',
'#tag' => 'code',
'#attributes' => [
'class' => ['language-json'],
],
'#value' => t('If this is blank, your library will need to implement code in your JavaScript. Please see the README.md.'),
'#suffix' => '',
],
];
}
}
/**
* Implements hook_views_pre_view().
*/
function charts_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
$hasFields = array_key_exists('fields', $view->display_handler->options);
if ($hasFields) {
$fields = $view->display_handler->getOption('fields');
$hasViewsFieldsOnOffHandler = FALSE;
foreach ($fields as $field) {
if (array_key_exists('plugin_id', $field)) {
if ($field['plugin_id'] == 'field_exposed_chart_type') {
$hasViewsFieldsOnOffHandler = TRUE;
}
}
}
if ($hasViewsFieldsOnOffHandler) {
// Grab the type that has been submitted.
$params = \Drupal::request()->query->all();
// This is for a GET request.
// If the view is submitted through AJAX, like in view preview, it will be
// a POST request. Merge the parameter arrays and we will get our values.
$postParams = \Drupal::request()->request->all();
$params = array_merge($params, $postParams);
foreach ($params as $key => $value) {
if (strpos($key, 'ct') === 0) {
$view->storage->set('exposed_chart_type', $value);
}
}
$view->element['#cache']['contexts'][] = 'url';
}
}
}
/**
* Implements hook_library_info_alter().
*
* Adapted from webform_library_info_alter() to add CDN support.
*/
function charts_library_info_alter(&$libraries, $extension) {
// Only process for charts_* modules.
if (strpos($extension, 'charts_') !== 0) {
return;
}
// Only try to apply cdn changes if the cdn requirements is on.
$config = \Drupal::config('charts.settings');
if (!$config->get('advanced.requirements.cdn')) {
return;
}
foreach ($libraries as &$library) {
if (isset($library['cdn']) && is_array($library['cdn'])) {
_charts_library_info_alter_recursive($library, $library['cdn']);
}
}
}
/**
* Recursive through a charts library.
*
* @param array $library
* A library defined in a chart module.
* @param array $cdn
* A associative array of library paths mapped to CDN URL.
*
* @note copied from _webform_library_info_alter_recursive().
*/
function _charts_library_info_alter_recursive(array &$library, array $cdn) {
foreach ($library as $key => &$value) {
// CSS and JS files and listed in associative arrays keyed via string.
if (!is_string($key) || !is_array($value)) {
continue;
}
// Ignore the CDN's associative array.
if ($key === 'cdn') {
continue;
}
// Replace the CDN sources (i.e. /library/*) with the CDN URL destination
// (https://cdnjs.cloudflare.com/ajax/libs/*).
foreach ($cdn as $source => $destination) {
if (_charts_library_check_source_exists($source)) {
continue;
}
if (strpos($key, $source) === 0) {
$uri = str_replace($source, $destination, $key);
$library[$uri] = $value;
$library[$uri]['type'] = 'external';
unset($library[$key]);
break;
}
}
// Recurse downward to find nested libraries.
_charts_library_info_alter_recursive($value, $cdn);
}
}
/**
* Checks whether a library source directory or file exists locally.
*
* @param string $source
* The source directory or file.
*
* @return bool
* True when the file exist, FALSE otherwise.
*/
function _charts_library_check_source_exists(string $source) {
$source = rtrim($source, '/');
$container = \Drupal::getContainer();
$app_root = $container->getParameter('app.root');
$site_path = $container->getParameter('site.path');
// The following logic is taken from libraries_get_libraries()
$search_dir = [];
$search_dir[] = $app_root;
// Similar to 'modules' and 'themes' directories inside an installation
// profile, installation profiles may want to place libraries into a
// 'libraries' directory.
$search_dir[] = 'profiles/' . \Drupal::installProfile();
// Also search sites/