Skip to content

Printing a HTML with a chart #7403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
hidegh opened this issue Apr 13, 2025 · 2 comments
Open

Printing a HTML with a chart #7403

hidegh opened this issue Apr 13, 2025 · 2 comments
Labels
bug something broken P3 backlog

Comments

@hidegh
Copy link

hidegh commented Apr 13, 2025

The HTML renders well.

The container "myDiv" has a width of 50% - PIC 1.

Now, when I try to print the HTML to A4, the chart is now overflowing, is outside the parent container, not re-sized.

I've added a rectange on the container for clarity.

PIC 1:
Image

PIC 2:
Image

@hidegh
Copy link
Author

hidegh commented Apr 13, 2025

NOTES:
The parent container has just its width set to 50%!
Height should be auto.

I'm trying also resizing, the graph, but the resizing seems to be done by height, where the inner container uses 100%, so result is odd:

Image

For those doing exp., I'm using extra scripts:

<script>
  window.addEventListener('beforeprint', () => {
    document.querySelectorAll('.js-plotly-plot').forEach(plot => {
      console.log('resizing', plot);
      Plotly.Plots.resize(plot);
    });
  });
</script>

@hidegh
Copy link
Author

hidegh commented Apr 14, 2025

Intermediate solution, good to play with - final should include auto patching all plotly graphs.

<html>
<head>
  <script src='https://cdn.plot.ly/plotly-3.0.1.min.js'></script>
  <style>
    #myDiv {
      width: 50% !important;
      border: 2px solid red;
      /*
      FLEX,
      OVERFLOW HIDDEN,
      FIXED HEIGHT (via VH),
      ...
      */

      /* must set height or use display flex, otherwise "plot-container plotly"'s 100% height will expand the container to stretch over multiple pages... */
      display: flex;
    }

    #myDiv .main-svg {
      border: 2px dashed red;
    }

    #myW {
      background-color: red;
      width: 0;
      height: 10px;
      margin-bottom: 10px;
    }
  </style>
</head>

<body>

  <div id="myW"></div>

  <div id='myDiv'>
    <!-- Plotly chart will be drawn inside this DIV -->
  </div>

  <img id="img" style="width: 25%" />

  <script>
    var trace1 = {
      x: ['giraffes', 'orangutans', 'monkeys'],
      y: [20, 14, 23],
      name: 'SF Zoo',
      type: 'bar'
    };

    var trace2 = {
      x: ['giraffes', 'orangutans', 'monkeys'],
      y: [12, 18, 29],
      name: 'LA Zoo',
      type: 'bar'
    };

    var data = [trace1, trace2];

    var layout = { barmode: 'stack' };

    Plotly.newPlot('myDiv', data, layout, { responsive: false });
  </script>

  <script>

    const resizeFn = () => {

      var container = document.querySelector('#myDiv');
      var containerBox = container.getBoundingClientRect();

      var svg = document.querySelector("#myDiv .svg-container");
      var svgBox = svg.getBoundingClientRect();
      
      var ratio = svgBox.width / svgBox.height;
      // overriden with a more reliable offsetWidth as getBoundingClientRect().width is affected by zooming, scaling, or print mode!
      ratio = svg.offsetWidth / svg.offsetHeight;

      var w = containerBox.width;
      // overriden with a more reliable offsetWidth as getBoundingClientRect().width is affected by zooming, scaling, or print mode!
      w = container.offsetWidth;
      var h = w / ratio;

      console.log('container size', containerBox.width, containerBox.height);
      console.log('svg size', svgBox.width, svgBox.height);
      console.log('svg w/h ratio', ratio);
      console.log('new size', w, h);

      var visualizer = document.querySelector('#myW');
      visualizer.style.width = w;

      Plotly.relayout(container, { width: w, height: h, autosize: true })

    }

    window.onresize = () => {
      console.log('on resize');
      resizeFn();
    }

    window.matchMedia('print').onchange = (print) => {
      console.log('media change');
      if (print.matches) {
        console.log('- match -> resize');
        resizeFn();
      } else {
        console.log('- no match');
        resizeFn();
      }
    }

    /*
    window.onbeforeprint = () => {
      console.log('on before print');
    }

    window.onafterprint = () => {
      console.log('on after print');
    }
    */

  </script>

</body>

</html>

@gvwilson gvwilson added bug something broken P3 backlog labels Apr 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken P3 backlog
Projects
None yet
Development

No branches or pull requests

2 participants