Why canvas content, line chart chart.js, doesn't show on bootstrap popover body?

299 views Asked by At

I'm trying to create bootstrap popover, whose content is a line chart chart.js, on bootstrap button. However, when I click on button, popover shows all the content I provided but not line chart. Note that, I set html true so that popover can accept HTML content.

I have tried recommedations from chart.js (accessibility part), bootstrap popover. But I didn't still work. I tested by adding text content in popover and it worked nut not work for line chart. Here is my code. Thanks everybody for spensing your time reading my issue.

<!DOCTYPE html>
<html lang="en">

<head>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-aFq/bzH65dt+w6FI2ooMVUpc+21e0SRygnTpmBvdBgSdnuTN7QbdgL+OapgHtvPp" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-qKXV1j0HvMUeCBQ+QVp7JcfGl760yU08IQ+GpUo5hlbpg51QRiuqHAJz8+BrxE/N" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js" integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDcfM9Qg==" crossorigin="anonymous"></script>
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.0.1/chart.min.js" integrity="sha512-tQYZBKe34uzoeOjY9jr3MX7R/mo7n25vnqbnrkskGr4D6YOoPYSpyafUAzQVjV6xAozAqUFIEFsCO4z8mnVBXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous"></script> -->
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <!-- <script src='https://kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js'></script> -->

</head>

<body>
    <div class="container py-3">
        <!-- Create popover trigger button -->
        <button type="button" class="btn btn-primary" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-html="true" title="Chart">Open Chart</button>
    </div>
    <script>
        // Chart data
        // import Chart from 'chart.js/auto';
        var chartData = {
            labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
            datasets: [{
                label: 'My Dataset',
                data: [65, 59, 80, 81, 56, 55, 40],
                fill: false,
                borderColor: 'rgb(75, 192, 192)',
                tension: 0.1
            }]
        };

        // Chart options
        var chartOptions = {
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        };

        // Create chart canvas
        var chartCanvas = document.createElement('canvas');
        chartCanvas.id = 'myChart';
        chartCanvas.role = "img";
        chartCanvas.setAttribute("aria-label","Hello world");
        chartCanvas.style.width = '400px';
        chartCanvas.style.height = '300px';
        console.log(chartCanvas.outerHTML);
        // Render chart
        var myChart = new Chart(chartCanvas, {
            type: 'line',
            data: chartData,
            options: chartOptions
        });
        console.log(chartCanvas.outerHTML)
        // Create popover content
        var content = '<div class="chart-container">' + chartCanvas.outerHTML + '<h1>Hello</h1>' + '</div>';
        

        // Initialize popover
        var popover = new bootstrap.Popover(document.querySelector('[data-bs-toggle="popover"]'), {
            container: 'body',
            content: content,
            html: true
        });
    </script>
      
</body>
1

There are 1 answers

1
Julianna On

So, I got it working.

I forked your CodePen, so you can see the functioning solution here.

Your canvas element needs to already be in the DOM before you draw the chart. So, I changed the code so that only the canvas element is inserted in the popover. Then, I added an event listener for the bootstrap event "inserted.bs.popover", which is called after the popover is inserted into the DOM. Here's the documentation for Bootstrap popover events.

Adding that event listener looks like this code:

$("[data-bs-toggle='popover']").on("inserted.bs.popover", () => {
  // Invoke Chart.js to draw the chart
  new Chart("myCanvas", chartjsConfig);
});

I hope that helps with your question.

Accessibility Aside

Since you are looking to incorporate accessibility into your charts, I also added some extra accessibility code to that codepen. I work on an open source library, Chart2Music, and I added its chartjs plugin to your code. You can play with it yourself by:

  1. Press the TAB key until you get to the "Open Chart" button.
  2. Press SPACEBAR to open the button (this was done by Bootstrap)
  3. Press TAB again. You'll focus on the chart in the popover.
  4. Press the left/right arrow keys. You'll move around the chart, and hear sounds ("sonification") to represent the values.

I added comments before the lines that are specific to Chart2Music, so hopefully it's not confusing.

Let me know if you have any questions!