[], ]; $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//*. $search_dir[] = $site_path; foreach ($search_dir as $dir) { if (file_exists($dir . $source) || file_exists($dir . $source)) { return TRUE; } } return FALSE; }