Publishing a chart from Google Sheets produces fixed-width result
Asked Answered
A

2

7

A client has many Google spreadsheets containing data from which they have generated charts on new sheets within the workbook. I have provided code which enables them to publish the chart (which previously generated a <script> element containing JSON), copypaste the published JSON into their CMS, and have the end result be a generated responsive <iframe>. The chart's width option is changed on the fly to match the container, and the usual trick of reloading the chart when the browser is resized handles keeping it that way.

However, Google Sheets has been updated and the client's new charts only have an option to publish as "Link" or "Embed", where the latter is just an <iframe> wrapped around the former. As the <iframe> is published with a fixed width, I have updated my code to handle this alternative, changing the width attribute of the iframe on the fly.

The problem is that the internal contents of this iframe are now completely generated by Google with a fixed width, rather than a width which matches the containing iframe (whose width I am setting).

I can't reach into the iframe to modify the document from script, as it's from a different domain. The original chart embedded in the spreadsheet is responsive (resizing the browser window containing the spreadsheet resizes the chart very nicely) but I cannot see any way to maintain that effect during publishing.

I could move everything out into script that directly uses the visualization API, but then it's not using the client's pre-generated charts (and it seems like every chart they produce is a different style/layout, which would be a maintenance nightmare).

So: how can I publish a pre-existing chart from a Google Sheets document, with the published result being responsive in the same way as the original chart?

Azar answered 16/1, 2015 at 11:12 Comment(2)
Still interested in an answer if anyone comes up with one, but the "solution" I've ended up going with is to suggest the client use Highcharts Cloud, whose iframe exports are responsive.Azar
have you tried css zoom option or transform: scale?Stipitate
R
2

If you can live with scaling and smaller text / thin lines.

Solution is using this JS + JQuery Scaling method in HTML head section, this written by yazzz here, kudos to her/him in that link, not in here.

<head>
<script 
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js">
</script>
<script>
// this script is written by yazzz https://mcmap.net/q/1627072/-dynamic-scaling-of-iframe-contents-as-frame-changes
$(function() {
    $("#wrapper").each(function() {
        var $wrap = $(this);
        function iframeScaler(){
            var wrapWidth = $wrap.width(); // width of the wrapper
            var wrapHeight = $wrap.height();
            var childWidth = $wrap.children("iframe").width(); // width of child iframe
            var childHeight = $wrap.children("iframe").height(); // child height
            var wScale = wrapWidth / childWidth;
            var hScale = wrapHeight / childHeight;
            var scale = Math.min(wScale,hScale);  // get the lowest ratio
            $wrap.children("iframe").css({"transform": "scale("+scale+")", "transform-origin": "left top" });  // set scale
        };
        $(window).on("resize", iframeScaler);
        $(document).ready( iframeScaler);
    });
});
</script>
</head>

<body>
<p>Responsive and Dynamic Iframe Scaling of Published Chart from Google Spreadsheet</p>
<p>Courtesy of <a href="https://mcmap.net/q/1627072/-dynamic-scaling-of-iframe-contents-as-frame-changes">yazzz from Javascript StackOverflow</a></p>

<div id="wrapper">
    <iframe width="500" height="294" seamless frameborder="0" scrolling="no" src="https://docs.google.com/spreadsheets/d/e/2PACX-1vRB4wPFarqsHWgk0ubQ6bH3YC5iwvDayAkrDg0iNPipAAszBA26QnFaPC1Xk5g8XF1ixP7jnsxiaMzL/pubchart?oid=1495533449&amp;format=interactive"></iframe>
</div>

</body>

You can view his/her implementation of my sample here in JS Fiddle

Rattail answered 19/6, 2020 at 11:6 Comment(0)
C
1

From what I saw the issue is that the google sheets canvas is usually around 50% of mobile size, so here is my solution. It's a bit weird but works for me:

@media (max-width:500px) {
    body p:has(iframe[src^="https://docs.google.com/spreadsheets"]) {
        transform: scale(0.5);
        transform-origin: top left;
    }
    body p iframe[src^="https://docs.google.com/spreadsheets"] {
        min-width: 200%;
        position: relative;
        left: 100%;
        margin-bottom: -180%;       
    }
}
Christenechristening answered 26/9, 2022 at 17:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.