The importance of displaying doughnut chart tooltips in Angular 5 console

Is there a way to consistently display tooltips for a doughnut chart? This code snippet might help:

Chart.pluginService.register({
  beforeRender: function(chart) {
  if (chart.config.options.showAllTooltips) {
    // create an array of tooltips
    // we can't use the chart tooltip because there is only one tooltip per chart
    chart.pluginTooltips = [];
    chart.config.data.datasets.forEach(function(dataset, i) {
    chart.getDatasetMeta(i).data.forEach(function(sector, j) {
      chart.pluginTooltips.push(new Chart.Tooltip({
        _chart: chart.chart,
        _chartInstance: chart,
        _data: chart.data,
        _options: chart.options.tooltips,
        _active: [sector]
      }, chart));
    });
  });

  // turn off normal tooltips
  chart.options.tooltips.enabled = false;
}
},
afterDraw: function(chart, easing) {
if (chart.config.options.showAllTooltips) {
  // we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
  if (!chart.allTooltipsOnce) {
    if (easing !== 1)
      return;
    chart.allTooltipsOnce = true;
  }

  // turn on tooltips
  chart.options.tooltips.enabled = true;
  Chart.helpers.each(chart.pluginTooltips, function(tooltip) {
    tooltip.initialize();
    tooltip.update();
    // we don't actually need this since we are not animating tooltips
    tooltip.pivot();
    tooltip.transition(easing).draw();
  });
  chart.options.tooltips.enabled = false;
}
}
});

https://jsfiddle.net/suhaibjanjua/qz3es03j/

I'm currently using Angular 5 and I'm unsure how to incorporate the above code into my component.ts file. Additionally, I would like to add a small black border to each tooltip. I know how to achieve this in CSS, but not sure how to implement it in the chart tooltips.

This is what my current component.ts looks like:

doughnutChartData: any[] = [0,18,26,16, 40];
doughnutChartLabels: any[] = ['NA', 'NE', 'NO', 'C', 'S'];
doughnutChartOptions: any = {
  responsive: true,
  maintainAspectRatio: false,
  cutoutPercentage: 80,
  tooltips: {
    enabled: true,
    backgroundColor: 'white',
    titleFontColor: 'black',
    bodyFontColor: 'black',
    xPadding: 20,
    yPadding: 20,
    displayColors: false,
    callbacks: {
            label: function(tooltipItem, data) {
                var allData = data.datasets[tooltipItem.datasetIndex].data;
                var tooltipLabel = data.labels[tooltipItem.index];
                var tooltipData = allData[tooltipItem.index];
                var total = 0;
                for (var i in allData) {
                    total += allData[i];
                }
                var tooltipPercentage = Math.round((tooltipData / total) * 100);
                return tooltipLabel + ': ' + tooltipPercentage + '%';
            }
        }
  }
};
doughnutChartColors: any[] = [{
  borderWidth: 3,
  backgroundColor: ['#ffffff', '#e827d3', 'black', 'rgb(104, 104, 104)', 'gray']
}];

Here's the corresponding HTML:

<mat-card class="charts-npls first-chart">
  <canvas baseChart
                [data]="doughnutChartData"
                [labels]="doughnutChartLabels"
                [options]="doughnutChartOptions"
                [colors]="doughnutChartColors"
                [legend]="false"
                chartType="doughnut">
   </canvas>
</mat-card>

Answer №1

After researching, I successfully located a solution by utilizing the following example: https://embed.plnkr.co/opFmFg34AyqVw?show=preview

declare var Chart: any;

ngOnInit() : void{
Chart.pluginService.register({
    beforeDraw: (chart) => {
    if (chart.config.options.showAllTooltips) {
      // create an array of tooltips
      // we can't use the chart tooltip because there is only one tooltip per chart
      chart.pluginTooltips = [];
      chart.config.data.datasets.forEach(function(dataset, i) {
        chart.getDatasetMeta(i).data.forEach(function(sector, j) {
          chart.pluginTooltips.push(new Chart.Tooltip({
            _chart: chart.chart,
            _chartInstance: chart,
            _data: chart.data,
            _options: chart.options.tooltips,
            _active: [sector]
          }, chart));
        });
      });

      // turn off normal tooltips
      chart.options.tooltips.enabled = false;
    }
  },
  afterDraw: (chart, easing) => {
    if (chart.config.options.showAllTooltips) {
      // we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
      if (!chart.allTooltipsOnce) {
        if (easing !== 1)
          return;
        chart.allTooltipsOnce = true;
      }

      // turn on tooltips
      chart.options.tooltips.enabled = true;
      Chart.helpers.each(chart.pluginTooltips, function(tooltip) {
        tooltip.initialize();
        tooltip.update();
        // we don't actually need this since we are not animating tooltips
        tooltip.pivot();
        tooltip.transition(easing).draw();
      });
      chart.options.tooltips.enabled = false;
    }
  }
});
}

I have also included:

showAllTooltips: true,

in the doughnutChartOptions

To further enhance your tooltip with a border, simply insert:

borderColor: 'rgba(0,0,0,1)',
borderWidth: 1,
caretSize: 0,

Setting caretSize to 0 will eliminate the caret, providing a clean rectangle appearance for your tooltips.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Button-operated lightbox image slider

I am currently developing a website on WAMP where users can store images and view them in a lightbox effect. I have successfully implemented the lightbox effect, but I am facing challenges with moving between images within the lightbox. <html> <? ...

The mobile navigation in HTML has a slight issue with the ::after pseudo-element, specifically within the

As I prepare to launch my website, I have made adjustments to the mobile layout by moving the navigation links to a navigation drawer. The template I am using included JavaScript scripts to handle this navigation change. However, I encountered an issue whe ...

When using Laravel with jQuery Ajax, the search for the file address is unsuccessful

Learning Laravel has been a challenging journey for me. I've encountered numerous problems that have made it feel like more of a hindrance than a helpful tool. But the real story lies elsewhere. Working with Laravel 4 and jQuery 2, I attempted to fet ...

Receive characteristics in component specification

Is there a way to pass the native attributes of an img element to a custom image component without explicitly defining each one, like alt, and have them all be applied to the img tag? Here is an example of what I mean: @Component({ selector: 'image ...

Exploring the world of JSON and JavaScript data structures

Can someone provide some clarification please? var a = '{"item":"earth", "color":"blue", "weight":920}'; Is the data type of a a string or an array ? var b = JSON.parse(a); What is the data type of b - an object or an array ? ...

Attempting to send a Promise to another function for it to return, encountering an error of "Unhandled promise rejection"

My goal is to develop a versatile database update function that can be utilized for creating more customized update functions. Within the module database.js, the following code is present: const {Pool,Client}=require('pg'); const pool=new Pool( ...

The fixed position setting does not anchor the elements to the bottom of a container

When applying the following styles: #fullpage-menu > .gradient { position: fixed; bottom: 0; left: 0; width: 100%; height: 0.3rem; } To the element with ID #fullpage-menu, which is styled as follows: #fullpage-menu { height: 100 ...

Can the keydown event have an impact on setInterval functionality?

I created a basic snake game using JavaScript and attempted to incorporate a new feature where var trail = []; var tail = 5; var normal_speed = 1000 / 10 var speed = 1000 / 10; var game_status = 0; var my_game; button.addEventListener("click", function ...

Concentrate on all elements within the form

I am in the process of developing a form with multiple input fields, one of which is shown below. I am interested in triggering an event using jQuery's focusout function. The form goes by the name: form_test <form id="form_test"> <input ...

Definition file for Typescript Angular 1.5 component

Encountering a problem with typescript and angular 1.5 - when building, an error pops up saying error TS2339: Property 'component' does not exist on type 'IModule'.. Could it be that I overlooked a definition file containing this proper ...

Exploring the $scope variable in AngularJS using JavaScript

How can I assign values to $scope.dragged and $scope.dropped in a JavaScript function? function drag(e){ e.dataTransfer.setData("text/html", e.target.id); console.log(e.target.id); $scope.dragged = e.target.className; } function drop(e){ ...

Is there a way to run /_next/static/xxx.js using a script tag?

I have customized my next.config file (webpack) to generate a static JavaScript file (.next/static/loader.js). The original loader.js is an Immediately Invoked Function Expression (IIFE): (function stickerLoader(){ alert('Hello'); // ... so ...

Unexpected database query result in Node.js

In my newuser.js file for a node.js environment with a mongodb database managed through mongoose, I have the following code: //newuser.js //This code is responsible for creating new user documents in the database and requires a GET parameter along with a ...

Tips for creating a vertical drawer using jQuery and CSS

Hello, I am currently working on developing a drawer component using Ember.js. If you want to view the progress so far, feel free to check out this jsbin http://jsbin.com/wulija/8/edit My goal is to have the drawer look like the following initially: +--- ...

The change event for the select element is malfunctioning

Currently, I am deep diving into Nodejs with the second edition of the node cookbook. This book has caught my attention because it explains concepts using practical sample code, making it easier to grasp. The example code I am working on is related to Br ...

What's the best way to organize a list while implementing List Rendering in VueJS?

Currently, I am working on List Rendering in Vue2. The list is rendering correctly, but it appears ordered based on the data arrangement in the array. For better organization, I need to sort each item alphabetically by title. However, I am facing difficult ...

The battle between Hover, Focus, and Blur modes intensifies

My goal is to implement 4 different effects on an element: When hovering over the element. When moving away from the element. When focusing on the element. When blurred. However, I'm encountering a conflict where when I focus on the element, the ...

How to Stop Browser Tooltip from Displaying HTML Tags within "innerHtml" in Angular 6

In my Angular application, a template is using the following code snippet: ... <span [innerHtml]="textVar"></span> ... The textVar variable is created to allow for special styling on certain characters or strings. It's formatted using th ...

Ways to retrieve the content from a textfield

Is there a way to retrieve text from a textfield in material UI without using the onChange method? It just seems odd that I would need to constantly track the value with onChange in order to use it for any other purpose. I decided to search for solutions ...

Getting the ng-model value from a Directive's template and passing it to a different HTML file

When working with my name directive, I am unable to retrieve the value of ng-model from the template-url. team-two.html <form name="userForm" novalidate> <div name-directive></div> </form> <pre>{{userForm.firstname}}< ...