Chartjs-Chartjs Custom Legend for Doughnut Chart Having Labelled Lines Sticking Out of Each Section

0👍

I found out a solution by taking multiple canvases and drawing the stuck out lines and texts above and below it using JavaScript’s 2d contexts. I brought the lines to touch the chartjs’s doughnut chart by giving negative margins. Responsiveness is still an issue but at least that’s one way of doing it. I am posting the code here. Screen size might dislocate the lines. You might wanna see the result on with full screen on your laptop.

<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            
            .chart-wrapper
            {
                width: 24rem;
                height: 24rem;
            }
            .debt-savings
            {
                margin-right: -15rem;
            }
            .needs
            {
                margin-left: -5.5rem;
            }
            .wants
            {
                margin-top: -6.8rem;
            }
        </style>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    </head>
    <body>
        <div class="row">
            <br><br><br><br><br><br><br><br>
        </div>
        <div class="row d-flex justify-content-center">
            <div class="col-4 chart-wrapper debt-savings">
                <canvas id="debt-savings"></canvas>
            </div>
            <div class="col-4 d-flex justify-content-center">
                <div class="chart-wrapper">
                    <canvas    id="budget-chart"></canvas>
                </div>
                
            </div>
            <div class="col-4 chart-wrapper needs">
                <canvas id="needs"></canvas>
            </div>
            
        </div>
        <div  class="row d-flex justify-content-end">
            <div class="col-6 chart-wrapper wants">
                <canvas id="wants"></canvas>
            </div>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script type="text/javascript">
       
            // Data for doughnut chart
        const data = {
            labels: [
              'Debt & Saving',
              'Needs',
              'Wants'
            ],
            datasets: [{
              label: 'My First Dataset',
              data: [20//debtAndSavingsPercet
                  , 30//needsPercet
                  , 50//wantsPercet
              ],
              backgroundColor: [
                'rgb(255, 99, 132)',
                'rgb(54, 162, 235)',
                'rgb(255, 205, 86)'
              ],
              hoverOffset: 4
            }]
          };
        var ctx = document.getElementById("budget-chart").getContext("2d");
        var myDoughnutChart = new Chart(ctx, {
            type: 'doughnut',
            data: data,
            options: {
                legend:{
                    display:false,
                },
                responsive:true,
                maintainAspectRatio:true,
            }
        });
        var debtAndSavingCanvas = document.getElementById("debt-savings");
        debtAndSavingCanvas.width  = 300;
        debtAndSavingCanvas.height = 300;
        var debtAndSavingCtx = debtAndSavingCanvas.getContext("2d");        
        debtAndSavingCtx.font = "normal normal 500 40px Georgia";
        debtAndSavingCtx.fillStyle = "green";
        debtAndSavingCtx.fillText("20%", 0, 100);
        debtAndSavingCtx.font = "16px Georgia";
        debtAndSavingCtx.fillText("Debt &", 100, 70);
        debtAndSavingCtx.fillText("savings", 100, 100);
        debtAndSavingCtx.font = "20px Georgia";
        debtAndSavingCtx.fillStyle = "grey";
        debtAndSavingCtx.fillText("Emergency savings,", 0, 134);
        debtAndSavingCtx.fillText("student loans, credit", 0, 154);
        debtAndSavingCtx.fillText("cards, etc.", 0, 174);
        debtAndSavingCtx.beginPath();
        debtAndSavingCtx.moveTo(300, 150);
        debtAndSavingCtx.lineTo(230, 110);
        debtAndSavingCtx.lineTo(0, 110);
        debtAndSavingCtx.stroke();
        //
        // Needs context 
        //
         var needsCanvas = document.getElementById("needs");
        needsCanvas.width  = 300;
        needsCanvas.height = 300;
        var needsCtx = needsCanvas.getContext("2d");        
        needsCtx.font = "normal normal 500 40px Georgia";
        needsCtx.fillStyle = "purple";
        needsCtx.fillText("53%", 30, 95);
        needsCtx.font = "20px Georgia";
        needsCtx.fillText("needs", 110, 95);
        needsCtx.font = "20px Georgia";
        needsCtx.fillStyle = "grey";
        needsCtx.fillText("Mortgage/rent, utilities,", 50, 134);
        needsCtx.fillText("phone/internet, etc", 50, 154);
        //draw the line
        needsCtx.beginPath();
        needsCtx.moveTo(0, 130);
        needsCtx.lineTo(30, 110);
        needsCtx.lineTo(200, 110);
        needsCtx.stroke();
        
        //
        // Wants context 
        //
         var wantsCanvas = document.getElementById("wants");
        wantsCanvas.width  = 300;
        wantsCanvas.height = 300;
        var wantsCanvas = wantsCanvas.getContext("2d");        
        wantsCanvas.font = "normal normal 500 40px Georgia";
        wantsCanvas.fillStyle = "purple";
        wantsCanvas.fillText("25%", 50, 95);
        wantsCanvas.font = "20px Georgia";
        wantsCanvas.fillText("wants", 130, 95);
        wantsCanvas.font = "20px Georgia";
        wantsCanvas.fillStyle = "grey";
        wantsCanvas.fillText("Mortgage/rent, utilities,", 50, 134);
        wantsCanvas.fillText("phone/internet, etc", 50, 154);
        //draw the line
        wantsCanvas.beginPath();
        wantsCanvas.moveTo(0, 80);
        wantsCanvas.lineTo(30, 110);
        wantsCanvas.lineTo(200, 110);
        wantsCanvas.stroke();
    </script>
    </body>
</html>

Leave a comment