Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only show labels when hovering the associated elements #22

Closed
laurensvanpoucke opened this issue Jan 9, 2018 · 4 comments
Closed

Only show labels when hovering the associated elements #22

laurensvanpoucke opened this issue Jan 9, 2018 · 4 comments

Comments

@laurensvanpoucke
Copy link

Is it possible to hide the labels as default and only show them when hovering the bar?
Thanks in regards!

@simonbrunel
Copy link
Member

simonbrunel commented Jan 10, 2018

Edit: a built-in feature now allows to easily implement this use case (see this comment).

PREVIOUS SOLUTION (don't use it)

There is no built-in feature for that use case but you could implement a custom solution pretty easily using scriptable options (see this jsfiddle).

You first need to log hovered elements using the Chart.js onHover option:

new Chart('id', {
  // ...
  options: {
    // ...
    onHover: function(event, elements) {
      var chart = this;
      
      // Store hovered elements under a private property
      // named $_user_ to make sure it doesn't conflict.
      var expando = chart.$_user_ || (chart.$_user_ = {});

      // To prevent updating the chart for every mouse move,
      // let's first check that the hovered items have changed.
      if (!Chart.helpers.arrayEquals(expando.hovered, elements)) {
      	expando.hovered = elements;
        chart.update();
      }
    }
})

Then you need to script the display option of the data labels:

options: {
  // ...
  plugins: {
    datalabels: {
      display: function(context) {
          var expando = context.chart.$_user_ || {};
          var elements = expando.hovered || [];
          var datasetIndex = context.datasetIndex;
          var dataIndex = context.dataIndex

          for (var i = 0, ilen = elements.length; i < ilen; ++i) {
            var el = elements[i];
            if (el._datasetIndex === datasetIndex && el._index === dataIndex) {
              return true;
            }
          };

          return false;
        },
        // ...
    }
  }
}

I'm sure it can be more optimized but at least I hope it gives you some inputs on how to implement what you need. It also works with other type of charts and interactions (fiddle).

@simonbrunel simonbrunel changed the title Show on hover Only show labels when hovering the associated elements Jan 10, 2018
@laurensvanpoucke
Copy link
Author

@simonbrunel Thanks man. Works like a charm!

@simonbrunel
Copy link
Member

simonbrunel commented Jan 13, 2018

This plugin should provide a way to make that use case simpler, for example by exposing a new context property representing the element active state:

// blue/semi transparent label that become red/opaque when hovering an element (e.g. bar)

options: {
  plugins: {
    datalabels: {
      backgroundColor: function(context) {
        return context.active ? 'red' : 'blue';
      },
      opacity: function(context) {
        return context.active ? 1 : 0.5;
      }
    }
  }
}

We would only re-evaluate options of the active element(s) instead of updating the whole chart (chart.update()), so much faster than the solution in my previous comment.

I'm re-opening this ticket as a reminder.

@simonbrunel
Copy link
Member

Done in c9cab49 (see sample) and will be released in 0.3.0 :)

Your use case would be implemented as (fiddle):

options: {
  plugins: {
    datalabels: {
      display: function(context) {
        return context.active;
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants