How to use plugins?

Created on 25 July 2024, 3 months ago
Updated 22 August 2024, about 2 months ago

I'm looking to use datalabels in my charts. Ideally I'd like to use chartjs as the charting library and then integrate the datalabels plugin, but I am very open to other methods of doing this. I'm a little lost on the documentation for version 5.0+ and searching around the internet doesn't help me very much.

I've attached an image of a version of a chart I'm making. Below is the code used to generate that chart

$charts_container = [
'#type' => 'container',
'#attributes' => [
'class' => ['pop_by_sex'],
'id' => $chart_id,
],
'content' => [
'three_series_column' => [
'#type' => 'chart',
'#data_labels' => TRUE,
'#tooltips' => $charts_settings->get('charts_default_settings.display.tooltips'),
'#chart_type' => 'column',
'series_one' => $male_series,
'series_two' => $female_series,
'series_three' => $total_series,
'x_axis' => $xaxis,
'y_axis' => $yaxis,
'#raw_options' => [
'options' => [
'maintainAspectRatio' => FALSE,
'responsive' => TRUE,
'plugins' => [
'title' => [
'display' => FALSE,
],
'legend' => [
'position' => 'top',
'labels' => [
'font' => [
'size' => 16,
'family' => 'Montserrat, Helvetica, sans-serif',
],
],
],
'datalabels' => [
'display' => TRUE,
'align' => 'center',
'anchor' => 'end',
'color' => '#666666',
'font' => [
'size' => 12,
'family' => 'Montserrat, Helvetica, sans-serif',
],
],
],
'scales' => [
'y' => [
'beginAtZero' => FALSE,
'ticks' => [
'font' => [
'size' => 16,
'family' => 'Montserrat, Helvetica, sans-serif',
],
],
],
'x' => [
'ticks' => [
'font' => [
'size' => 16,
'family' => 'Montserrat, Helvetica, sans-serif',
],
],
],
],
],
],
],
],
];

I'm really just looking for guidance on the best way to get data labels working and I'm open to anything. I've been at this for a couple of days and getting stumped. Even just being pointed in the direction of how to manage either data labels in general or with how to integrate plugins into drupal charts would be immensely helpful to me.

πŸ’¬ Support request
Status

Fixed

Version

5.1

Component

Chart.js integration

Created by

