简体   繁体   中英

ChartJS - Show percentage base on data on hover (AngularJS)

I have simple chartjs in angularjs, and I would show (20%) when hovering.

在此处输入图像描述

HTML

JS

angular.module('chartDemo', ['chart.js']).config(['ChartJsProvider', function (ChartJsProvider) { // Configure all charts ChartJsProvider.setOptions({ //animation: false, //responsive: false }); }]).controller('MainController', MainController);

function MainController($scope, $timeout) { var vm = this;

vm.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales"];
vm.data = [30, 50, 20];
vm.options = {
  legend: {
    display: true,
    position: 'bottom'
  },
  tooltips: {
    callbacks: {
      label: (ttItem,data) => (`${data.labels[ttItem.index]}: ${data.datasets[ttItem.datasetIndex].data[ttItem.index]}%`)
    }
  },
  cutoutPercentage: 60,
  tooltipEvents: [],
  tooltipCaretSize: 0,
  showTooltips: true,
  onAnimationComplete: function() {
    self.showTooltip(self.segments, true);
  }
}

}

MainController.$inject = ['$scope', '$timeout'];

Fiddle

https://jsfiddle.net/bheng/hegma4zn/2/

Right now, it showed % correct, when the data kind of match up to 100% like this [30, 50, 20]

Let's if the data look like this [360, 507, 207, 900] then code won't work anymore.

Any sugesstion for me to get that working?


Percentage

var percent = total/data.datasets[item.datasetIndex].data[item.index];

I just don't know how to grab the total value.

First get the total for the data we can use Javascript's reduce method

const total = vm.data.reduce((a, b) => a+b, 0);

Now update the label callback to calculate the percentages.

        callbacks: {
        label: (ttItem,data) => (`${data.labels[ttItem.index]}: ${Math.round(data.datasets[ttItem.datasetIndex].data[ttItem.index]/total*10000)/100}%`)
      }

Note, in the above code I've rounded the percentages to show 2 decimal points, you might want to change that.

Here's the entire code for MainController.

function MainController($scope, $timeout) {
  var vm = this;
  
  vm.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales", "Other Sales"];
  
  vm.data = [360, 507, 207, 900];
  
  const total = vm.data.reduce((a, b)=> a+b, 0);
  
  vm.options = {
    legend: {
      display: true,
      position: 'bottom'
    },
    tooltips: {
        callbacks: {
        label: (ttItem,data) => (`${data.labels[ttItem.index]}: ${Math.round(data.datasets[ttItem.datasetIndex].data[ttItem.index]/total*10000)/100}%`)
      }
    },
    cutoutPercentage: 60,
    tooltipEvents: [],
    tooltipCaretSize: 0,
    showTooltips: true,
    onAnimationComplete: function() {
      self.showTooltip(self.segments, true);
    }
  }
  
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM