2

I'm making a pie chart and I'm struggling to show the pie chart data value of each slices. As my application is written in React.js, I use react-chartjs-2.

I found this solution for chart.js and tried to implement, but it didn't work for react-chartjs-2.

How to display pie chart data values of each slice in chart.js

How can I add value to each slices? Any help is appreciated.

This is a current view of pie chart.

enter image description here

According to the advice, I implemented chart.piecelabel.js. It does not work yet..

My code

import {Pie} from 'react-chartjs-2';
import {pieceLabel} from 'chart.piecelabel.js';

export default class Categories extends React.Component{
constructor(props){
    super(props);
    this.state = {
        slideOpen : false,
        piData : piData
      }

this.handleClick = this.handleClick.bind(this);
this.update = this.update.bind(this);
this.doParentToggle = this.doParentToggle.bind(this);
}

doParentToggle(){


this.setState({
    piData : piData
  })
  console.log('-------')
  console.log('parentToggle' + piData )
  console.log('parentToggle' + piData2 )
  console.log('parentToggle' + piData3 )
  console.log('-------')
  this.update();
 }

handleClick(){
    this.setState({
        slideOpen : !this.state.slideOpen
    })
}

update() {
  var piData;
  this.setState({
    piData : piData
  })
  console.log('-------')
  console.log('parentToggle' + piData )
  console.log('parentToggle' + piData2 )
  console.log('parentToggle' + piData3 )
  console.log('-------')
  }    

render(){
 const CategoriesPanel = this.state.slideOpen? "slideOpen" : "";
 const { length } = this.props


  var totalData = piData + piData2 + piData3 + piData4 + piData5;

   let newpiData =  function() {
   return parseFloat((piData /  totalData ) * 100 ).toFixed(2) };

   let newpiData2 =  function() {
   return parseFloat((piData2 /  totalData ) * 100).toFixed(2) };

   let newpiData3 =  function() {
   return  parseFloat((piData3 /  totalData ) * 100).toFixed(2) };

   let newpiData4 =  function() {
   return parseFloat((piData4 /  totalData ) * 100).toFixed(2) };

   let newpiData5 =  function() {
   return parseFloat((piData5 /  totalData ) * 100).toFixed(2) };

  const data = {
  datasets: [{
    data: [ newpiData() , newpiData2(), newpiData3(), newpiData4(), newpiData5()],
    backgroundColor: [
    'orange',
    'blue',
    'red',
    'purple',
    'green'
    ],
    hoverBackgroundColor: [
    'orange',
    'blue',
    'red',
    'purple',
    'green'
    ],
    borderColor: [ 'orange',
    'blue',
    'red',
    'purple',
    'green'
    ]
  }],
  options : [{
    pieceLabel: { render: 'value' }
  }]};

   var pieOptions = {
   events: false,
   animation: {
   duration: 500,
   easing: "easeOutQuart",
   onComplete: function () {
   var ctx = this.chart.ctx;
   ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
   ctx.textAlign = 'center';
   ctx.textBaseline = 'bottom';

   this.data.datasets.forEach(function (dataset) {

    for (var i = 0; i < dataset.data.length; i++) {
      var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
          total = dataset._meta[Object.keys(dataset._meta)[0]].total,
          mid_radius = model.innerRadius + (model.outerRadius - model.innerRadius)/2,
          start_angle = model.startAngle,
          end_angle = model.endAngle,
          mid_angle = start_angle + (end_angle - start_angle)/2;

      var x = mid_radius * Math.cos(mid_angle);
      var y = mid_radius * Math.sin(mid_angle);

      ctx.fillStyle = '#fff';
      if (i == 3){ // Darker text color for lighter background
        ctx.fillStyle = '#444';
      }
      var percent = String(Math.round(dataset.data[i]/total*100)) + "%";
      ctx.fillText(dataset.data[i], model.x + x, model.y + y);
      // Display percent in another line, line break doesn't work for fillText
      ctx.fillText(percent, model.x + x, model.y + y + 15);
    }
   });               
   }
   }
 };
return(
<div>
<div id="chart" className={CategoriesPanel}>
<Pie style={{"fontSize" : "20px" }}data={data}/>
<div className="categoriesSlide" onClick={this.handleClick}>{this.state.slideOpen? <img src={Arrowup} alt="arrowup" className="arrowup" /> : <img src={Arrowdown} alt="arrowdown" className="arrowdown"/>}</div>
<button onClick={this.update} className="chartButton">Update Information</button></div>

 <div className="clear">
 <List parentToggle={this.doParentToggle} />
 <ListSecond parentToggle={this.doParentToggle} />
 <ListThird parentToggle={this.doParentToggle} />
 <ListFourth parentToggle={this.doParentToggle} />
 <ListFifth parentToggle={this.doParentToggle} />
 </div>
 </div>
    )
}
}
aaayumi
  • 1,224
  • 8
  • 27
  • 47

1 Answers1

7

You can use this ChartJS Plugin - Chart.PieceLabel.js

first, install it via npm :

npm install chart.piecelabel.js --save

then, import it in your component :

import 'chart.piecelabel.js';

and finally, add the following in your chart options :

pieceLabel: {
   render: 'value'
}

note: this is the minimum option needed to be set to display the value and you can find more options here.

ɢʀᴜɴᴛ
  • 32,025
  • 15
  • 116
  • 110
  • Hi, thank you so much for the suggestion. Actually I tried this before trying the above solution. Unfortunately it didn't work. Do you have a working demo? – aaayumi Sep 27 '17 at 12:26
  • Your import statement should be `import 'chart.piecelabel.js';` **not** `import {pieceLabel} from 'chart.piecelabel.js';` – ɢʀᴜɴᴛ Sep 27 '17 at 12:48
  • If I remove, I get this error.. `./src/categories.js Line 1650: 'pieceLabel' is not defined no-undef` – aaayumi Sep 27 '17 at 12:52
  • 1
    um.. that shouldn't occur. you've also added the option in wrong place. add `pieceLabel: { render: 'value' }` inside `pieOptions` – ɢʀᴜɴᴛ Sep 27 '17 at 12:58
  • I edited my code. I set ` pieceLabel` inside `options`. Even though it does not work yet, I don't get any error related `./src/categories.js Line 1650: 'pieceLabel' is not defined no-undef` anymore. I think I'm close to the answer.. – aaayumi Sep 27 '17 at 13:05
  • Have you ever tried it in your code? If you have a repository or something, could you kindly show me? thanks – aaayumi Sep 27 '17 at 13:06
  • 1
    Tried it long ago, no longer have that repo. Anyway, just noticed you've set `options` inside `dataset` which is incorrect, You need to add `options` separately. Try with this code - https://kopy.io/Waaxo – ɢʀᴜɴᴛ Sep 27 '17 at 13:22
  • 1
    Sorry I didn't understand what you mean before. Your code clarified it. Thank you so much for your kind help!!! – aaayumi Sep 27 '17 at 13:28
  • No problem. Glad to help!! – ɢʀᴜɴᴛ Sep 27 '17 at 13:29