πŸ‡¨πŸ‡¦Canada kevin.bruner

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @kevin.bruner
  • πŸ‡ΊπŸ‡ΈUnited States andileco

    Hi @kevin.bruner, are you on the Drupal Slack workspace? There was a very similar request with some back-and-forth: https://drupal.slack.com/archives/C878FC7HS/p1720606113996459

    Let me try to summarize here:
    My first request would be to create a patch on this issue that gives Chart.js-specific settings to enable that plugin electively. The charts_highcharts submodule has a good example of how to do this. If you go to Configuration > Content Authoring > Charts Settings and select "Highcharts", then click the tab that says, "Highcharts settings", you'll see two checkboxes, one for enabling the "Exporting" library and another for enabling the "Texture" library. These are essentially Highcharts plugins. Then, in the Highcharts.php file, we attach those libraries if they are enabled in the settings.

    If that seems like too much (which I don't think it should be), you can also write a custom module that overrides the library info to add in the new JS and also replace charts_chartjs.js with your own copy that includes "plugins" around here: https://git.drupalcode.org/project/charts/-/blob/5.0.x/modules/charts_ch...

    There's some info on how to overwrite the library here: https://git.drupalcode.org/project/drupal/-/blob/11.x/core/lib/Drupal/Co...

  • πŸ‡¨πŸ‡¦Canada kevin.bruner

    Thanks. I'll look into that. I think you. I think we may have a case of this on our hands here because I'm not familiar at all with the modules structure https://xkcd.com/2501/

    I'll report back with what I'm able to do, but I'll be learning these components and how to modify them from scratch

  • πŸ‡ΊπŸ‡ΈUnited States andileco

    Haha, I don't feel like an expert, but I appreciate it!

    Can you send a picture of what you're hoping for and what you're getting instead?

    I can try to send some links from the Highcharts example that would directly correspond to what's needed for the first (preferred) approach.

  • πŸ‡¨πŸ‡¦Canada kevin.bruner

    Here's attached the end goal. I've attached the current state in my original post. I'm really just an IT generalist on a very small team trying to refactor out some vue.js another developer left in that is unmaintainable. Drupal is just a tool we use and this is the first module I've attempted to write, so I didn't expect to go fully into the weeds of creating patches and modifying other modules on my first foray, but I'll do that if it's the best way to get some numerical values on these charts.

  • πŸ‡ΊπŸ‡ΈUnited States andileco

    OK, so I looked into this more, and I'm changing my tune. I think dataLabels is actually just a default Charts module feature that was originally missing from Chart.js. So I'm going to add this in more directly and not make it an optional library like my first suggestion.

  • Merge request !104Add dataLabels option for Chart.js β†’ (Merged) created by andileco
  • πŸ‡ΊπŸ‡ΈUnited States andileco

    Please try this patch!

  • πŸ‡¨πŸ‡¦Canada kevin.bruner

    That's great! I'll try it out this morning and let you know. Thanks so much!

  • πŸ‡ΊπŸ‡ΈUnited States andileco

    At the same level as '#type' => 'chart' you can add: '#data_labels' => TRUE,

  • Status changed to Needs review 3 months ago
  • πŸ‡ΊπŸ‡ΈUnited States andileco

    I added a quick screenshare video for adding data labels in Views (hint: checking the box that says, "Enable data labels"). This is the normal behavior for other libraries; now Chart.js has it too.

    If this looks good, please move to RTBC.

  • πŸ‡¨πŸ‡¦Canada kevin.bruner

    I was able to apply the patch and I can see the code changes on my server as expected. I can see the option in the views menu, but I'm not using views. I'm trying to create a custom block using a module. I've added the datalabels line where I believe it should go (see below) but to no effect. Is there something else I need to do?

    $charts_container = [
    '#type' => 'container',
    '#data_labels' => TRUE,
    '#attributes' => [
    'class' => ['pop_by_sex'],
    'id' => $chart_id,
    ],
    'content' => [
    'three_series_column' => [
    '#type' => 'chart',
    '#tooltips' => $charts_settings->get('charts_default_settings.display.tooltips'),
    '#chart_type' => 'column',
    'series_one' => $male_series,
    'series_two' => $female_series,
    'series_three' => $total_series,
    'x_axis' => $xaxis,
    'y_axis' => $yaxis,
    '#raw_options' => $chartjs_options,
    ],
    ],
    ];

  • πŸ‡ΊπŸ‡ΈUnited States andileco

    Yes, see attached image. You'll also want to be sure the plugin JS is present in your page (follow the README instructions or use the CDN).

  • πŸ‡¨πŸ‡¦Canada kevin.bruner

    Oh wow, absolutely a reading comprehension issue on my part. Yes, I see the numbers now! Marking as reviewed. I can't thank you enough for all your help.

  • Status changed to RTBC 3 months ago
  • πŸ‡¨πŸ‡¦Canada kevin.bruner

    You seem to be pretty good at distilling my user error into actionable results, so if you have the patience, I have another question.

    I have some pretty large values, so I was hoping to use the formatter function to save some space (e.g. 2.5M vs 25000000)

    https://chartjs-plugin-datalabels.netlify.app/guide/formatting.html#data...

    Is there a way that you know of to pass these into the raw_options array? Here's what I'm using for raw_options. The function is visible in the final canvas as a string which obviously means I'm doing this wrong!

    $chartjs_options = [
    'options' => [
    'maintainAspectRatio' => FALSE,
    'responsive' => TRUE,
    'plugins' => [
    'title' => [
    'display' => FALSE,
    ],
    'legend' => [
    'position' => 'top',
    'labels' => [
    'font' => [
    'size' => 16,
    'family' => 'Montserrat, Helvetica, sans-serif',
    ],
    ],
    ],
    'datalabels' => [
    'anchor' => 'end',
    'align' => 'top',
    'color' => '#000',
    'font' => [
    'size' => 14,
    ],
    'formatter' => 'function(value, context) {
    if (value >= 1000000) {
    return (value / 1000000).toFixed(1) + "M";
    } else if (value >= 1000) {
    return (value / 1000).toFixed(1) + "K";
    } else {
    return value;
    }
    }',
    ],
    ],
    ],
    ];

  • πŸ‡ΊπŸ‡ΈUnited States andileco

    PHP sanitizes those JS functions embedded in PHP. We built a work-around, which you can see implemented in the charts_api_example module:

    1) Create your custom module by creating my_module.info.yml
    2) Define a library: https://git.drupalcode.org/project/charts/-/blob/5.0.x/modules/charts_ap... (you may need to play with the weight in order for your JS to run at the right time)
    3) Create your JS file (note this particular line): https://git.drupalcode.org/project/charts/-/blob/5.0.x/modules/charts_ap...
    4) Attach your library to your chart(s): https://git.drupalcode.org/project/charts/-/blob/5.0.x/modules/charts_ap...

    More details here: https://www.drupal.org/project/charts/issues/3197574#comment-13999765 β†’

  • Pipeline finished with Skipped
    3 months ago
    #235148
  • Status changed to Fixed 3 months ago
  • πŸ‡ΊπŸ‡ΈUnited States andileco
  • πŸ‡¨πŸ‡¦Canada kevin.bruner

    I've been at the JS hook override thing for a while now and I'm getting nowhere. I'm able to invoke the hook and confirm that it's running for each chart through Drupal logging, but I can't log out the results of $chart_id (it returns null) every time. I can't log $element because it contains circular references.

    While I am grateful for your help, I must be frank: I don't think the examples are very self-explanatory.

  • Status changed to Needs work 3 months ago
  • πŸ‡ΊπŸ‡ΈUnited States andileco

    Opening this back up because I realized I need to apply it to the 5.1.x branch.

    I can definitely appreciate what you're saying. It's not an area that has received a lot of love, and I don't use that feature much myself (plus, I typically use Highcharts through Views).

    I'm happy to take a peek at your JS if you're willing to send it. And happy to patch the codebase or if you have specific recommendations.

  • Merge request !106Resolve #3463862 "51x " β†’ (Merged) created by andileco
  • Pipeline finished with Skipped
    2 months ago
    #247382
  • Status changed to Fixed 2 months ago
  • πŸ‡ΊπŸ‡ΈUnited States andileco

    Marking this fixed; however, @kevin.bruner, please open a new support request if needed.

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

Production build 0.71.5 2024