How can I display both numbers and percentages on a pie chart using ChartJS datalabels?

I am currently using ChartJS in my React application to display data on a pie chart. My requirement is to display both the number and percentage values on each slice of the chart (e.g. 5(6.7%)). However, with the existing code, I am only able to show the percentage value. Can anyone provide guidance on how I can achieve this dual display? Thank you.

const data = {
    labels: ['America', 'China', 'Dubai', 'India'],
    datasets: [
      {
        label: 'Work Orders',
        data: [10, 50, 5, 2],
        backgroundColor: [
          '#00CF9B',
          '#E55B5E',
          '#FFD366',
          '#5A9ED4',
        ],
        borderWidth: 0,
      },
    ],
  };

  const options = {
    plugins: {
      legend: {
        position: 'right'
      },
      datalabels: {
        color: 'black',
        font: {
          weight: 'bold'
        },
        formatter: (value, ctx) => {
          let sum = 0;
          let dataArr = ctx.chart.data.datasets[0].data;
          dataArr.map(data => {
            sum += data;
          });
          let percentage = (value * 100 / sum).toFixed(2) + "%";
          return `${value}(${percentage})`;
        },
      }
    }
  }

<Pie data={data} options={options} />

Answer №1

I believe it would be beneficial to include the value as part of the callback's returned value.

Additionally, by utilizing a doughnut/pie controller, you can access the dataset meta data where the total value is already available, thus eliminating the need to sum all values each time.

const data = {
    labels: ['USA', 'China', 'Dubai', 'India'],
    datasets: [
      {
        label: 'Tasks',
        data: [10, 50, 5, 2],
        backgroundColor: [
          '#00CF9B',
          '#E55B5E',
          '#FFD366',
          '#5A9ED4',
        ],
        borderWidth: 0,
      },
    ],
  };

  const options = {
    plugins: {
      legend: {
        position: 'right'
      },
      datalabels: {
        display: 'auto',
        color: 'black',
        font: {
          weight: 'bold'
        },
        formatter: (value, ctx) => {
          const total = ctx.chart.getDatasetMeta(0).total;
          let percentage = (value * 100 / total).toFixed(2) + "%";
          return percentage + '(' + value + ')';
        },
      }
    }
  }

const ctx = document.getElementById('myChart').getContext('2d');
new Chart(ctx, {
  type: 'pie',
  plugins: [ChartDataLabels],
  data,
  options
});
.myChartDiv {
  max-width: 600px;
  max-height: 400px;
}
<script src="https://npmcdn.com/chart.js@latest/dist/chart.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5a39323b282e3029772a362f3d3334773e3b2e3b363b383f36291a687468746a">[email protected]</a>/dist/chartjs-plugin-datalabels.min.js"></script>
<div class="myChartDiv">
  <canvas id="myChart" width="600" height="400"></canvas>
</div>

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

How can you spot the conclusion of different lines that refuse to remain in place?

Currently, I am facing a jquery issue that has left me stumped. The website I am working on is structured as follows: <div class="Header"></div> <div class="main"><?php include('content.html'); ?></div> <div clas ...

Using placeholders with inputs in an Angular2 table generated by ngFor

I have an array public example = [['hallo', 'fruit', 'rose'], ['apple','book']] Currently, I am working on creating a table of inputs. The values in this table depend on the specific part that I am usin ...

Guide to retriecing a state in Next.js 14

Check out my code below: "useState" // firebase.js import firebase from "firebase/app"; import "firebase/auth"; // Import the authentication module export default async function handler(req, res) { if (req.method !== " ...

Retrieve the identification of a randomly selected div element using an array

