简体   繁体   中英

Make google charts responsive while keeping aspect ratio of parent element constant

I currently have a dashboard with 4 columns at the top with the grid elements set to padding-top 100% to keep a perfect square (may change to 75% but solution should hopefully work for any aspect ratio). I would like the donut chart to fit inside the parent div and not overflow into hidden but instead shrink the chart such that the height fits inside the parent div. Currently, the chart does shrink since i have have width set to 100% but the bottom of the donut chart gets hidden at most resolutions. If I click to refresh the page it loads perfectly. I have added javascript to make the chart responsive but doesnt seem to fix the overflow problem when collapsing page. I was thinking since the child elements of the flex should be flex items so couldnt I use flex-grow vertically to fill column of that second item which is the google chart? I could be thinking about this wrong all together tho and would really appreciate some feedback.

Looking at this post seems to reference a similar issue by vincent in the comment but the exact solution is not written out.

Google chart redraw/scale on window resize

HTML

    <link rel="stylesheet" href="~/css/dashboard.css" />

<div class="grid-4-2-1 grid-square">
    <grid-child-1 class="grid-child">
        <div class="grid-content">
            <div class="chart-container">
                <h4>Title 1</h4>
                <div id="title1-donut-chart" class="chart"></div>
            </div>
        </div>
    </grid-child-1>
    <grid-child-2 class="grid-child">
        <div class="grid-content">
            <div class="chart-container">
                <h4>Title 2</h4>
                <div id="title2-donut-chart" class="chart"></div>
            </div>
        </div>
    </grid-child-2>
    <grid-child-3 class="grid-child">
        <div class="grid-content">
            <div class="chart-container">
                <h4>Title 3</h4>
                <div id="title3-donut-chart" class="chart"></div>
            </div>
        </div>
    </grid-child-3>
    <grid-child-4 class="grid-child">
        <div class="grid-content">

        </div>
    </grid-child-4>
</div>

@section Scripts
{
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script src="~/js/dashboard.js"></script>
    <script type="text/javascript">
        // Set a callback to run when the Google Visualization API is loaded.
        google.charts.setOnLoadCallback(drawChartPrimary);
        google.charts.setOnLoadCallback(drawChartSecondary);
        google.charts.setOnLoadCallback(drawChartSupervising);
    </script>

CSS

.chart-container {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    flex-direction: column
}
.chart-container h4{
    margin-bottom: 10px;
}

.grid-4-2-1 {
    display: grid;
    grid-template-areas: "grid-child-1 grid-child-2 grid-child-3 grid-child-4";
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-gap: 10px;
    margin: 10px;
}

.grid-3-1 {
    display: grid;
    grid-template-areas: "grid-child-1 grid-child-2 grid-child-3";
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-gap: 20px;
    margin: 20px;
}

.grid-child {
    position: relative;
    align-items: center;
    justify-content: space-between;
    background-color: #fff;
    position: relative;
    border: .5px solid #e6e6e6;
}

.grid-child .grid-content {
    position: absolute;
    right: 0px;
    top: 0px;
    height: 100%;
    width: 100%;
    box-sizing: border-box;
    overflow:hidden;
    padding: 10px;
}

.grid-square .grid-child {
    padding-top: 100%;
}

.chart {
    height: 100%;
    width: auto;
}


/*javascript made @media queries without sidebar*/
.width-480-768 .grid-4-2-1 {
    grid-template-areas: "grid-child-1 grid-child-2" "grid-child-3 grid-child-4";
    grid-template-columns: repeat(2, minmax(0, 1fr));
}


.width-0-480 .grid-4-2-1 {
    grid-template-areas: "grid-child-1" "grid-child-2" "grid-child-3" "grid-child-4";
    grid-template-columns: repeat(1, minmax(0, 1fr));
}

.width-0-480 .grid-3-1 {
    grid-template-areas: "grid-child-1" "grid-child-2" "grid-child-3";
    grid-template-columns: repeat(1, minmax(0, 1fr));
}

Javascript

window.addEventListener("resize", function () {
    drawChartTitle1();
    drawChartTitle2();
    drawChartTitle3();
});

document.querySelector('#main-subnav-menu').addEventListener('transitionend', function () {
    drawChartTitle1();
    drawChartTitle2();
    drawChartTitle3();
});

// Load the Visualization API and the corechart package.
google.charts.load('current', {'packages': ['corechart'] });

// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChartTitle1() {

    // Create the data table.
    var data = google.visualization.arrayToDataTable([
        ['Task', 'Hours per Day'],
        ['stuff1', 11],
        ['stuff2', 2]
    ]);

    // Set chart options
    var options = {
        legend: 'none',
        pieSliceText: 'label',
        legend: 'none',
        pieHole: 0.3,
        chartArea: { 'width': '100%', 'height': '100%' }
    };

    // Instantiate and draw our chart, passing in some options.
    var chart = new google.visualization.PieChart(document.getElementById('title1-donut-chart'));
    chart.draw(data, options);
}

function drawChartTitle2() {

    // Create the data table.
    var data = google.visualization.arrayToDataTable([
        ['Task', 'Hours per Day'],
        ['stuff1', 11],
        ['stuff2', 2]
    ]);

    // Set chart options
    var options = {
        legend: 'none',
        pieSliceText: 'label',
        legend: 'none',
        pieHole: 0.3,
        chartArea: { 'width': '100%', 'height': '100%' }
    };

    // Instantiate and draw our chart, passing in some options.
    var chart = new google.visualization.PieChart(document.getElementById('title2-donut-chart'));
    chart.draw(data, options);
}

function drawChartTitle3() {

    // Create the data table.
    var data = google.visualization.arrayToDataTable([
        ['Task', 'Hours per Day'],
        ['stuff1', 11],
        ['stuff2', 2]
    ]);

    // Set chart options
    var options = {
        legend: 'none',
        pieSliceText: 'label',
        legend: 'none',
        pieHole: 0.3,
        chartArea: { 'width': '100%', 'height': '100%' }
    };

    // Instantiate and draw our chart, passing in some options.
    var chart = new google.visualization.PieChart(document.getElementById('title3-donut-chart'));
    chart.draw(data, options);
}

The only solution I could find was to add the following to the javascript functions when drawing the charts in the resize events and transition events.

document.getElementById('title1-review-donut-chart').innerHTML = '';

It turns out you have to delete all content first so the browser can resize the div first. The link posted in my question had a hint towards it but this would be the pure javascript method of doing this.

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