Temperaturer
Datagrunnlag
Dataene er hentet fra nettstedet rimfrost
[2]
og består av
enkle tab-separerte filer med månedlige temperaturer for forskjellige observasjonssteder.
dataene som er tilgjengelig i dette eksempelet er fra Oslo, Madrid og Moskva.
Oslo-dataene ser slik ut:
Det er skrevet et pythonskript som returnerer
disse dataene i en "chart"-format. Det ser slik ut:
#! /usr/bin/python
import cgi
"""
Loading temperatur data and prepare for a Google chart
Temperaturedata is one line for each year, months tabseparated
average as last value is ignored
Datafilenames are:
temp-<place>.txt, place in lowercase, temp-madrid.txt
Data is collected from: http://www.rimfrost.no/
"""
import urllib
errormsg='feil'
#----------------------------------------
# string templates
# when error
errorDiv='''<div>
No data found for %s
</div>
'''
#wrapping the chart image
element='''<div>
<img
src="http://chart.apis.google.com/chart?%s"
alt="failed" />
</div>'''
# parameters to chart as described in
# http://code.google.com/apis/chart/docs/chart_params.html
chxl='0:|J|F|M|A|M|J|J|A|S|O|N|D|1:|-20|-15|-10|-5|0|5|10|15|20|25|30|2:|'
chxt='x,y,r'
chs='500x250'
cht='bvg'
chco='76A4FB'
chd='t:%s'
chg='0,20,0,0,0,0'
chds='-20,30'
chtt='%s' # title
# chart string
chart='chxl=%s&chxt=%s&chs=%s&cht=%s&chco=%s&chd=%s&chg=%s&chds=%s&chtt=%s'
#when two series
chbh='a,1,6' # when two series to fix column width and neighbourhood
chdl='%s|%s'# when two series, ie: Moskva 2006|Madrid 2006
chco2='76A4FB,FB76A4'
chart2='chxl=%s&chxt=%s&chs=%s&cht=%s&chco=%s&chd=%s&chg=%s&chds=%s&chtt=%s&chbh=%s&chdl=%s'
#----------------------------------------
# load data from anywhere
def loadData(address):
try:
# as an url, possibly with scheme file:
f=urllib.urlopen(address)
res=f.read()
f.close()
return (res)
except:
# try as a strait filename (absolute or relative)
try:
file=open(address,'r')
res=file.read()
file.close()
return (res)
except:
return None
#------------------------------------------
# extract months temp, tabseparated
def extractData(year,place):
address='temp-%s.txt'%place.lower()
data=loadData(address)
if data==None:
return None
lines=data.split('\n')
for line in lines:
if line.startswith(year):
#print line
vals=line.split('\t')
ret=''
#loose year and average
for val in vals[1:-1]:
ret=ret+val+','
return ret[:-1]
#------------------------------------------
# Prepare div for one or two places [year,place]
def doIt(place1,place2):
csvdata1=None
csvdata2=None
if len(place1)!=2:
return errorDiv%('nowhere')
csvdata1=extractData(place1[0],place1[1])
if csvdata1==None:
return errorDiv%(place1[0]+','+place1[1])
if len(place2)==2:
csvdata2=extractData(place2[0],place2[1])
if csvdata2==None:
return errorDiv%(place2[0]+','+place2[1])
# we have one or two data sets
if csvdata2!=None:
# two data sets
vchtt=chtt%'Temperaturer'
vchd=chd%csvdata1+'|'+csvdata2
vchdl=chdl%(place1[1]+' '+place1[0],place2[1]+' '+place2[0])
chartv=chart2%(chxl,chxt,chs,cht,chco2,vchd,chg,chds,vchtt,chbh,vchdl)
elt=element%chartv
return elt.replace('&','&')
# one data set
# those carry the actual values, data and title
vchtt=chtt%place1[1]+' '+place1[0]
vchd=chd%csvdata1
chartv=chart%(chxl,chxt,chs,cht,chco,vchd,chg,chds,vchtt)
elt=element%chartv
return elt.replace('&','&')
#--------------------------------
# expect to find: place1,year1[,place2,year2]
place1=year1=place2=year2=None
#place1='Moskva'
#year1='2005'
#place2='Moskva'
#year2='2006'
form=cgi.FieldStorage()
print 'Content-type: text/html; charset=utf-8\n'
if form.has_key('place1'):
place1=form['place1'].value
if form.has_key('year1'):
year1=form['year1'].value
if form.has_key('place2'):
place2=form['place2'].value
if form.has_key('year2'):
year2=form['year2'].value
if place1==None or year1==None:
t=doIt([],[])
elif place2==None or year2==None:
t=doIt([year1,place1],[])
else:
t=doIt([year1,place1],[year2,place2])
print t
Du kan teste det med å skrive f.eks. følgende i netleserens adressefelt:
http://www.it.hiof.no/~borres/cgi-bin/ajax/temperaturer/prepareGoogleChart.py?place1=oslo&year1=2006
Visning
Et enkelt eksempel som lar oss se ett eller to datasett i et søylediagram:
The chart will appear here
Javaskriptet som sender og mottar en AJAX-request er basert på jQuery
[3]
og ser slik ut:
function SendIt(frm,targetNodeId)
{
address='http://www.it.hiof.no/~borres/cgi-bin/ajax/temperaturer/prepareGoogleChart.py';
p1=frm.place1.value;y1=frm.year1.value;
p2=frm.place2.value;y2=frm.year2.value;
params='place1='+p1+'&year1='+y1
if(p2!='noplace')
params=params+'&place2='+p2+'&year2='+y2
$.ajax({
url:address,
data:params,
type:'GET',
success:function(data)
{
$('#'+targetNodeId).html(data);
},
error:function(data)
{
$('#'+targetNodeId).html('error');
}
});
}
Et eksempel på et resultat kan se slik ut (brukket om for lesbarhet):
<img
src="http://chart.apis.google.com/chart?
chxl=0:|J|F|M|A|M|J|J|A|S|O|N|D|1:|-20|-15|-10|-5|0|5|10|15|20|25|30|2:|&
chxt=x,y,r&
chs=500x250&
cht=bvg&
chco=76A4FB,FB76A4&
chd=t:-3.00,-8.90,-6.00,7.10,14.80,16.50,19.30,17.60,13.10,6.00,1.40,-4.10|
-10.80,-13.30,-3.70,6.00,12.40,18.20,18.00,17.50,13.30,7.00,0.70,1.20&
chg=0,20,0,0,0,0&
chds=-20,30&
chtt=Temperaturer&
chbh=a,1,6&
chdl=Moskva%202005|Moskva%202006"
alt="failed" />
Som du ser er det en rekke parameterverdier som er satt.
Google har en forklaring av disse på
Chart Feature List,
[4]
.
Dersom vi f.eks. endrer parameteren cht (chart type) til fra bvg til lc , får vi noe slikt:
Terningkast
Datagrunnlag
Vi tar utgangspunkt vindataene som beskrevet i modulen
Noen datasett
.
Et kort utdrag av vinfila som XML ser slik ut:
.
Vi er interesserte i hvor mange viner vi har med terningkast 1, 2 osv.
Vi kan lett telle dette med en XSL-transformasjon.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="//wines">
<xsl:value-of select="count(wine[dice='1'])"/>,
<xsl:value-of select="count(wine[dice='2'])"/>,
<xsl:value-of select="count(wine[dice='3'])"/>,
<xsl:value-of select="count(wine[dice='4'])"/>,
<xsl:value-of select="count(wine[dice='5'])"/>,
<xsl:value-of select="count(wine[dice='6'])"/>
</xsl:template>
</xsl:stylesheet>
Vi kunne lage et pythonskript som gjorde transformasjonen og leverte resultatet tilbake på samme måte
ovenfor, men vi nøyer oss med å slå fast at vi finner følgende 6 verdier: 57,119,318,637,532,315.
Dersom vi skulle være ajour med eventuelle endringer i vindataene, måtte vi selvsagt lage et slikt skript.
Visning
Vi forsøker å framstille disse datene (57,119,318,637,532,315) som et kakediagram.
Koden er slik (brukket om for lesbarhet):
<img
src="http://chart.apis.google.com/chart?
chl=I|II|III|IV|V|VI&
chs=300x300&
cht=p&
chco=BBBB00,BB0000&
chds=0,1000&
chd=t:57,119,318,637,532,315&
chtt=Terningkast%20for%20viner"
alt="failed" />