Problem/Motivation

I'd like to be able to automatically generate something like a tag cloud or a word cloud using data derived from Drupal content. It seems that a few of the supported chart libraries offer this kind of functionality, but it doesn't seem to be exposed in the Drupal module UI anywhere?

I also can't seem to find docs that might help with further augmenting the Charts module to make use of these library-specific kinds of features, or how to add other code to these main libraries that are already supported. For example, I'd like to somehow incorporate this D3 library:

https://github.com/jasondavies/d3-cloud

As Charts seems to support C3/D3, it seems that this might be within reach, but not sure how to proceed?

CommentFileSizeAuthor
#3 highcharts_wordcloud.png180.04 KBandileco

Comments

GNUMatrix created an issue. See original summary.

bluegeek9’s picture

I think this would need to be a separate module extending charts with an additional chart type.

andileco’s picture

Status: Active » Closed (works as designed)
StatusFileSize
new180.04 KB

I'm going to close this, because I agree a custom module is the best solution for this for now. However, here's how you could do this:

MY_MODULE.info.yml

name: 'Highcharts Wordcloud'
type: module
description: 'Enables creation of Wordclouds using the Highcharts library.'
core_version_requirement: ^10.3 || ^11
package: Examples
dependencies:
  - 'charts:charts'
  - 'charts:charts_highcharts'

MY_MODULE.libraries.yml

MY_MODULE:
  version: VERSION
  js:
    /libraries/highcharts_wordcloud/wordcloud.js: { minified: true }
  cdn:
    /libraries/highcharts_wordcloud/wordcloud.js: https://code.highcharts.com/12.1.1/modules/wordcloud.js
  dependencies:
    - charts/global
    - charts_highcharts/charts_highcharts
    - charts_highcharts/highcharts

MY_MODULE.module

<?php

/**
 * Implements hook_chart_alter().
 */
function MY_MODULE_chart_alter(array &$element, $chart_id) {
  $element['#attached']['library'][] = 'MY_MODULE/MY_MODULE';
}

/**
 * Implements HOOK_charts_plugin_supported_chart_types_alter().
 */
function MY_MODULE_charts_plugin_supported_chart_types_alter(array &$types, string $chart_plugin_id) {
  if ($chart_plugin_id === 'highcharts') {
    $types[] = 'wordcloud';
  }
}

MY_MODULE.charts_types.yml

wordcloud:
  label: 'Wordcloud'
  axis: 'y_only'
  axis_inverted: false
  stacking: false

MY_MODULE.routing.yml

MY_MODULE.display:
  path: /wordcloud-example
  defaults:
    _controller: '\Drupal\MY_MODULE\Controller\MyModule::display'
    _title: 'A Wordcloud'
  requirements:
    _permission: 'access content'

src/Controller/MyModule.php

<?php

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;

/**
 * Charts Api Example.
 */
class ChartsApiExample extends ControllerBase {

  /**
   * Display the dashboard of charts.
   *
   * @return array
   *   Array to render.
   */
  public function display() {

    // This is a container for the word cloud.
    $charts_container = [
      '#type' => 'container',
      'content' => [],
    ];

    $data = 'Chapter 1. Down the Rabbit-Hole ' .
      'Alice was beginning to get very tired of sitting by her sister on ' .
      'the bank, and of having nothing to do: ' .
      'once or twice she had peeped into the book her sister was reading, ' .
      'but it had no pictures or conversations ' .
      'in it, \'and what is the use of a book,\' thought Alice ' .
      '\'without pictures or conversation?\'' .
      'So she was considering in her own mind (as well as she could, for ' .
      'the hot day made her feel very sleepy ' .
      'and stupid), whether the pleasure of making a daisy-chain would be ' .
      'worth the trouble of getting up and picking ' .
      'the daisies, when suddenly a White Rabbit with pink eyes ran close ' .
      'by her.';
    // Convert text to lowercase and remove punctuation
    $text = strtolower($data);
    $text = preg_replace('/[^\p{L}\p{N}\s]/u', '', $text);

    // Split text into words
    $words = preg_split('/\s+/', $text, -1, PREG_SPLIT_NO_EMPTY);

    // Count word frequencies.
    $word_counts = array_count_values($words);

    // Format the result.
    $result = [];
    foreach ($word_counts as $word => $count) {
      $result[] = [
        'name' => $word,
        'weight' => $count
      ];
    }
    $charts_container['content']['wordcloud'] = [
      '#type' => 'chart',
      '#library' => 'highcharts',
      '#title' => $this->t('Highcharts Word Cloud'),
      '#chart_type' => 'wordcloud',
      'series' => [
        '#type' => 'chart_data',
        '#title' => $this->t('Occurances'),
        '#data' => $result,
      ],
    ];

    return $charts_container;
  }
}

andileco’s picture

bluegeek9’s picture

Status: Closed (works as designed) » Active

I am interested in making a Word cloud module using chartjs and the wordcloud library.

https://www.npmjs.com/package/chartjs-chart-wordcloud

What should the machine name be charts_chartjs_wordcloud ? I want to be consistent with the charts ecosystem.

andileco’s picture

We don't have a convention for charts_library_type, but we do for charts_library_extendedfeature. Check out how Highcharts is handling additional files (JS modules) and the relatively new library+type method. We might not need a separate module.

andileco’s picture

Status: Active » Closed (outdated)

Closing this. @bluegeek9 - if you end up building that module, please link to it from here.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.