【问题标题】:Chart.js not updating or receiving data from Flask pythonChart.js 没有从 Flask python 更新或接收数据
【发布时间】:2018-12-18 15:19:46
【问题描述】:

我正在尝试使用来自 python 脚本的数据为 Web 应用程序创建交互式图表。

错误是python代码中的数据没有在chart.js脚本上传输或更新,也没有在html上输出。

三个脚本的流程:来自python的标签和数据,进入chart.js以呈现条形图并在html上输出

当我将非洲(数据点)从 2447 更改为 5578 时,图表没有更新。我不确定问题是从 python 转移还是渲染图表。

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>

【问题讨论】:

    标签: javascript python flask chart.js


    【解决方案1】:

    script1.js 没有被flask.render_template 渲染,因为它只被script 标签链接。但是,向后端发送请求以获取 jsonified 数据比尝试在模板中呈现值本身要好得多。在 Python 文件中创建一个额外的路由以在 ajax 请求时返回值:

    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})})
    

    不要忘记在 HTML 中包含 jquery 以支持 ajax 调用:

    <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>
    

    最后,在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'
       }
      }
     });
    });
    

    【讨论】:

    • 你能解释一下解决方案吗 1)如何在 Python 文件中创建一个额外的路由以在 ajax 请求时返回值 2)什么是 flask.jsonify({'payload':json.dumps ({'data':data, 'labels':labels})}) 3)javascript的第一段?
    • @Lko Python 文件中的附加路由已经创建(get_data)。 flask.jsonify 返回数据结构 {'payload': {'data': [5578, 5267, 734, 784, 433], 'labels': ['Africa', 'Asia', 'Europe', 'Latin America', 'North America']}} 的字符串化版本,然后将其加载到 javascript 对象中。
    • 或者让我澄清一下我在做什么。我用 pandas 编写了一个 python 脚本,它输出了一些表格和折线图。我正在尝试创建一个网络应用程序,(我可以在其中获取用户输入,然后输出我尝试过的折线图和表格。我正在尝试使用烧瓶,如果有更好的方法,请告诉我
    • @Lko flask 无疑是显示来自pandas 数据框的值的最简单方法。
    • 这部分怎么样? $(document).ready(function(){ var _data; var _labels; $.ajax({ url: "/get_data", type: "get", data: {vals: ''}, success: function(response) {
    【解决方案2】:

    响应@Lko评论的代码示例将js保存在单独的文件中,请参阅我对上一篇文章的评论。

    文件结构: \main.py \静态\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'
            }
          }
          });
    

    【讨论】:

    • 您好,谢谢!为什么不能 var labelsVar={{labels|tojson}}; var dataVar={{data|tojson}};从 html 到 javascript 的行?
    【解决方案3】:

    要渲染 javascript(替换你的变量)将 javascript 放在要渲染的 html 文件中,并使用 Flask jinja filter tojson:一个例子:

      <!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>
    

    【讨论】:

    • 如果我将
    • 如果您可以通过调用 API 从 javascript 加载数据可能会更好。即使用烧瓶创建一个 API 并在 API 上创建一个 HTTP GET 以加载您的数据。但是,如果您真的想采用这种方法,我建议您将尽可能多的 javascript 保留在 .js 文件中,并使用呈现数据部分的脚本部分,即一个脚本将数据加载到变量中,而您的主 js 脚本只使用变量已经定义。请参阅下面的代码示例。然后编写和调试脚本可能会更容易,因为它是纯 javascript。
    【解决方案4】:
    data:JSON.parse('{{data}}')
    

    我无法将我的烧瓶应用程序中的数据传递到 html 中的脚本部分,所以我这样做了,它成功了。

    【讨论】:

      【解决方案5】:

      您可以在列表中传递数据(使用 render_template)并在 html 中检索它:

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

      【讨论】:

        猜你喜欢
        • 2023-03-21
        • 2019-01-02
        • 2020-07-31
        • 2018-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多