XMLを吐き出す
GAEのデータストアに保存したデータを取得し、FusionChart(Flashベースのグラフ出力ライブラリ)でグラフ表示するというプログラムを作っている。
FusionChartは、グラフにプロットするデータを、以下のような形式のXMLで渡してやる必要がある。
XMLの一例です。 <?xml version="1.0" encoding="utf-8"?> <chart> <dataset> <set y="123.45" x="2009-12-01"/> <set y="223.12" x="2009-12-02"/> <set y="331.92" x="2009-12-03"/> <set y="297.31" x="2009-12-04"/> <set y="275.03" x="2009-12-05"/> <set y="197.27" x="2009-12-06"/> <set y="189.82" x="2009-12-07"/> </dataset> </chart>
このXMLデータの中身が固定ならば、静的ファイルとしてGAEのサーバに置けばいいのだが、データストアに保存されているyとxの値を動的に持ってきたい。しかし、GAEではサーバ側に動的にファイルを保存することができないため、XMLデータをレスポンスとして返すgetメソッドを作ることにした。
XML書き出しにどのライブラリを使えば良いのか、と調べていたのだが、よく考えたら、Djangoテンプレート使えば出来るんじゃね?と思いついたのでやってみる。
XMLテンプレートchartdata.xml
<?xml version="1.0" encoding="utf-8"?> <chart> <dataset> {% for d in datas %} <set y="{{ d.Rate }}" x="{{ d.Date }}"/> {% endfor %} </dataset> </chart>
Pythonコード(抜粋)
class ChartXML(webapp.RequestHandler): def get(self): #Bigtableからデータを取得 datas = model.MyBigTable.all().order('x') page_contents = {"datas" : datas} #XMLを吐き出す path = os.path.abspath('chartdata.xml') self.response.out.write(template.render(path, page_contents, True))
このようにしておいて、FusionChartへXMLデータのURLを渡す際に、
<div id="divChart"> ここにチャートが表示されます。(Adobe Flashが必要) </div> <script type="text/javascript"> $(function() { var myChart = new FusionCharts("chart/CandleStick.swf", "myChartId", "600", "300"); /* 静的ファイルへのURLを渡すかわりに、getメソッドへのURLを渡す */ myChart.setDataURL("/ChartXML"); myChart.render("divChart"); }); </script>
これでXMLデータが渡され、チャートが表示できた。
ただこの方法だと、Flashの?キャッシュが有効になってしまい、最新データが反映されないという問題があるのだが、それはまた別途。