Home > Back-end >  How to create a JS file from python graph
How to create a JS file from python graph

Time:06-06

I have used altair to create graphs using python. So I have used following code to save the chart.

chart.save('chart.html', embed_options={'actions': False})

My chart.html file look as below,

<!DOCTYPE html>
<html>
<head>
  <style>
    .error {
        color: red;
    }
  </style>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm//vega@5"></script>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm//[email protected]"></script>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm//vega-embed@6"></script>
</head>
<body>
  <div id="vis"></div>
  <script>
    (function(vegaEmbed) {
      var spec = {"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"url": "https://cdn.jsdelivr.net/npm/[email protected]/data/cars.json"}, "mark": "point", "encoding": {"color": {"type": "nominal", "field": "Origin"}, "x": {"type": "quantitative", "field": "Horsepower"}, "y": {"type": "quantitative", "field": "Miles_per_Gallon"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json"};
      var embedOpt = {"actions": false, "mode": "vega-lite"};
function showError(el, error){
          el.innerHTML = ('<div  style="color:red;">'
                            '<p>JavaScript Error: '   error.message   '</p>'
                            "<p>This usually means there's a typo in your chart specification. "
                            "See the javascript console for the full traceback.</p>"
                            '</div>');
          throw error;
      }
      const el = document.getElementById('vis');
      vegaEmbed("#vis", spec, embedOpt)
        .catch(error => showError(el, error));
    })(vegaEmbed);
</script>
</body>
</html>

This works fine and I could see my graph without any issue. But I need to convert it to a javascript file so I could call that script whenever I need. Is there any way to get a javascript file as follows?

mychart.js
----------
(function(vegaEmbed) {
      var spec = {"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"url": "https://cdn.jsdelivr.net/npm/[email protected]/data/cars.json"}, "mark": "point", "encoding": {"color": {"type": "nominal", "field": "Origin"}, "x": {"type": "quantitative", "field": "Horsepower"}, "y": {"type": "quantitative", "field": "Miles_per_Gallon"}}, "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json"};
      var embedOpt = {"actions": false, "mode": "vega-lite"};
function showError(el, error){
          el.innerHTML = ('<div  style="color:red;">'
                            '<p>JavaScript Error: '   error.message   '</p>'
                            "<p>This usually means there's a typo in your chart specification. "
                            "See the javascript console for the full traceback.</p>"
                            '</div>');
          throw error;
      }
      const el = document.getElementById('vis');
      vegaEmbed("#vis", spec, embedOpt)
        .catch(error => showError(el, error));
    })(vegaEmbed);

My intention is to use as below, then I can easily call this from different file.

<div id="vis"></div>
  <script src="mychart.js"></script>

Update:-

Is there anyway to change the keyword 'vis' before creating JS? like below,

const el = document.getElementById('ID1');
          vegaEmbed("#ID1", spec, embedOpt)
            .catch(error => showError(el, error));

CodePudding user response:

There is no built-in function for that, so the easiest is probably to index the html string based on the occurrence of the word vegaEmbed and an offset:

import altair as alt
from vega_datasets import data


source = data.cars.url
chart = alt.Chart(source).mark_circle().encode(
    x=alt.X('Horsepower:Q', scale=alt.Scale(nice=False)),
    y='Miles_per_Gallon:Q',
)

html_chart = chart.to_html()
# These offsets will be the same for any chart
start = html_chart.index('vegaEmbed') - 10
end = html_chart.index('vegaEmbed);')   11
print(html_chart[start:end])
# Out
(function(vegaEmbed) {
      var spec = {"config": {"view": {"continuousWidth": 400, "continuousHeight": 300}}, "data": {"url": "https://cdn.jsdelivr.net/npm/[email protected]/data/cars.json"}, "mark": "circle", "encoding": {"x": {"field": "Horsepower", "scale": {"nice": false}, "type": "quantitative"}, "y": {"field": "Miles_per_Gallon", "type": "quantitative"}}, "$schema": "https://vega.github.io/schema/vega-lite/v5.2.0.json"};
      var embedOpt = {"mode": "vega-lite"};

      function showError(el, error){
          el.innerHTML = ('<div  style="color:red;">'
                            '<p>JavaScript Error: '   error.message   '</p>'
                            "<p>This usually means there's a typo in your chart specification. "
                            "See the javascript console for the full traceback.</p>"
                            '</div>');
          throw error;
      }
      const el = document.getElementById('vis');
      vegaEmbed("#vis", spec, embedOpt)
        .catch(error => showError(el, error));
    })(vegaEmbed);

Then you can write that string variable to disk like a regular text file.

  • Related