Lko
Lko

Reputation: 252

Chart.js not updating or receiving data from Flask python

I am trying to create an interactive chart for a web app with data from python script.

The error is data from the python code is not transferred or updated on the chart.js script and not output on the html.

The flow of the 3 scripts: labels and data from python, goes into the chart.js to render the bar-chart and is output on the html

When I change Africa (data point) from 2447 to 5578, the chart is not updated. I am not sure if the issue is transferring from python or rendering the chart.

Python

from flask import Flask,render_template
app = Flask(__name__)

@app.route("/")
def result():
   labels = ["Africa", "Asia", "Europe", "Latin America", "North America"]

   data = [5578,5267,734,784,433]

   return render_template("result.html", labels=labels, data=data)
if __name__ == '__main__':
app.debug = True
app.run()

script1.js

new Chart(document.getElementById("bar-chart"), {
type: 'bar',
data: {
  labels: "{{labels}}",
  datasets: [
    {
      label: "Population (millions)",
      backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
      data: "{{data }}"
    }
  ]
},
options: {
  legend: { display: false },
  title: {
    display: true,
    text: 'Predicted world population (millions) in 2050'
  }
}
});

HTML

  <!DOCTYPE html>
<html>
  <head>
    <title>New</title>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"> 
</script>

  </head>
  <body>
  <h1>Test</h1>
    <div class="wrapper">
    <canvas id="bar-chart" width="800" height="450"></canvas>
    </div>

     <script src="{{ url_for('static', filename='script1.js') }}"></script>

   </body>
  </html>

Upvotes: 1

Views: 7911

Answers (5)

Al Martins
Al Martins

Reputation: 436

You may pass the data on a list (with render_template) and retrieve it on html with:

labels: [{% for item in families %}
         "{{ item }}",
         {% endfor %}]

Upvotes: 0

Vaisakh Gopinath
Vaisakh Gopinath

Reputation: 123

data:JSON.parse('{{data}}')

I couldn't pass data from my flask app to script section in html so I did this and it worked.

Upvotes: 0

Steve
Steve

Reputation: 496

Code example in response to @Lko comment to keep js in a separate file, see my comment to the previous post.

File structure: \main.py \static\script1.js \templates\result.html

HTML:

    <!DOCTYPE html>
    <html>
      <head>
        <title>New</title>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script>

      </head>
      <body>
      <h1>Test</h1>
        <div class="wrapper">
        <canvas id="bar-chart" width="800" height="450"></canvas>
        </div>

        <!-- <script src="{{ url_for('static', filename='script1.js') }}"></script> -->
        <script type = "text/javascript">
            var labelsVar={{labels|tojson}};
            var dataVar={{data|tojson}};
        </script>
        <script type = "text/javascript"  src="{{ url_for('static', filename = 'script1.js') }}"></script>
      </body>
      </html>

Javascript:

  console.log(labelsVar);
  console.log(dataVar);
  new Chart(document.getElementById("bar-chart"), {
      type: 'bar',
      data: {
        labels: labelsVar,
        datasets: [
          {
            label: "Population (millions)",
            backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
            data: dataVar
          }
        ]
      },
      options: {
        legend: { display: false },
        title: {
          display: true,
          text: 'Predicted world population (millions) in 2050'
        }
      }
      });

Upvotes: 2

Steve
Steve

Reputation: 496

To render the javascript (replacing your variables) put the javascript in the html file to be rendered and use Flask jinja filter tojson: An example:

  <!DOCTYPE html>
  <html>
    <head>
      <title>New</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script>

    </head>
    <body>
    <h1>Test</h1>
      <div class="wrapper">
      <canvas id="bar-chart" width="800" height="450"></canvas>
      </div>

      <!-- <script src="{{ url_for('static', filename='script1.js') }}"></script> -->
      <script>
          //console.log({{labels|tojson}});
          //console.log({{data|tojson}});
          new Chart(document.getElementById("bar-chart"), {
              type: 'bar',
              data: {
                labels: {{labels|tojson}},
                datasets: [
                  {
                    label: "Population (millions)",
                    backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
                    data: {{data|tojson}}
                  }
                ]
              },
              options: {
                legend: { display: false },
                title: {
                  display: true,
                  text: 'Predicted world population (millions) in 2050'
                }
              }
              });
      </script>

    </body>
    </html>

Upvotes: 1

Ajax1234
Ajax1234

Reputation: 71451

script1.js is not being rendered by flask.render_template as it is only being linked to by the script tag. However, it is much better practice to send a request to the backend for jsonified data than attempt to render the values themselves in the template. Create an additional route in the Python file to return the values upon an ajax request:

import json
@app.route("/")
def result():
  return render_template("result.html")

@app.route('/get_data')
def get_data():
  labels = ["Africa", "Asia", "Europe", "Latin America", "North America"]
  data = [5578,5267,734,784,433]
  return flask.jsonify({'payload':json.dumps({'data':data, 'labels':labels})})

Do not forget to include jquery to support the ajax call in the HTML:

<head> 
  <title>New</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"> 
</head>

Lastly, in script1.js:

$(document).ready(function(){
   var _data;
   var _labels;
  $.ajax({
   url: "/get_data",
   type: "get",
   data: {vals: ''},
   success: function(response) {
     full_data = JSON.parse(response.payload);
     _data = full_data['data'];
     _labels = full_data['labels'];
   },

 });
 new Chart(document.getElementById("bar-chart"), {
  type: 'bar',
 data: {
   labels: _labels,
   datasets: [
   {
    label: "Population (millions)",
    backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
   data: _data
   }
   ]
   },
    options: {
    legend: { display: false },
     title: {
      display: true,
     text: 'Predicted world population (millions) in 2050'
   }
  }
 });
});

Upvotes: 7

Related Questions