将Python中的JSON加载到Google注释图表的DataTable中

时间:2014-02-22 19:14:55

标签: python json google-visualization web.py

我用python收集污染数据并将其存储在MySQL表中。 现在,我希望在Google的Annotated charts之一中显示此内容。

当我在网页上显示图表,通过web.py服务器呈现时,我得到一张空白图表。 没什么,只是空白。它可能是JSON字符串的格式化方式,也可能是我尝试将其加载到DataTable对象中的方式。

以下是我目前如何将MySQL数据转换为DataTable对象并使用Python和web.py将其转发到Web:

  1. 使用python从mysql查询数据。这回来了:

    [(datetime.datetime(2014, 2, 23, 2, 1, 3), 329),
     (datetime.datetime(2014, 2, 23, 1, 1, 4), 337),
     (datetime.datetime(2014, 2, 23, 0, 1, 5), 353),
     (datetime.datetime(2014, 2, 22, 23, 1, 4), 377),
     (datetime.datetime(2014, 2, 22, 22, 1, 7), 404),
     (datetime.datetime(2014, 2, 22, 21, 1, 5), 402),
     (datetime.datetime(2014, 2, 22, 20, 1, 4), 391),
     (datetime.datetime(2014, 2, 22, 19, 1, 3), 385),
     (datetime.datetime(2014, 2, 22, 18, 1, 3), 389),
     (datetime.datetime(2014, 2, 22, 17, 1, 3), 400)]
    
  2. 然后使用谷歌的gviz_api python库来定义表

    description = [("Time","datetime"),
                   ("PM25 Pollution","number")]
    
  3. 然后创建DataTable对象并加载数据

    data_table = gviz_api.DataTable(description)
    data_table.LoadData(data)
    
  4. 我正在使用web.py来渲染所有这些并在网上获取它,所以我得到了JSON字符串:

    return data_table.ToJson()
    
  5. 这是返回的JSON字符串:

    {"rows":[{"c":[{"v":"Date(2014,1,23,2,1,3)"},{"v":329}]},{"c":[{"v":"Date(2014,1,23,1,1,4)"},{"v":337}]},{"c":[{"v":"Date(2014,1,23,0,1,5)"},{"v":353}]},{"c":[{"v":"Date(2014,1,22,23,1,4)"},{"v":377}]},{"c":[{"v":"Date(2014,1,22,22,1,7)"},{"v":404}]},{"c":[{"v":"Date(2014,1,22,21,1,5)"},{"v":402}]},{"c":[{"v":"Date(2014,1,22,20,1,4)"},{"v":391}]},{"c":[{"v":"Date(2014,1,22,19,1,3)"},{"v":385}]},{"c":[{"v":"Date(2014,1,22,18,1,3)"},{"v":389}]},{"c":[{"v":"Date(2014,1,22,17,1,3)"},{"v":400}]}],"cols":[{"type":"datetime","id":"Time","label":"Time"},{"type":"number","id":"PM25 Pollution","label":"PM25 Pollution"}]}
    
  6. 然后我将字符串发送到此模板进行渲染:

    $def with (jsonDataString)
    
    <html>
      <head>
        <script type='text/javascript' src='http://www.google.com/jsapi'></script>
        <script type='text/javascript'>
          google.load('visualization', '1.1', {'packages':['annotationchart']});
          google.setOnLoadCallback(drawChart)
    
          function drawChart() {
            var data = new google.visualization.DataTable($jsonDataString);
    
            var chart = new google.visualization.AnnotationChart(document.getElementById('chart_div'));
    
            var options = {
              displayAnnotations: true,
            };
    
            chart.draw(data, options);
          }
        </script>
      </head>
    
      <body>
        <div id='chart_div' style='width: 900px; height: 500px;'></div>
        <!-- Output the string to see if its there-->
        $jsonDataString
      </body>
    </html>
    
  7. 当我加载页面时,请看一个900 x 500像素的空白空格,然后是上面的JSON字符串。所以我知道我收到了JSON字符串,但我是图表的新手,不知道它是否格式正确。我没有改变任何东西,只是让gviz_api Python库完成工作。

    我也尝试过:

    var data = new google.visualization.DataTable.fromJson($jsonDataString);
    

    但无济于事。

    注意:$jsonDataString由web.py模板系统转义,并被当前显示的字符串替换。

    我已经用google进行了一些搜索,并且堆栈溢出并且似乎无法找到问题所在。如果您有任何建议或意见,我们将不胜感激。如果您认为可以提供帮助,我会尽力详细说明,但我不太了解我在这里写的内容。

    编辑#1 有趣。这实际上是我在Chrome中查看源代码时得到的内容。这是由web.py的Templator:

    呈现的
        <html>
        <head>
            <script type='text/javascript' src='http://www.google.com/jsapi'></script>
            <script type='text/javascript'>
              google.load('visualization', '1.1', {'packages':['annotationchart']});
              google.setOnLoadCallback(drawChart)
    
              function drawChart() {
                var data = new google.visualization.DataTable({&quot;rows&quot;:[{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,18,1,4)&quot;},{&quot;v&quot;:383}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,17,1,3)&quot;},{&quot;v&quot;:386}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,16,1,3)&quot;},{&quot;v&quot;:366}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,15,1,4)&quot;},{&quot;v&quot;:333}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,14,1,3)&quot;},{&quot;v&quot;:329}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,13,1,3)&quot;},{&quot;v&quot;:320}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,12,1,3)&quot;},{&quot;v&quot;:316}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,11,1,4)&quot;},{&quot;v&quot;:302}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,10,1,3)&quot;},{&quot;v&quot;:296}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,9,1,3)&quot;},{&quot;v&quot;:296}]}],&quot;cols&quot;:[{&quot;type&quot;:&quot;datetime&quot;,&quot;id&quot;:&quot;Time&quot;,&quot;label&quot;:&quot;Time&quot;},{&quot;type&quot;:&quot;number&quot;,&quot;id&quot;:&quot;PM25 Pollution&quot;,&quot;label&quot;:&quot;PM25 Pollution&quot;}]});
    
                var chart = new google.visualization.AnnotationChart(document.getElementById('chart_div'));
    
                var options = {
                  displayAnnotations: true,
                };
    
                chart.draw(data, options);
              }
    
            </script>
        </head>
    
        <body>
        <div id='chart_div' style='width: 900px; height: 500px;'></div>
        <!-- Output the string to see if its there-->
        {&quot;rows&quot;:[{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,18,1,4)&quot;},{&quot;v&quot;:383}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,17,1,3)&quot;},{&quot;v&quot;:386}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,16,1,3)&quot;},{&quot;v&quot;:366}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,15,1,4)&quot;},{&quot;v&quot;:333}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,14,1,3)&quot;},{&quot;v&quot;:329}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,13,1,3)&quot;},{&quot;v&quot;:320}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,12,1,3)&quot;},{&quot;v&quot;:316}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,11,1,4)&quot;},{&quot;v&quot;:302}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,10,1,3)&quot;},{&quot;v&quot;:296}]},{&quot;c&quot;:[{&quot;v&quot;:&quot;Date(2014,1,23,9,1,3)&quot;},{&quot;v&quot;:296}]}],&quot;cols&quot;:[{&quot;type&quot;:&quot;datetime&quot;,&quot;id&quot;:&quot;Time&quot;,&quot;label&quot;:&quot;Time&quot;},{&quot;type&quot;:&quot;number&quot;,&quot;id&quot;:&quot;PM25
        Pollution&quot;,&quot;label&quot;:&quot;PM25 Pollution&quot;}]}
        </body>
        </html>
    

    我想我知道这里发生了什么。 web.py的Templator必须用网络安全报价替换&#34; s。这显然不适合JS。我想要做的就是找到如何在web.py中禁用websafe引用呈现。 (或者找一些其他的工作。)

    感谢Anto,感谢您的建议。我真的很难不检查输出!

    编辑#2:已解决 为了使web.py无法呈现网络安全报价,我只需更换:

    $jsonDataString
    

    $:jsonDataString
    

    在web.py模板中。 找到答案here

