wkhtmltopdf – how to load variables from python file into script tag in HTML file

Question:

i am generating a pdf file in python using pdfkit and wkhtmltopdf.
i have created a python dictionary and passed all the variables I want to show in the body of the HTML file and it works fine.
Now I have added Google charts to it, for doing that I have added a script tags in the head tag and it worked and I can see the graph in the PDF file.
But the data for the chart is hard coded and I want to pass the data as a variable from python.
So my qestion is how I can pass the variables to the script tag.

This is my code.

<head>
  <meta charset="utf-8" />
  <script src="http://www.gstatic.com/charts/loader.js"></script>
  <script>
    function init() {
      google.charts.load("44", { packages: ["corechart"] });
      var interval = setInterval(function () {
        if (
          google.visualization !== undefined &&
          google.visualization.DataTable !== undefined &&
          google.visualization.AreaChart !== undefined
        ) {
          clearInterval(interval);
          window.status = "ready";
          drawChart();
        }
      }, 100);
    }

    function drawChart() {
      // Define the chart to be drawn.
      var data = google.visualization.arrayToDataTable([
        ["Price", "Size"],
        [50, 7],
        [60, 8],
        [70, 8],
        [80, 9],
        [90, 9],
        [100, 9],
        [110, 10],
        [120, 11],
        [130, 14],
        [140, 14],
        [150, 15],
      ]);

      var chart = new google.visualization.AreaChart(
        document.getElementById("myChart")
      );
      chart.draw(data, null);
    }
  </script>
</head>

<body onload="init()">
  <div style="width: 950px; height: 500px" id="myChart"></div>
</body>

I have tried to pass it like what I used in the body tag but it didn’t work.

Asked By: Anan

||

Answers:

first, you can use the promise returned by google’s load statement,
instead of looping on an interval.

  google.charts.load("44", {
    packages: ["corechart"]
  }).then(drawChart);

next, I don’t know python.

but what you want to do is write the data as json to the body of a separate page.
then use fetch on this page to get that data and display it in the chart.

I think you can use something like dumps in python to write the json to a separate page.

google.charts.load("44", {
  packages: ["corechart"]
}).then(drawChart);

function drawChart() {
  fetch('url path to separate page where python data is written').then((response) => response.json()).then((jsonData) => {
    var data = google.visualization.arrayToDataTable(jsonData);
    var chart = new google.visualization.AreaChart(
      document.getElementById("myChart")
    );
    chart.draw(data, null)
  });
}
Answered By: WhiteHat

I solved the problem like this.
I have added the arrays in this way in python

output_text = template.render(context, data1=data1, data2=data2, data3=data3)

and added a delay in python pdfkit options so it can render the graphs

 options = {
        "page-size": "A4",
        "encoding": "UTF-8",
        "javascript-delay": 3000,
    }

And in HTML script tag but I have got it as a string instead of an array so I have used eval()

eval("{{data1}}")

and that is how I solved the problem.

Final working code:

<script>
  function init() {
    google.load("visualization", "44", { packages: ["corechart"] });
    var interval = setInterval(function () {
      if (
        google.visualization !== undefined &&
        google.visualization.DataTable !== undefined &&
        google.visualization.AreaChart !== undefined
      ) {
        clearInterval(interval);
        window.status = "ready";
        var data1 = google.visualization.arrayToDataTable(eval("{{data1}}"));
        var chart1 = new google.visualization.AreaChart(
          document.getElementById("myChart1")
        );
        chart1.draw(data1, null);
      }
    }, 1000);
  }
</script>
<body onload="init()">
  <div class="graph-style" id="myChart1"></div>
</body>
Answered By: Anan