How to fix overlapping Google Chart legend
Asked Answered
I

1

2

This has been something I've been working on for hours now and I can't seem to find a solution that works. I have a page (ASP.NET Core) that has bootstrap tabs on it. Each tab displays a different chart. I've read various answers and tried so many different things from this and other sites but I'm sure what I'm doing wrong.

This is a proof of concept page I'm making and from what I understand I need to stall the loading of the chart until the nav-tab is selected. That is what I am unsure of how to do.

My View:

<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

@Html.Partial("~/Views/Shared/Chart_ByMonth.cshtml")
@Html.Partial("~/Views/Shared/Chart_ByMonthAndQuarter.cshtml")
@Html.Partial("~/Views/Shared/Chart_ByLeaseAdmin.cshtml")
@Html.Partial("~/Views/Shared/Chart_Fourth.cshtml")

<script type="text/javascript">
    // Load the Visualization API and the corechart package.
    google.charts.load('current', {'packages':['corechart']});

    // Set a callback to run when the Google Visualization API is loaded.
    google.charts.setOnLoadCallback(drawMonthChart);
    google.charts.setOnLoadCallback(drawMonthAndQuarterChart);
    google.charts.setOnLoadCallback(drawLeaseAdminChart);
    google.charts.setOnLoadCallback(drawFourthChart);
</script>

<body>
<ul class="nav nav-tabs" id="tabs">
        <li class="active" id="tab_1"><a data-toggle="tab" href="#home">By Month</a></li>
        <li id="tab_2"><a data-toggle="tab" href="#menu1">By Month & Quarter</a></li>
        <li id="tab_3"><a data-toggle="tab" href="#menu2">By Lease Admin</a></li>
        <li id="tab_4"><a data-toggle="tab" href="#menu3">Fourth Chart</a></li>
    </ul>
    <div class="tab-content">
        <div id="home" class="tab-pane fade in active">
            <h3>By Month</h3>
            <select>
                <option selected>January</option>
                <option>February</option>
                <option>March</option>
                <option>April</option>
                <option>May</option>
                <option>June</option>
                <option>July</option>
                <option>August</option>
                <option>September</option>
                <option>October</option>
                <option>November</option>
                <option>December</option>
            </select>
            <select>
                <option>2016</option>
                <option>2017</option>
            </select>
            <button type="submit" class="btn btn-success">Submit</button>
            <div id="chart_month_div" style="padding-top: 20px;"></div>
        </div>
.....
</div>
</body>

The partial view for that chart is just hard-coded data, again a proof of concept page:

<script type="text/javascript">


function drawMonthAndQuarterChart() {

    // Create the data table.
    var data = google.visualization.arrayToDataTable([
        ['Type', 'Cash', 'Credit', { role: 'annotation' }],
        ['January', 10, 24, ''],
        ['February', 16, 22, ''],
        ['March', 28, 19, '']
    ]);

    // Set chart options
    var options = {
        width: 1200,
        height: 400,
        legend: { position: 'top', maxLines: 3 },
        bar: { groupWidth: '75%' },
        isStacked: true,

        hAxis: {
            minValue: 0,
            title: 'Approvals for the month & quarter'
        }

    };


    // Instantiate and draw our chart, passing in some options.
    var chartMonthandquarter = new google.visualization.BarChart(document.getElementById('chart_monthandquarter_div'));
    chartMonthandquarter.draw(data, options);
}

The charts all load fine when tabs are selected. The legend is overlapped with itself on all but the initially shown chart. I've tried defaulting the chart divs to be hidden and having an onclick event for each tab that overrides the styling, I've tried doing events where a tab is active, nothing seems to work and I've just been banging my head against the wall.

I suspect it has something to do with the fact that I'm calling

google.charts.setOnLoadCallback(drawMonthAndQuarterChart);
google.charts.setOnLoadCallback(drawLeaseAdminChart);
google.charts.setOnLoadCallback(drawFourthChart);

and since the charts are already drawn right on page creation, there's no way to redraw them. What I am not sure how to do is successfully get the charts to draw only when a new tab is active or something similar.

Ingate answered 16/8, 2017 at 16:56 Comment(0)
H
3

as you've gathered,
the problem is a result of drawing the chart while the tab is hidden

need to wait until the tab is shown before drawing for the first time

as such, only draw the first chart using the callback...

google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawMonthChart);

once the callback fires, you don't have to call it again,
you can draw as many charts as needed afterwards

then wait for the tabs to be clicked before drawing the next chart...

here, a switch statement is used on the href attribute,
to determine which tab was clicked,
then draw its chart...

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
    switch ($(e.target).attr('href')) {
      case '#home':
        drawMonthChart();
        break;

      case '#menu1':
        drawMonthAndQuarterChart();
        break;

      case '#menu2':
        drawLeaseAdminChart();
        break;

      case '#menu3':
        drawFourthChart();
        break;
    }
});
Humiliation answered 16/8, 2017 at 17:15 Comment(5)
Hey thanks so much for confirming my suspicions. I've implemented the switch statement as a new script on my view after the initial script that does the draw on Callback but when I click the other tabs, The select lists and labels show up but no charts do.Ingate
I added alerts instead of the function calls in the switch and they are not appearing. The code you provided looks like it should work as an event for the Bootstrap tabs that I'm using though so I'm confused as to why nothing appears to be fired off when I switch tabs.Ingate
Sorry, I should have been more clear, I tried both. Added it to the functions then separately to the switch. Neither fired off.Ingate
I found this. getbootstrap.com/docs/3.3/javascript/#tabs I will take a look here and see if I can't figure out what is going on here, this is my first time using these bootstrap tabs as well.Ingate
Okay there were some additional problems on my end but your code did end up working once I resolved those. Thanks so much for the assistance!Ingate

© 2022 - 2024 — McMap. All rights reserved.