1 个答案:

答案 0 :(得分:0)

我来到这里寻找从(python)pandas数据框 - &gt; json - &gt; JavaScript中的google.visualization.DataTable ......

#imports
import pandas as pd
import json
# create df for test
cols = ["col1", "col2", "col3"]
vals = [["work",2,3],["play",5,6]]
df = pd.DataFrame(vals, columns=cols)


# Send df to google.visualization.DataTable via json
# ..parse column data (I'm only using numbers and strings)
# ..google allows ['string', 'number', 'boolean', 'date', 'datetime', and 'timeofday']
# ..but no dates for json
# .. ..one-liner here
cols = [{"id": col,
        "label": col,
        "type": "string" if df[col].dtype == 'O' else "number"
        } for col in df.columns]
# ..use pandas to get at the row data
jsdata = json.loads(df.to_json(orient="split"))["data"]
# .. ..multi-liners seem easier to read...
rows = []
for row in jsdata:
    row = [{"v": val} for val in row]
    rows.append({"c": row})

#.. I'm using dumps to show the value but you probably want to use 
#.. dump in practice
to_google = json.dumps({"cols": cols, "rows": rows})
print(to_google)

In [1]:
{"cols": [{"id": "col1", "label": "col1", "type": "string"}, {"id": "col2", "label": "col2", "type": "number"}, {"id": "col3", "label": "col3", "type": "number"}], "rows": [{"c": [{"v": "work"}, {"v": 2}, {"v": 3}]}, {"c": [{"v": "play"}, {"v": 5}, {"v": 6}]}]}

在.js方面,关键行是:

// parse the responseText from your xhttp GET
_jsonIn = JSON.parse(xhttp.responseText);
// drop it into your table
dt = new google.visualization.DataTable(_jsonIn);

transported table