Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed whitespace problems in the charts tag, fixed example generator,…

… then regenerated examples.
  • Loading branch information...
commit dd7140be04c1bad79c06bc518b9f6b3e3303dc10 1 parent e83b4c3
@jacobian jacobian authored
View
50 docs/examples.html
@@ -52,7 +52,7 @@
{% chart-colors "CC0000" "00CC00" %}
{% chart-background "EEEEEE" %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chtt=Hello,+World%21&amp;cht=lc&amp;chs=300x200&amp;chco=CC0000,00CC00&amp;chf=bg,s,EEEEEE&amp;chd=e:AAAKApBcCkEAFxH2KPM9QATXXCbCfXj.o9uPz15w,..5wz1uPo9j.fXbCXCTXQAM9KPH2FxEACkBcApAK" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chtt=Hello,+World%21&amp;cht=lc&amp;chs=300x200&amp;chco=CC0000,00CC00&amp;chf=bg,s,EEEEEE&amp;chd=e:AAAKApBcCkEAFxH2KPM9QATXXCbCfXj.o9uPz15w,..5wz1uPo9j.fXbCXCTXQAM9KPH2FxEACkBcApAK" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -64,7 +64,7 @@
{% chart-size &quot;300&quot; &quot;200&quot; %}
{% chart-background-gradient &quot;45&quot; &quot;000000&quot; &quot;0&quot; &quot;FFFFFF&quot; &quot;0.6&quot; %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?cht=v&amp;chs=300x200&amp;chf=bg,lg,45,000000,0,FFFFFF,0.6&amp;chd=e:..zMmZTNTNTNGa" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?cht=v&amp;chs=300x200&amp;chf=bg,lg,45,000000,0,FFFFFF,0.6&amp;chd=e:..zMmZTNTNTNGa" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -76,7 +76,7 @@
{% chart-type &quot;pie&quot; %}
{% chart-background-stripes &quot;45&quot; &quot;cccccc&quot; &quot;0.05&quot; &quot;FFFFFF&quot; &quot;0.05&quot; %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=p&amp;chf=bg,ls,45,cccccc,0.05,FFFFFF,0.05&amp;chd=e:VVqq.." width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=p&amp;chf=bg,ls,45,cccccc,0.05,FFFFFF,0.05&amp;chd=e:VVqq.." width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -88,7 +88,7 @@
{% chart-type &quot;bar&quot; %}
{% chart-bar-width 60 0 6 %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bhg&amp;chbh=60,0,6&amp;chd=e:VVqq.." width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bhg&amp;chbh=60,0,6&amp;chd=e:VVqq.." width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -109,9 +109,9 @@
{% chart-bar-width 70 6 0 %}
{% endchart %}</pre></td>
<td>
-<img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bvg&amp;chco=CC0000,0000CC&amp;chbh=30,5,10&amp;chd=e:LwQAU5ac,..3LvBng" width="300" height="200" />
+<img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bvg&amp;chco=CC0000,0000CC&amp;chbh=30,5,10&amp;chd=e:LwQAU5ac,..3LvBng" width="300" height="200" alt="" />
-<img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bvs&amp;chco=CC0000,0000CC&amp;chbh=70,6,0&amp;chd=e:LwQAU5ac,..3LvBng" width="300" height="200" /></td>
+<img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bvs&amp;chco=CC0000,0000CC&amp;chbh=70,6,0&amp;chd=e:LwQAU5ac,..3LvBng" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -125,7 +125,7 @@
{% chart-data-scale &quot;-10,250&quot; %}
{% chart-colors &quot;CC0000&quot; &quot;0000CC&quot; %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bvs&amp;chds=-10,250&amp;chco=CC0000,0000CC&amp;chd=t:36.0,49.0,64.0,81.0|196.0,169.0,144.0,121.0" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bvs&amp;chds=-10,250&amp;chco=CC0000,0000CC&amp;chd=t:36.0,49.0,64.0,81.0|196.0,169.0,144.0,121.0" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -141,7 +141,7 @@
{% chart-grid-lines-data grid_lines_data %}
{% chart-grid-lines-style grid_lines_style %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bvg&amp;chds=0,20&amp;chco=CC0000&amp;chm=D,FFFFFF,1,0,1,1|D,FFFFFF,2,0,1,1|D,FFFFFF,3,0,1,1&amp;chd=t1:0.001,2.0,6.0,14.0,18.0,0.001|5.0,5.0,5.0,5.0,5.0,5.0|10.0,10.0,10.0,10.0,10.0,10.0|15.0,15.0,15.0,15.0,15.0,15.0" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bvg&amp;chds=0,20&amp;chco=CC0000&amp;chm=D,FFFFFF,1,0,1,1|D,FFFFFF,2,0,1,1|D,FFFFFF,3,0,1,1&amp;chd=t:0.001,2.0,6.0,14.0,18.0,0.001|5.0,5.0,5.0,5.0,5.0,5.0|10.0,10.0,10.0,10.0,10.0,10.0|15.0,15.0,15.0,15.0,15.0,15.0" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -153,7 +153,7 @@
{% chart-size &quot;300x200&quot; %}
{% chart-type &quot;scatter&quot; %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=s&amp;chd=e:AAAKApBcCkEAFxH2KPM9QATXXCbCfXj.o9uPz15w,..5wz1uPo9j.fXbCXCTXQAM9KPH2FxEACkBcApAK" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=s&amp;chd=e:AAAKApBcCkEAFxH2KPM9QATXXCbCfXj.o9uPz15w,..5wz1uPo9j.fXbCXCTXQAM9KPH2FxEACkBcApAK" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -168,7 +168,7 @@
{% chart-line-style 1 1 2 %}
{% chart-grid 15 15 1 1 %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?cht=lc&amp;chs=300x200&amp;chco=CC0000,00CC00&amp;chls=3,6,3|1,1,2&amp;chg=15,15,1,1&amp;chd=e:AAAKApBcCkEAFxH2KPM9QATXXCbCfXj.o9uPz15w,..5wz1uPo9j.fXbCXCTXQAM9KPH2FxEACkBcApAK" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?cht=lc&amp;chs=300x200&amp;chco=CC0000,00CC00&amp;chls=3,6,3|1,1,2&amp;chg=15,15,1,1&amp;chd=e:AAAKApBcCkEAFxH2KPM9QATXXCbCfXj.o9uPz15w,..5wz1uPo9j.fXbCXCTXQAM9KPH2FxEACkBcApAK" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -186,7 +186,7 @@
{% endchart %}</pre></td>
<td>
-<img src="http://chart.apis.google.com/chart?cht=lc&amp;chs=300x200&amp;chm=R,E5ECF9,0,.75,.25|B,76A4FB,0,0,0&amp;chd=e:AAALAtBmC1EcGYIsLWOXRuVdZhd9ivn4tYzO5b.." width="300" height="200" /></td>
+<img src="http://chart.apis.google.com/chart?cht=lc&amp;chs=300x200&amp;chm=R,E5ECF9,0,.75,.25|B,76A4FB,0,0,0&amp;chd=e:AAALAtBmC1EcGYIsLWOXRuVdZhd9ivn4tYzO5b.." width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -200,7 +200,7 @@
{% chart-marker &quot;circle&quot; &quot;cccc0077&quot; 1 4 90 %}
{% chart-marker &quot;x&quot; &quot;0000CC&quot; 0 9.3 20 %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?cht=lc&amp;chs=300x200&amp;chco=CC0000,00CC00&amp;chm=o,cccc0077,1,4,90|x,0000CC,0,9.3,20&amp;chd=e:AAAKApBcCkEAFxH2KPM9QATXXCbCfXj.o9uPz15w,..5wz1uPo9j.fXbCXCTXQAM9KPH2FxEACkBcApAK" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?cht=lc&amp;chs=300x200&amp;chco=CC0000,00CC00&amp;chm=o,cccc0077,1,4,90|x,0000CC,0,9.3,20&amp;chd=e:AAAKApBcCkEAFxH2KPM9QATXXCbCfXj.o9uPz15w,..5wz1uPo9j.fXbCXCTXQAM9KPH2FxEACkBcApAK" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -209,7 +209,7 @@
<td><pre>{% chart %}
{% chart-data data2 data3 %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=200x200&amp;cht=lc&amp;chd=e:AAAKApBcCkEAFxH2KPM9QATXXCbCfXj.o9uPz15w,..5wz1uPo9j.fXbCXCTXQAM9KPH2FxEACkBcApAK" width="200" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=200x200&amp;cht=lc&amp;chd=e:AAAKApBcCkEAFxH2KPM9QATXXCbCfXj.o9uPz15w,..5wz1uPo9j.fXbCXCTXQAM9KPH2FxEACkBcApAK" width="200" height="200" alt="" /></td>
</tr>
<tr>
@@ -228,7 +228,7 @@
{% axis-labels &quot;Jan&quot; &quot;Feb&quot; &quot;Mar&quot; &quot;Apr&quot; %}
{% endaxis %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?cht=lc&amp;chs=300x200&amp;chm=R,E5ECF9,0,.75,.25|B,76A4FB,0,0,0&amp;chd=e:..5bzOtYn4ivd9ZhVdRuOXLWIsGYEcC1BmAtALAA&amp;chxt=y,x&amp;chxr=0,0,100&amp;chxl=1:|Jan|Feb|Mar|Apr" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?cht=lc&amp;chs=300x200&amp;chm=R,E5ECF9,0,.75,.25|B,76A4FB,0,0,0&amp;chd=e:..5bzOtYn4ivd9ZhVdRuOXLWIsGYEcC1BmAtALAA&amp;chxt=y,x&amp;chxr=0,0,100&amp;chxl=1:|Jan|Feb|Mar|Apr" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -248,7 +248,7 @@
{% axis-style &quot;000000&quot; &quot;14&quot; %}
{% endaxis %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bvg&amp;chco=CC0000,0000CC&amp;chbh=30,5,10&amp;chf=bg,ls,0,cccccc,0.25,ffffff,0.25&amp;chd=e:LwQAU5ac,..3LvBng&amp;chxt=t&amp;chxl=0:|Group+1|Group+2|Group+3|Control&amp;chxp=0,10,37,62,87&amp;chxs=0,000000,14" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=bvg&amp;chco=CC0000,0000CC&amp;chbh=30,5,10&amp;chf=bg,ls,0,cccccc,0.25,ffffff,0.25&amp;chd=e:LwQAU5ac,..3LvBng&amp;chxt=t&amp;chxl=0:|Group+1|Group+2|Group+3|Control&amp;chxp=0,10,37,62,87&amp;chxs=0,000000,14" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -260,7 +260,7 @@
{% chart-data &quot;60,30,10&quot; %}
{% chart-colors &quot;cc00ee&quot; %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=p3&amp;chco=cc00ee&amp;chd=e:..gAKr" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=p3&amp;chco=cc00ee&amp;chd=e:..gAKr" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -276,7 +276,7 @@
{% axis-labels 5 0 -5 %}
{% endaxis %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=lc&amp;chm=r,000000,0,.499,.501&amp;chd=e:gAmXsdyE296791.i...K9G541nwgqukheIX1R2MbHyEHBjANAIBUDvHRLzRIXEdWjvp-v01B5Z8w--.9.q-G7W3gyutMnIgzabUROmJnFhCeAnAAArClFrJ0O1UiathFnatcy83s7f-N.t.8-68o5O00vkptjddEWyQ4LlHGDmBPAGAPBpEQH-MpSGYGeakzq.wv116C&amp;chxt=x,y&amp;chxs=0,000000,11,0,_&amp;chxl=0:|||1:|5|0|-5" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=lc&amp;chm=r,000000,0,.499,.501&amp;chd=e:gAmXsdyE296791.i...K9G541nwgqukheIX1R2MbHyEHBjANAIBUDvHRLzRIXEdWjvp-v01B5Z8w--.9.q-G7W3gyutMnIgzabUROmJnFhCeAnAAArClFrJ0O1UiathFnatcy83s7f-N.t.8-68o5O00vkptjddEWyQ4LlHGDmBPAGAPBpEQH-MpSGYGeakzq.wv116C&amp;chxt=x,y&amp;chxs=0,000000,11,0,_&amp;chxl=0:|||1:|5|0|-5" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -292,7 +292,7 @@
{% axis &quot;bottom&quot; hide %}
{% chart-range-marker &quot;h&quot; &quot;000000&quot; 1 .997 %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=lc&amp;chm=r,000000,0,1,0.997&amp;chd=e:5lf.AA&amp;chxt=y,x&amp;chxr=0,-10,0&amp;chxs=1,000000,11,0,_&amp;chxl=1:||" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=lc&amp;chm=r,000000,0,1,0.997&amp;chd=e:5lf.AA&amp;chxt=y,x&amp;chxr=0,-10,0&amp;chxs=1,000000,11,0,_&amp;chxl=1:||" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -311,7 +311,7 @@
{% axis-labels 10 0 -10 %}
{% endaxis %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=lc&amp;chco=00cc00&amp;chls=4&amp;chm=r,000000,0,.499,.501&amp;chd=e:gAjLmOpCretdu6vwv.vkuis7qzoPlWiQfEb6Y6WNT5SDQxQGQEQqR3ToV5Ykbheqh3k-n5qgssuYvev-v0vDtqrvpWmljkgZdNaIXTUzSwRPQTQAQVRSS1U6XaaRdWgijtmuper1tvvGv2v9vcuUsmqZnxk2huehbZYcVyTjRzQnQDQHQ0SIT.WUZDcDfNiZlfoXq6tA&amp;chxt=x,y&amp;chxs=0,000000,11,0,_&amp;chxl=0:|||1:|10|0|-10" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=lc&amp;chco=00cc00&amp;chls=4&amp;chm=r,000000,0,.499,.501&amp;chd=e:gAjLmOpCretdu6vwv.vkuis7qzoPlWiQfEb6Y6WNT5SDQxQGQEQqR3ToV5Ykbheqh3k-n5qgssuYvev-v0vDtqrvpWmljkgZdNaIXTUzSwRPQTQAQVRSS1U6XaaRdWgijtmuper1tvvGv2v9vcuUsmqZnxk2huehbZYcVyTjRzQnQDQHQ0SIT.WUZDcDfNiZlfoXq6tA&amp;chxt=x,y&amp;chxs=0,000000,11,0,_&amp;chxl=0:|||1:|10|0|-10" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -333,7 +333,7 @@
{% endchart %}</pre></td>
<td>
-<img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=lc&amp;chco=0000cc&amp;chls=2,2,2&amp;chm=r,000000,0,.499,.501&amp;chd=e:6C11wvq.kzeaYGSGMpH-EQBpAPAGBPDmHGLlQ4WydEjdptvk005O8o-6.8.t-N7f3sy8tcnahFatUiO1J0FrClArAAAnCeFhJnOmURabgznItMyu3g7W-G.q.9--8w5Z1Bv0p-jvdWXERILzHRDvBUAIANBjEHHyMbR2X1eIkhquwg1n549G.K...i916729yEsdmXgA&amp;chxt=x&amp;chxs=0,000000,11,0,_&amp;chxl=0:||" width="300" height="200" /></td>
+<img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=lc&amp;chco=0000cc&amp;chls=2,2,2&amp;chm=r,000000,0,.499,.501&amp;chd=e:6C11wvq.kzeaYGSGMpH-EQBpAPAGBPDmHGLlQ4WydEjdptvk005O8o-6.8.t-N7f3sy8tcnahFatUiO1J0FrClArAAAnCeFhJnOmURabgznItMyu3g7W-G.q.9--8w5Z1Bv0p-jvdWXERILzHRDvBUAIANBjEHHyMbR2X1eIkhquwg1n549G.K...i916729yEsdmXgA&amp;chxt=x&amp;chxs=0,000000,11,0,_&amp;chxl=0:||" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -345,7 +345,7 @@
{% chart-type &quot;pie&quot; %}
{% chart-labels data1 %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=p&amp;chl=10|20|30&amp;chd=e:VVqq.." width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=p&amp;chl=10|20|30&amp;chd=e:VVqq.." width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -357,7 +357,7 @@
{% chart-type &quot;pie&quot; %}
{% chart-title &quot;Pie!&quot; 18 &quot;cc0000&quot; %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=p&amp;chts=cc0000,18&amp;chtt=Pie%21&amp;chd=e:VVqq.." width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=p&amp;chts=cc0000,18&amp;chtt=Pie%21&amp;chd=e:VVqq.." width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -369,7 +369,7 @@
{% chart-type &quot;pie&quot; %}
{% chart-pie-orientation &quot;4.7&quot; %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=p&amp;chp=4.7&amp;chd=e:VVqq.." width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=300x200&amp;cht=p&amp;chp=4.7&amp;chd=e:VVqq.." width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -382,7 +382,7 @@
{% chart-data-scale &quot;0,10&quot; %}
{% chart-data &quot;5&quot; %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chl=head&amp;chs=300x200&amp;cht=gom&amp;chds=0,10&amp;chd=t:5.0" width="300" height="200" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chl=head&amp;chs=300x200&amp;cht=gom&amp;chds=0,10&amp;chd=t:5.0" width="300" height="200" alt="" /></td>
</tr>
<tr>
@@ -395,7 +395,7 @@
{% chart-map-data mapdata %}
{% chart-colors &quot;ffffff&quot; &quot;ff0000&quot; &quot;0000ff&quot; %}
{% endchart %}</pre></td>
- <td><img src="http://chart.apis.google.com/chart?chs=440x220&amp;cht=t&amp;chtm=usa&amp;chld=KSCAMN&amp;chco=ffffff,ff0000,0000ff&amp;chd=e:AA..gA" width="440" height="220" /></td>
+ <td><img src="http://chart.apis.google.com/chart?chs=440x220&amp;cht=t&amp;chtm=usa&amp;chld=KSCAMN&amp;chco=ffffff,ff0000,0000ff&amp;chd=e:AA..gA" width="440" height="220" alt="" /></td>
</tr>
</tbody>
View
4 docs/render-examples.py
@@ -9,7 +9,7 @@
from math import sin
from django import template
from docutils.core import publish_parts
-from lxml import etree
+from xml.etree import ElementTree as etree
from unipath import FSPath as Path
def render_examples():
@@ -27,7 +27,7 @@ def render_examples():
source = Path(__file__).parent.child("examples.txt").read_file()
published = publish_parts(source, writer_name="xml", settings_overrides={"xml_declaration": False})
tree = etree.fromstring(published["whole"])
- for section in tree.xpath("//section"):
+ for section in tree.findall("section"):
title = section.find("title").text
chart = section.find("literal_block").text
t = template.Template("{% load charts %}" + chart)
View
884 googlecharts/templatetags/charts.py
@@ -63,32 +63,32 @@ def sparkline(data, size="100x30", color=_chart_color):
@register.tag
def chart(parser, token):
- bits = iter(token.split_contents())
- name = bits.next()
- varname = None
- saveas = None
- extends = None
- for bit in bits:
- if bit == "as":
- varname = bits.next()
- elif bit == "saveas":
- raise template.TemplateSyntaxError("Sorry, 'saveas' isn't implemented yet!")
- saveas = template.Variable(bits.next())
- elif bit == "extends":
- extends = template.Variable(bits.next())
- else:
- raise template.TemplateSyntaxError("Unknown argument to '%s': '%s'" % (name, bit))
- nodelist = parser.parse("end%s" % name)
- parser.delete_first_token()
- return ChartNode(nodelist, varname, saveas, extends)
+ bits = iter(token.split_contents())
+ name = bits.next()
+ varname = None
+ saveas = None
+ extends = None
+ for bit in bits:
+ if bit == "as":
+ varname = bits.next()
+ elif bit == "saveas":
+ raise template.TemplateSyntaxError("Sorry, 'saveas' isn't implemented yet!")
+ saveas = template.Variable(bits.next())
+ elif bit == "extends":
+ extends = template.Variable(bits.next())
+ else:
+ raise template.TemplateSyntaxError("Unknown argument to '%s': '%s'" % (name, bit))
+ nodelist = parser.parse("end%s" % name)
+ parser.delete_first_token()
+ return ChartNode(nodelist, varname, saveas, extends)
class ChartNode(template.Node):
- def __init__(self, nodelist, varname, saveas, extends):
- self.nodelist = nodelist
- self.saveas = saveas
- self.varname = varname
- self.extends = extends
+ def __init__(self, nodelist, varname, saveas, extends):
+ self.nodelist = nodelist
+ self.saveas = saveas
+ self.varname = varname
+ self.extends = extends
def render(self, context):
c = Chart()
@@ -120,19 +120,19 @@ def render(self, context):
for o in c.options['_final_color_map'].items():
context["chart_%s_only" % o[1]] = c.img(color_override=o[0])
- if self.varname:
- context[self.varname] = c
- return ""
- else:
- return c.img()
+ if self.varname:
+ context[self.varname] = c
+ return ""
+ else:
+ return c.img()
class Chart(object):
- BASE = "http://chart.apis.google.com/chart"
- defaults = {
- "chs": "200x200",
- "cht": "lc"
- }
+ BASE = "http://chart.apis.google.com/chart"
+ defaults = {
+ "chs": "200x200",
+ "cht": "lc"
+ }
def __init__(self):
# Use a SortedDict for the options so they are added in a
@@ -144,12 +144,12 @@ def __init__(self):
self.datarange = None
self.alt = None
- def clone(self):
- clone = self.__class__()
- clone.options = self.options.copy()
- clone.datasets = self.datasets[:]
- clone.axes = self.axes[:]
- return clone
+ def clone(self):
+ clone = self.__class__()
+ clone.options = self.options.copy()
+ clone.datasets = self.datasets[:]
+ clone.axes = self.axes[:]
+ return clone
def img(self, color_override = None):
orig_colors = self.options.get('chco')
@@ -175,9 +175,9 @@ def img(self, color_override = None):
return s
- def url(self):
- if self.options.get('cht', None) == 't':
- self.datasets.append(self.options.pop("_mapdata"))
+ def url(self):
+ if self.options.get('cht', None) == 't':
+ self.datasets.append(self.options.pop("_mapdata"))
# Figure out the chart's data range
if not self.datarange:
@@ -243,207 +243,207 @@ def charts(self):
@register.tag(name="chart-data")
def chart_data(parser, token):
- bits = iter(token.split_contents())
- name = bits.next()
- datasets = map(parser.compile_filter, bits)
- return ChartDataNode(datasets, "chart-data")
+ bits = iter(token.split_contents())
+ name = bits.next()
+ datasets = map(parser.compile_filter, bits)
+ return ChartDataNode(datasets, "chart-data")
@register.tag("chart-grid-lines-data")
def chart_grid_lines_data(parser, token):
- """
- An alternative method for providing data, intended to allow
- for the creation of fake line series that will simulate a
- grid-line drawn *on top* of the other data series.
-
- Unfortunately, this is necessary because the tick marks and
- range markets supported by the API do not--as far I can tell--
- allow for the guides to be drawn on top of the data.
- """
- bits = iter(token.split_contents())
- name = bits.next()
- data_obj = map(parser.compile_filter, bits)
- return ChartDataNode(data_obj, "chart-grid-lines-data")
+ """
+ An alternative method for providing data, intended to allow
+ for the creation of fake line series that will simulate a
+ grid-line drawn *on top* of the other data series.
+
+ Unfortunately, this is necessary because the tick marks and
+ range markets supported by the API do not--as far I can tell--
+ allow for the guides to be drawn on top of the data.
+ """
+ bits = iter(token.split_contents())
+ name = bits.next()
+ data_obj = map(parser.compile_filter, bits)
+ return ChartDataNode(data_obj, "chart-grid-lines-data")
class ChartDataNode(template.Node):
- def __init__(self, datasets, type):
- self.datasets = datasets
- self.type = type
-
- def resolve(self, context):
- resolved = []
-
- # If the data is provided by the {% chart-data %} tag ...
- if self.type == 'chart-data':
- for data in self.datasets:
- try:
- data = data.resolve(context)
- except template.VariableDoesNotExist:
- data = []
-
- # XXX need different ways of representing pre-encoded data, data with
- # different separators, etc.
- if isinstance(data, basestring):
- data = filter(None, map(safefloat, data.split(",")))
- else:
- # I don't understand why you would remove zero values, as this does?
- # I'm going to comment it out and use my own version
- # data = filter(None, map(safefloat, data))
- data = map(safefloat, data)
- resolved.append(data)
-
- # If the data is provided by the {% chart-grid-lines-data %} tag ...
- elif self.type == 'chart-grid-lines-data':
- for data in self.datasets:
- data = data.resolve(context)
-
- # Since this variable can contain multiple lists,
- # We'll add an extra loop that doesn't exist above.
- for series in data:
-
- # Split the tuple
- value_count, value = series
- # Extend the series to the length of the count
- series = [value] * value_count
-
- # Conduct the same filtering as above
- if isinstance(data, basestring):
- series = filter(None, map(safefloat, series.split(",")))
- else:
- series = map(safefloat, series)
-
- # And if there's anything there ...
- if series:
- # Add it to the final set
- resolved.append(series)
-
-
- return resolved
-
- def render(self, context):
- return ""
+ def __init__(self, datasets, type):
+ self.datasets = datasets
+ self.type = type
+
+ def resolve(self, context):
+ resolved = []
+
+ # If the data is provided by the {% chart-data %} tag ...
+ if self.type == 'chart-data':
+ for data in self.datasets:
+ try:
+ data = data.resolve(context)
+ except template.VariableDoesNotExist:
+ data = []
+
+ # XXX need different ways of representing pre-encoded data, data with
+ # different separators, etc.
+ if isinstance(data, basestring):
+ data = filter(None, map(safefloat, data.split(",")))
+ else:
+ # I don't understand why you would remove zero values, as this does?
+ # I'm going to comment it out and use my own version
+ # data = filter(None, map(safefloat, data))
+ data = map(safefloat, data)
+ resolved.append(data)
+
+ # If the data is provided by the {% chart-grid-lines-data %} tag ...
+ elif self.type == 'chart-grid-lines-data':
+ for data in self.datasets:
+ data = data.resolve(context)
+
+ # Since this variable can contain multiple lists,
+ # We'll add an extra loop that doesn't exist above.
+ for series in data:
+
+ # Split the tuple
+ value_count, value = series
+ # Extend the series to the length of the count
+ series = [value] * value_count
+
+ # Conduct the same filtering as above
+ if isinstance(data, basestring):
+ series = filter(None, map(safefloat, series.split(",")))
+ else:
+ series = map(safefloat, series)
+
+ # And if there's anything there ...
+ if series:
+ # Add it to the final set
+ resolved.append(series)
+
+
+ return resolved
+
+ def render(self, context):
+ return ""
#
# Chart options
#
class OptionNode(template.Node):
- def __init__(self, callback, args, multi=None):
- self.callback = callback
- self.args = args
- self.multi = multi
-
- def render(self, context):
- return ""
-
- def resolve_arguments(self, context):
- for arg in self.args:
- try:
- yield arg.resolve(context)
- except template.VariableDoesNotExist:
- yield None
-
- def update_options(self, options, context):
- data = self.callback(*self.resolve_arguments(context))
- if self.multi:
- for key in data:
- if key in options:
- options[key] = options[key] + self.multi + data[key]
- else:
- options[key] = data[key]
- else:
- options.update(data)
+ def __init__(self, callback, args, multi=None):
+ self.callback = callback
+ self.args = args
+ self.multi = multi
+
+ def render(self, context):
+ return ""
+
+ def resolve_arguments(self, context):
+ for arg in self.args:
+ try:
+ yield arg.resolve(context)
+ except template.VariableDoesNotExist:
+ yield None
+
+ def update_options(self, options, context):
+ data = self.callback(*self.resolve_arguments(context))
+ if self.multi:
+ for key in data:
+ if key in options:
+ options[key] = options[key] + self.multi + data[key]
+ else:
+ options[key] = data[key]
+ else:
+ options.update(data)
class ChartOptionNode(OptionNode):
- def update_chart(self, chart, context):
- self.update_options(chart.options, context)
-
+ def update_chart(self, chart, context):
+ self.update_options(chart.options, context)
+
class AxisOptionNode(OptionNode):
- pass
+ pass
def option(tagname, multi=None, nodeclass=ChartOptionNode):
- """
- Decorator-helper to register a chart-foo option tag. The decorated function
- will be called at resolution time with the proper arity (determined from
- inspecting the decorated function). This callback should return a dictionary
- which will be used as arguments in the chart URL.
- """
- def decorator(func):
- # Figure out how to validate the args to the tag
- args, varargs, varkw, defaults = inspect.getargspec(func)
- max_args = min_args = 0
- if args:
- max_args = len(args)
- if defaults:
- min_args = max_args - len(defaults)
- unlimited = bool(varargs)
-
- def template_tag_callback(parser, token):
- bits = iter(token.split_contents())
- name = bits.next()
- args = map(template.Variable, bits)
-
- if not unlimited and len(args) < min_args:
- raise template.TemplateSyntaxError("Too few arguments to '%s'" % name)
- if not unlimited and len(args) > max_args:
- raise template.TemplateSyntaxError("Too many arguments to '%s'" % name)
-
- return nodeclass(func, args, multi)
- template_tag_callback.__name__ = func.__name__
- template_tag_callback.__doc__ = func.__doc__
- register.tag(tagname, template_tag_callback)
- return func
-
- return decorator
+ """
+ Decorator-helper to register a chart-foo option tag. The decorated function
+ will be called at resolution time with the proper arity (determined from
+ inspecting the decorated function). This callback should return a dictionary
+ which will be used as arguments in the chart URL.
+ """
+ def decorator(func):
+ # Figure out how to validate the args to the tag
+ args, varargs, varkw, defaults = inspect.getargspec(func)
+ max_args = min_args = 0
+ if args:
+ max_args = len(args)
+ if defaults:
+ min_args = max_args - len(defaults)
+ unlimited = bool(varargs)
+
+ def template_tag_callback(parser, token):
+ bits = iter(token.split_contents())
+ name = bits.next()
+ args = map(template.Variable, bits)
+
+ if not unlimited and len(args) < min_args:
+ raise template.TemplateSyntaxError("Too few arguments to '%s'" % name)
+ if not unlimited and len(args) > max_args:
+ raise template.TemplateSyntaxError("Too many arguments to '%s'" % name)
+
+ return nodeclass(func, args, multi)
+ template_tag_callback.__name__ = func.__name__
+ template_tag_callback.__doc__ = func.__doc__
+ register.tag(tagname, template_tag_callback)
+ return func
+
+ return decorator
@option("chart-type")
def chart_type(arg):
- """
- Set the chart type. Valid arguments are anything the chart API understands,
- or the following human-readable alternates:
-
- * 'line'
- * 'xy'
- * 'xy' / 'line-xy'
- * 'bar' / 'bar-grouped'
- * 'column' / 'column-grouped'
- * 'bar-stacked'
- * 'column-stacked'
- * 'pie'
- * 'pie-3d'
- * 'venn'
- * 'scatter'
- * 'map'
-
- """
- types = {
- 'line': 'lc',
- 'sparkline': 'ls',
- 'xy': 'lxy',
- 'line-xy': 'lxy',
- 'bar': 'bhg',
- 'column': 'bvg',
- 'bar-stacked': 'bhs',
- 'column-stacked': 'bvs',
- 'bar-grouped': 'bhg',
- 'column-grouped': 'bvg',
- 'pie': 'p',
- 'pie-3d': 'p3',
- 'venn': 'v',
- 'scatter': 's',
- 'google-o-meter': 'gom',
- 'map': 't',
- }
- return {"cht": types.get(arg, arg)}
+ """
+ Set the chart type. Valid arguments are anything the chart API understands,
+ or the following human-readable alternates:
+
+ * 'line'
+ * 'xy'
+ * 'xy' / 'line-xy'
+ * 'bar' / 'bar-grouped'
+ * 'column' / 'column-grouped'
+ * 'bar-stacked'
+ * 'column-stacked'
+ * 'pie'
+ * 'pie-3d'
+ * 'venn'
+ * 'scatter'
+ * 'map'
+
+ """
+ types = {
+ 'line': 'lc',
+ 'sparkline': 'ls',
+ 'xy': 'lxy',
+ 'line-xy': 'lxy',
+ 'bar': 'bhg',
+ 'column': 'bvg',
+ 'bar-stacked': 'bhs',
+ 'column-stacked': 'bvs',
+ 'bar-grouped': 'bhg',
+ 'column-grouped': 'bvg',
+ 'pie': 'p',
+ 'pie-3d': 'p3',
+ 'venn': 'v',
+ 'scatter': 's',
+ 'google-o-meter': 'gom',
+ 'map': 't',
+ }
+ return {"cht": types.get(arg, arg)}
@option("chart-data-scale", multi=",")
def chart_data_scale(*args):
- return {"chds": smart_join(",", *args)}
+ return {"chds": smart_join(",", *args)}
@option("chart-colors", multi=",")
def chart_colors(*args):
- return {"chco": smart_join(",", *args)}
+ return {"chco": smart_join(",", *args)}
@option("chart-bar-colors", multi="|")
def chart_bar_colors(*args):
@@ -519,193 +519,193 @@ def chart_auto_colors(color, item_label_list):
@option("chart-size")
def chart_size(arg1, arg2=None):
- if arg2:
- return {"chs": smart_join("x", arg1, arg2)}
- else:
- return {"chs": arg1}
+ if arg2:
+ return {"chs": smart_join("x", arg1, arg2)}
+ else:
+ return {"chs": arg1}
@option("chart-background", multi="|")
def chart_background(color):
- return _solid("bg", color)
+ return _solid("bg", color)
@option("chart-fill", multi="|")
def chart_fill(color):
- return _solid("c", color)
-
+ return _solid("c", color)
+
def _solid(type, color):
- return {"chf": "%s,s,%s" % (type, color)}
+ return {"chf": "%s,s,%s" % (type, color)}
@option("chart-background-gradient", multi="|")
def chart_background_gradient(angle, *colors):
- return _fancy_background("bg", "lg", angle, colors)
-
+ return _fancy_background("bg", "lg", angle, colors)
+
@option("chart-fill-gradient", multi="|")
def chart_fill_gradient(angle, *colors):
- return _fancy_background("c", "lg", angle, colors)
+ return _fancy_background("c", "lg", angle, colors)
@option("chart-background-stripes", multi="|")
def chart_background_stripes(angle, *colors):
- return _fancy_background("bg", "ls", angle, colors)
-
+ return _fancy_background("bg", "ls", angle, colors)
+
@option("chart-fill-stripes", multi="|")
def chart_fill_stripes(angle, *colors):
- return _fancy_background("c", "ls", angle, colors)
-
+ return _fancy_background("c", "ls", angle, colors)
+
def _fancy_background(bgtype, fancytype, angle, colors):
- return {"chf": smart_join(",", bgtype, fancytype, angle, *colors)}
+ return {"chf": smart_join(",", bgtype, fancytype, angle, *colors)}
@option("chart-title")
def chart_title(title, fontsize=None, color="000000"):
- title = title.replace("\n", "|")
- if fontsize:
- return {"chtt":title, "chts":"%s,%s" % (color, fontsize)}
- else:
- return {"chtt": title}
+ title = title.replace("\n", "|")
+ if fontsize:
+ return {"chtt":title, "chts":"%s,%s" % (color, fontsize)}
+ else:
+ return {"chtt": title}
@option("chart-legend", multi="|")
def chart_legend(*labels):
- return {"chdl": smart_join("|", *flatten(labels))}
+ return {"chdl": smart_join("|", *flatten(labels))}
@option("chart-pie-orientation")
def chart_pie_orientation(radians):
- return {"chp": radians}
+ return {"chp": radians}
@option("chart-labels", multi="|")
def chart_labels(*labels):
- return {"chl": smart_join("|", *flatten(labels))}
+ return {"chl": smart_join("|", *flatten(labels))}
@option("chart-bar-width")
def chart_bar_width(width, barspace=None, groupspace=None):
- return {"chbh": smart_join(",", width, barspace, groupspace)}
+ return {"chbh": smart_join(",", width, barspace, groupspace)}
@option("chart-line-style", multi="|")
def chart_line_style(thickness, line_length=None, space_length=None):
- return {"chls": smart_join(",", thickness, line_length, space_length)}
+ return {"chls": smart_join(",", thickness, line_length, space_length)}
@option("chart-grid")
def chart_grid(xstep, ystep, line_length=None, space_length=None):
- return {"chg": smart_join(",", xstep, ystep, line_length, space_length)}
+ return {"chg": smart_join(",", xstep, ystep, line_length, space_length)}
rangetypes = {
- "h": "r",
- "horiz": "r",
- "horizontal": "r",
- "v": "R",
- "vert": "R",
- "vertical": "R",
+ "h": "r",
+ "horiz": "r",
+ "horizontal": "r",
+ "v": "R",
+ "vert": "R",
+ "vertical": "R",
}
@option("chart-range-marker", multi="|")
def chart_range_marker(range_type, color, start, end):
- rt = rangetypes.get(range_type, range_type)
- return {"chm": smart_join(",", rt, color, "0", start, end)}
+ rt = rangetypes.get(range_type, range_type)
+ return {"chm": smart_join(",", rt, color, "0", start, end)}
@option("chart-fill-area", multi="|")
def chart_fill_area(color, startindex=0, endindex=0):
- if startindex or endindex:
- filltype = "b"
- else:
- filltype = "B"
- return {"chm": smart_join(",", filltype, color, startindex, endindex, "0")}
+ if startindex or endindex:
+ filltype = "b"
+ else:
+ filltype = "B"
+ return {"chm": smart_join(",", filltype, color, startindex, endindex, "0")}
marker_types = {
- 'arrow': 'a',
- 'cross': 'c',
- 'diamond': 'd',
- 'circle': 'o',
- 'square': 's',
- 'line': 'v',
- 'full-line': 'V',
- 'h-line': 'h',
- 'horiz-line': 'h',
- 'horizontal-line': 'h',
+ 'arrow': 'a',
+ 'cross': 'c',
+ 'diamond': 'd',
+ 'circle': 'o',
+ 'square': 's',
+ 'line': 'v',
+ 'full-line': 'V',
+ 'h-line': 'h',
+ 'horiz-line': 'h',
+ 'horizontal-line': 'h',
}
@option("chart-marker", multi="|")
def chart_marker(marker, color, dataset_index, data_point, size):
- marker = marker_types.get(marker, marker)
- return {"chm": smart_join(",", marker, color, dataset_index, data_point, size)}
+ marker = marker_types.get(marker, marker)
+ return {"chm": smart_join(",", marker, color, dataset_index, data_point, size)}
@option("chart-grid-lines-style", multi="|")
def chart_grid_lines_style(iterable):
- """
- Set the style for fake grid lines.
-
- Provide an iterable yielding (color, dataset_index, size)
- """
- try:
- it = iter(iterable)
- except TypeError:
- return {}
-
- labels = []
- for m in it:
- try:
- color, dataset_index, size = m
- except ValueError:
- continue
- labels.append(smart_join(",", 'D', color, dataset_index, 0, size, 1))
- if labels:
- return {"chm": smart_join("|", *flatten(labels))}
- else:
- return {}
+ """
+ Set the style for fake grid lines.
+
+ Provide an iterable yielding (color, dataset_index, size)
+ """
+ try:
+ it = iter(iterable)
+ except TypeError:
+ return {}
+
+ labels = []
+ for m in it:
+ try:
+ color, dataset_index, size = m
+ except ValueError:
+ continue
+ labels.append(smart_join(",", 'D', color, dataset_index, 0, size, 1))
+ if labels:
+ return {"chm": smart_join("|", *flatten(labels))}
+ else:
+ return {}
@option("chart-markers", multi="|")
def chart_markers(dataset_index, iterable):
- """
- Provide an iterable yielding (type, color, point, size)
- """
- try:
- it = iter(iterable)
- except TypeError:
- return {}
-
- markers = []
- for m in it:
- try:
- marker, color, data_point, size = m
- except ValueError:
- continue
- marker = marker_types.get(marker, marker)
- markers.append(smart_join(",", marker, color, dataset_index, data_point, size))
-
- return {"chm": smart_join("|", *flatten(markers))}
+ """
+ Provide an iterable yielding (type, color, point, size)
+ """
+ try:
+ it = iter(iterable)
+ except TypeError:
+ return {}
+
+ markers = []
+ for m in it:
+ try:
+ marker, color, data_point, size = m
+ except ValueError:
+ continue
+ marker = marker_types.get(marker, marker)
+ markers.append(smart_join(",", marker, color, dataset_index, data_point, size))
+
+ return {"chm": smart_join("|", *flatten(markers))}
label_types = {
- 'flag': 'f',
- 'text': 't',
- 'number': 'N',
+ 'flag': 'f',
+ 'text': 't',
+ 'number': 'N',
}
@option("data-point-labels", multi="|")
def data_point_labels(dataset_index, iterable):
- """
- Adds data labels as described here: http://code.google.com/apis/chart/labels.html#data_point_labels
-
- You will need to provide an iterable yielding (label_type, label_contents, color, data_point, size, priority)
-
- And keep in mind that flags and text labels require a very different `label_contents` than a set of numbers.
- """
- try:
- it = iter(iterable)
- except TypeError:
- return {}
-
- labels = []
- for m in it:
- try:
- label_type, label_contents, color, data_point, size, priority = m
- except ValueError:
- continue
- label = label_types.get(label_type, label_type)
- labels.append(smart_join(",", label + label_contents, color, dataset_index, data_point, size, priority))
- return {"chm": smart_join("|", *flatten(labels))}
+ """
+ Adds data labels as described here: http://code.google.com/apis/chart/labels.html#data_point_labels
+
+ You will need to provide an iterable yielding (label_type, label_contents, color, data_point, size, priority)
+
+ And keep in mind that flags and text labels require a very different `label_contents` than a set of numbers.
+ """
+ try:
+ it = iter(iterable)
+ except TypeError:
+ return {}
+
+ labels = []
+ for m in it:
+ try:
+ label_type, label_contents, color, data_point, size, priority = m
+ except ValueError:
+ continue
+ label = label_types.get(label_type, label_type)
+ labels.append(smart_join(",", label + label_contents, color, dataset_index, data_point, size, priority))
+ return {"chm": smart_join("|", *flatten(labels))}
@option("chart-map-area")
def chart_map_area(where):
- return {'chtm': where}
-
+ return {'chtm': where}
+
@option("chart-map-data")
def chart_map_data(data):
place_list = []
@@ -723,57 +723,57 @@ def chart_map_data(data):
#
@register.tag
def axis(parser, token):
- bits = token.split_contents()
-
- if len(bits) == 2:
- # {% axis <side> %} ... {% endaxis %}
- name, side = bits
- nodelist = parser.parse("end%s" % name)
- parser.delete_first_token()
- return AxisNode(template.Variable(side), nodelist)
-
- elif len(bits) == 3:
- # {% axis <side> hide %}
- name, side = bits[0:2]
- if bits[2].lower() != "hide":
- raise template.TemplateSyntaxError("%s tag expected 'hide' as last argument" % name)
- return NoAxisNode(template.Variable(side))
-
- else:
- raise template.TemplateSyntaxError("axis tag takes one or two arguments")
+ bits = token.split_contents()
+
+ if len(bits) == 2:
+ # {% axis <side> %} ... {% endaxis %}
+ name, side = bits
+ nodelist = parser.parse("end%s" % name)
+ parser.delete_first_token()
+ return AxisNode(template.Variable(side), nodelist)
+
+ elif len(bits) == 3:
+ # {% axis <side> hide %}
+ name, side = bits[0:2]
+ if bits[2].lower() != "hide":
+ raise template.TemplateSyntaxError("%s tag expected 'hide' as last argument" % name)
+ return NoAxisNode(template.Variable(side))
+
+ else:
+ raise template.TemplateSyntaxError("axis tag takes one or two arguments")
class AxisNode(template.Node):
-
- sides = {
- 'left': 'y',
- 'right': 'r',
- 'top': 't',
- 'bottom': 'x',
- }
-
- def __init__(self, side, nodelist=None):
- self.side = side
- self.nodelist = nodelist
-
- def render(self, context):
- return ''
-
- def resolve(self, context):
- axis = self.get_axis(context)
- for node in self.nodelist:
- if isinstance(node, AxisOptionNode):
- node.update_options(axis.options, context)
-
- return axis
-
- def get_axis(self, context):
- try:
- side = self.side.resolve(context)
- except template.VariableDoesNotExist:
- return None
- side = self.sides.get(side, side)
- return Axis(side)
-
+
+ sides = {
+ 'left': 'y',
+ 'right': 'r',
+ 'top': 't',
+ 'bottom': 'x',
+ }
+
+ def __init__(self, side, nodelist=None):
+ self.side = side
+ self.nodelist = nodelist
+
+ def render(self, context):
+ return ''
+
+ def resolve(self, context):
+ axis = self.get_axis(context)
+ for node in self.nodelist:
+ if isinstance(node, AxisOptionNode):
+ node.update_options(axis.options, context)
+
+ return axis
+
+ def get_axis(self, context):
+ try:
+ side = self.side.resolve(context)
+ except template.VariableDoesNotExist:
+ return None
+ side = self.sides.get(side, side)
+ return Axis(side)
+
class NoAxisNode(AxisNode):
def resolve(self, context):
a = self.get_axis(context)
@@ -782,69 +782,69 @@ def resolve(self, context):
return a
class Axis(object):
- def __init__(self, side):
- self.side = side
- self.options = SortedDict()
-
+ def __init__(self, side):
+ self.side = side
+ self.options = SortedDict()
+
# Axis options use %s placeholders for the axis index; this gets
# filled in by Chart.url()
@option("axis-labels", nodeclass=AxisOptionNode)
def axis_labels(*labels):
- return {"chxl": "%s:|" + smart_join("|", *flatten(labels))}
-
+ return {"chxl": "%s:|" + smart_join("|", *flatten(labels))}
+
@option("axis-label-positions", nodeclass=AxisOptionNode)
def axis_label_position(*positions):
- return {"chxp": smart_join(",", "%s", *flatten(positions))}
-
+ return {"chxp": smart_join(",", "%s", *flatten(positions))}
+
@option("axis-range", nodeclass=AxisOptionNode)
def axis_range(start, end):
- return {"chxr": "%%s,%s,%s" % (start, end)}
+ return {"chxr": "%%s,%s,%s" % (start, end)}
alignments = {
- 'left': -1,
- 'right': 1,
- 'center': 0,
+ 'left': -1,
+ 'right': 1,
+ 'center': 0,
}
@option("axis-style", nodeclass=AxisOptionNode)
def axis_style(color, font_size=None, alignment=None):
- alignment = alignments.get(alignment, alignment)
- return {"chxs": smart_join(",", "%s", color, font_size, alignment)}
+ alignment = alignments.get(alignment, alignment)
+ return {"chxs": smart_join(",", "%s", color, font_size, alignment)}
@option("axis-tick-length", nodeclass=AxisOptionNode)
def axis_range(length):
- return {"chxtc": "%%s,%s" % (length)}
+ return {"chxtc": "%%s,%s" % (length)}
#
# "Metadata" nodes
#
class MetadataNode(ChartOptionNode):
- def update_chart(self, chart, context):
- self.callback(chart, *self.resolve_arguments(context))
-
+ def update_chart(self, chart, context):
+ self.callback(chart, *self.resolve_arguments(context))
+
@option("chart-data-range", nodeclass=MetadataNode)
def chart_data_range(chart, lower=None, upper=None):
- if lower and upper:
- try:
- map(float, (lower, upper))
- except ValueError:
- return
- chart.datarange = (lower, upper)
- elif lower == "auto":
- chart.datarange = None
+ if lower and upper:
+ try:
+ map(float, (lower, upper))
+ except ValueError:
+ return
+ chart.datarange = (lower, upper)
+ elif lower == "auto":
+ chart.datarange = None
@option("chart-alt", nodeclass=MetadataNode)
def chart_alt(chart, alt=None):
- chart.alt = alt
-
+ chart.alt = alt
+
@option("chart-grid-lines", nodeclass=MetadataNode)
def chart_grid_lines(chart):
- """
- Indicates that you intended to provide fake grid line data.
- """
- chart.grid_lines = True
+ """
+ Indicates that you intended to provide fake grid line data.
+ """
+ chart.grid_lines = True
#
# Helper functions
@@ -852,39 +852,39 @@ def chart_grid_lines(chart):
extended_separator = ","
def encode_text(values):
- return extended_separator.join(str(v) for v in values)
+ return extended_separator.join(str(v) for v in values)
def encode_extended(values, value_range):
- """Encode data using Google's "extended" encoding for the most granularity."""
- return "".join(num2chars(v, value_range) for v in values)
+ """Encode data using Google's "extended" encoding for the most granularity."""
+ return "".join(num2chars(v, value_range) for v in values)
_encoding_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-."
_num2chars = [a+b for a in _encoding_chars for b in _encoding_chars]
def num2chars(n, value_range):
- if n is not None:
- return _num2chars[norm(n, value_range)]
- else:
- return '__'
-
+ if n is not None:
+ return _num2chars[norm(n, value_range)]
+ else:
+ return '__'
+
def norm(n, value_range):
- minvalue, maxvalue = value_range
- if minvalue >= 0:
- return int(round(float(n) / maxvalue * 4095, 0))
- elif maxvalue <= 0:
- return 4095 - int(round(float(n) * 4095 / minvalue))
- else:
- return int(round((n - minvalue) * (float(4095) / (maxvalue - minvalue))))
+ minvalue, maxvalue = value_range
+ if minvalue >= 0:
+ return int(round(float(n) / maxvalue * 4095, 0))
+ elif maxvalue <= 0:
+ return 4095 - int(round(float(n) * 4095 / minvalue))
+ else:
+ return int(round((n - minvalue) * (float(4095) / (maxvalue - minvalue))))
def safefloat(n):
- try:
- return float(n)
- except (TypeError, ValueError):
- return None
-
+ try:
+ return float(n)
+ except (TypeError, ValueError):
+ return None
+
def smart_join(sep, *args):
- return sep.join(smart_str(s, errors="ignore") for s in args if s is not None)
-
+ return sep.join(smart_str(s, errors="ignore") for s in args if s is not None)
+
# I'm annoyed with the fact the urllib.urlencode doesn't allow specifying
# "safe" characters -- specifically ":", ",", and "|" since those characters
# make reading gchart URLs much easier.
@@ -898,9 +898,9 @@ def urlencode(query, safe="/:,|"):
return "&".join(qlist)
def flatten(iterator):
- for i in iterator:
- if hasattr(i, "__iter__"):
- for j in flatten(iter(i)):
- yield j
- else:
- yield i
+ for i in iterator:
+ if hasattr(i, "__iter__"):
+ for j in flatten(iter(i)):
+ yield j
+ else:
+ yield i
Please sign in to comment.
Something went wrong with that request. Please try again.