Search code examples
javascripthtmljquerychart.jsdonut-chart

I want to Display Data instead of percentages when cursor hovers over Doughnut Chart in JS


const data = {
  labels: ['xyz', 'abc'],
  datasets: [{
   label: 'Weekly Sales',
    data: [12, 20],     
    backgroundColor: [
      'rgb(254, 214, 10)',
      'rgb(255, 90, 48)'
    ],
    borderColor: [
      "#ffffff",         
    ],
    borderWidth: 1
  }]
};

var sum = 0;
var i;
for (i = 0; i < data.datasets[0].data.length; ++i) {
    sum += data.datasets[0].data[i];
}
console.log("sume", sum);
 for (i = 0; i < data.datasets[0].data.length; ++i) {
    data.datasets[0].data[i] = Math.round((data.datasets[0].data[i] / sum) * 100); 
}  

// config 
const config = {
  type: 'doughnut',
  data,
    options: {
    plugins: {
     datalabels: {
                        formatter: (value, ctx) => {
                let datasets = ctx.chart.data.datasets;
                
                      if (datasets.indexOf(ctx.dataset) === datasets.length - 1) {
                       //var sum = datasets[0].data.reduce((a, b) => a + b, 0);
                       var percentage = Math.round((value / sum) * 100) +"%";
                      return percentage;
                    
                     } else {
                       return percentage;
                     
     }


      },
      color: '#fff',
            }
     }
    }        
  }; 


// render init block
const myChart = new Chart(
  document.getElementById('myChart'),
  config
);
$(document).ready(function () {
$("#count1").text( data.datasets[0].data[0]+"%" );
$("#count2").text( data.datasets[0].data[1]+"%" )
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<!--  <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>  -->
 <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.min.js"></script>

<canvas id="myChart"></canvas>

<div class="block-text">
             <div class="flex-chart"> <div class="box-file"></div><p class="spacing">abc</p>
             <p id = "count1">20%</p></div>

             <div class="flex-chart"> <div class="box-url"></div><p class="spacing">xyz</p> 
             <p id = "count2">30%</p>

         </div>
         </div>

I just want to display data: [12, 20], this data instead of percentages when cursor hovers over Doughnut Chart without Changing other code.** **When cursor hovers over Doughnut Chart, it shows the percentage of the Data value. Simply, I want to display Data values when cursor hover overs Doughnut Chart without changes in this Code.


Solution

  • In the following line, you are overwriting the data items:

    data.datasets[0].data[i] = Math.round((data.datasets[0].data[i] / sum) * 100); 
    

    It would be better to create a new array here, legendData, which you can then use later on. So:

    const legendData = [];
    for (i = 0; i < data.datasets[0].data.length; ++i) {
        legendData[i] = Math.round((data.datasets[0].data[i] / sum) * 100); 
    }  
    

    And at the bottom of the JavaScript code you need to make the following changes:

    $("#count1").text( legendData[0]+"%" );
    $("#count2").text( legendData[1]+"%" )
    

    I am not sure if your formatter function is working properly, but that does not affect this solution.

    const data = {
      labels: ['xyz', 'abc'],
      datasets: [{
        label: 'Weekly Sales',
        data: [12, 20],
        backgroundColor: [
          'rgb(254, 214, 10)',
          'rgb(255, 90, 48)'
        ],
        borderColor: [
          "#ffffff",
        ],
        borderWidth: 1
      }]
    };
    
    var sum = 0;
    var i;
    for (i = 0; i < data.datasets[0].data.length; ++i) {
      sum += data.datasets[0].data[i];
    }
    
    const legendData = [];
    
    for (i = 0; i < data.datasets[0].data.length; ++i) {
      legendData[i] = Math.round((data.datasets[0].data[i] / sum) * 100);
    }
    
    const config = {
      type: 'doughnut',
      data,
      options: {
        plugins: {
          datalabels: {
            formatter: (value, ctx) => {
              let datasets = ctx.chart.data.datasets;
              if (datasets.indexOf(ctx.dataset) === datasets.length - 1) {
                //var sum = datasets[0].data.reduce((a, b) => a + b, 0);
                var percentage = Math.round((value / sum) * 100) + "%";
                return percentage;
              } else {
                return percentage;
              }
            },
            color: '#fff',
          }
        }
      }
    };
    
    // render init block
    const myChart = new Chart(
      document.getElementById('myChart'),
      config
    );
    
    $(document).ready(function() {
      $("#count1").text(legendData[0] + "%");
      $("#count2").text(legendData[1] + "%")
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
    <!--  <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>  -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.min.js"></script>
    
    <canvas id="myChart"></canvas>
    <div class="block-text">
      <div class="flex-chart">
        <div class="box-file"></div>
        <p class="spacing">abc</p>
        <p id="count1">20%</p>
      </div>
      <div class="flex-chart">
        <div class="box-url"></div>
        <p class="spacing">xyz</p>
        <p id="count2">30%</p>
      </div>
    </div>