I am attempting to implement a right-click function using only JavaScript. My initial plan was to utilize a mouseover function, as shown below: mysteryDiv.onmouseover=function(){ if (rightMBclicked === true) { console.log(mysteryDiv.id); } ...

The component fails to display during my testing efforts

I am encountering a peculiar issue. In my setup, I am using jasmine 2.0, react 0.13.3, react-router 0.13.3, and various other packages. The problem lies within my test suite where it fails to findRenderedDOMComponentWithTag(). Let me provide a specific exa ...

The glitch in jQuery's animate function callback

In my code to animate the sliding out of a div, I encountered an issue: var current = $('.s_text:visible'); current.animate({ right: 1014, opacity:0, },{queue: false, duration:2000}, function() { current.hide(); }); Strangely, the callbac ...

Switching from cURL to Ajax resulted in receiving a 400 Error code

My goal is to save specific URLs into a jsonbox, but I keep encountering Error 400. The curl command provided in the documentation is as follows: curl -X POST 'https://jsonbox.io/demobox_6d9e326c183fde7b' \ -H 'content-type: applic ...

Vue alert: Issue encountered in watcher 'childItems' callback - 'TypeError: Unable to access property 'tag' as it is undefined'

I am currently in the process of developing the Store page for a web application. I am utilizing Axios to retrieve product data and display it in a Vue template. While the backend functionality is working correctly and the frontend is rendering successfull ...

Ordering Operations in Redux

Right now, I'm facing a situation where I need Redux Actions to run one after the other in sequence. I've come across different middlewares like redux-promise that work well if you know the successive actions when triggering the root action. My ...

How big should the placeholder image be for the image area?

How can I create a loading image to replace a .gif while it loads? I need a placeholder image of about 325x325 (same size as the gif) to keep content in place. I've attempted using background: url() without success and haven't explored JS/jQuery ...

Using yargs to pass parameters/arguments to a Node script through an npm script

Is it feasible to retrieve a key from yargs when utilizing as an npm script argument? A user inputs in the OSX terminal: npm run scaffold --name=blah which triggers in package.json: "scaffold" : "node ./scaffold/index.js -- " This leads to const yar ...

When utilizing VueJs, it's not possible to retrieve a data property from within a function

I am encountering a challenge when trying to access the data property within the function. Despite my efforts, I seem to be missing something crucial and unable to pinpoint what it is. Here is my class: export default { name: "Contact", component ...

The correct way to extract a jwt token from headers and integrate it into an express application

After successfully implementing both the frontend and backend in express.js with authentication and authorization using JWT, I have confirmed that the JWT token is being properly set upon login. You can see the auth-token key in the image below: https://i ...

Screening for items that meet specific criteria

Currently, the functions are functioning properly by filtering inventory based on barcode and manufacturer. However, I am looking to enhance it to behave like default angularjs filtering. Specifically, I want it so that if I select manufacturer - LG and ba ...

Why does the name not appear when I first click the button, only 'emit'?

I am attempting to utilize eventemiter in order to send a name when clicking a button, but it doesn't seem to be working as expected. The issue I am facing is that the name is not displayed the first time I click the button, however, if I click it aga ...

Update a separate page seamlessly without the need to refresh

I'm looking for a way to automatically update my webpage without the need to refresh it. Can anyone suggest and explain the best solution for this issue? Thank you in advance add.php file This PHP file simply prompts the user for their name. <for ...

Using Typescript to typecast in D3.js

Utilizing the D3 graph example available here. I've defined my data object as shown below: interface ID3Data { age: string, population: number } const data: ID3Data[] = [ { age: "<5", population: 2704659 }, { age: "5-13", population: 4499 ...

Anticipating the outcome of a function in asynchronous JavaScript

After taking a break from web development for a couple of years, I recently dove back into it. While I dabbled in AngularJS before, I have now shifted my focus to Angular2. My current challenge revolves around handling asynchronous JavaScript. Despite enc ...

Exploring MapQuest API: Unraveling the process of dissecting MapQuest

I am currently exploring MapQuest navigation and utilizing JavaScript code to retrieve the data. Although I am able to extract JSON content in my application, I am unsure of how to utilize this data for navigation. I have started a new project and execute ...

Executing the command `npm run jshint` yields the error message `script not found: jshint`

Currently, I'm attempting to run jshint on a few javascript files. However, I am encountering an issue where the local npm install of jshint is not functioning as expected. Upon checking, the package is indeed present: $ npm list --depth=0 <a hre ...