Mercurial > hg > rlgallery-misc
view py/stats2.py @ 44:7c789e87ee5d
Rearrange the statistics pages.
Move each game's charts onto individual pages. Put links to these
pages on /scoring/index.html, instead of dumping all the charts there.
author | John "Elwin" Edwards |
---|---|
date | Thu, 16 Jan 2014 11:04:45 -0800 |
parents | 3ecbd4fa2a08 |
children | 0f4163dbbafc |
line wrap: on
line source
#!/usr/bin/python3 import psycopg2 import rlgall from datetime import datetime sitename = "rlgallery.org" svgpath = rlgall.webdir timestr = datetime.utcnow().strftime("%Y-%m-%d %H:%M") dochead = """<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="900" height="600"> """ stylesheet = """<style type="text/css"> rect.frame {{ fill:#ffffff; fill-opacity:1; stroke:#000000; stroke-width:2; stroke-opacity:1; }} rect.bar {{ fill:#{0}; fill-opacity:1; stroke:#000000; stroke-width:2; stroke-opacity:1; }} </style> """ framerect = '<rect width="750" height="500" x="100" y="50" class="frame"/>\n' barstr = '<rect width="{0}" height="{1}" x="{2}" y="{3}" class="bar"/>\n' xllabel = '<text x="{0}" y="570" font-size="15" text-anchor="middle">{1}</text>\n' ylabel = '<text x="90" y="{0}" font-size="16" text-anchor="end">{1}</text>\n' xlabelf = '<text x="475" y="590" font-size="15" text-anchor="middle">{0}</text>\n' ltitle = '<text x="100" y="35" font-size="16" text-anchor="start">{0}</text>\n' ctitle = '<text x="475" y="34" font-size="18" text-anchor="middle">{0}</text>\n' rtitle = '<text x="850" y="35" font-size="16" text-anchor="end">{0}</text>\n' ylabelf = """<g transform="translate(100, 300)"> <g transform="rotate(-90)"> <text x="0" y="-60" font-size="16" text-anchor="middle">{0}</text> </g> </g> """ def ylimits(x): ll = [2, 3, 4, 5, 6, 8, 10, 15] m = 1 size = 0 while True: for i in ll: if i * m > x: size = i lim = i * m break if size: break else: m *= 10 if size in [3, 6]: if lim == 3: divs = 3 else: divs = 6 elif size in [4, 8]: divs = 4 else: if lim == 2: divs = 2 else: divs = 5 return divs, lim def mkxlgraph(game, xls, xlcounts): xlgraph = open("{0}/xl-{1}.svg".format(svgpath, game.uname), "w") xlgraph.write(dochead) xlgraph.write(stylesheet.format("0000ff")) xlgraph.write(framerect) xldivs, xlmax = ylimits(max(xlcounts)) scale = 500 / xlmax for xl, count in zip(xls, xlcounts): barx = xl * 50 + 60 barh = round(scale * count) bary = 550 - barh xlgraph.write(barstr.format(30, barh, barx, bary)) xlgraph.write(xllabel.format(barx + 15, xl)) for yl in range(xldivs + 1): labeln = int(xlmax * yl / xldivs) labelh = 550 + 8 - 500 * yl / xldivs xlgraph.write(ylabel.format(labelh, labeln)) xlgraph.write(xlabelf.format("Experience level")) xlgraph.write(ylabelf.format("# of games")) xlgraph.write(ltitle.format(sitename)) xlgraph.write(ctitle.format(game.name)) xlgraph.write(rtitle.format(timestr)) xlgraph.write('</svg>\n') xlgraph.close() return def mkscoregraph(game, scoreblocks, scorecounts): if isinstance(game, rlgall.ARogueGame): scorewidth = 1500 else: scorewidth = 1000 scoregraph = open("{0}/score-{1}.svg".format(svgpath, game.uname), "w") scoregraph.write(dochead) scoregraph.write(stylesheet.format("ffff00")) scoregraph.write(framerect) scoredivs, scoremax = ylimits(max(scorecounts)) scale = 500 / scoremax for block, count in zip(scoreblocks, scorecounts): barx = block * 75 + 100 barh = round(scale * count) bary = 550 - barh scoregraph.write(barstr.format(75, barh, barx, bary)) scoregraph.write(xllabel.format(barx, block * scorewidth)) for yl in range(scoredivs + 1): labeln = int(scoremax * yl / scoredivs) labelh = 550 + 8 - 500 * yl / scoredivs scoregraph.write(ylabel.format(labelh, labeln)) scoregraph.write(xlabelf.format("Score")) scoregraph.write(ylabelf.format("# of games")) scoregraph.write(ltitle.format(sitename)) scoregraph.write(ctitle.format(game.name)) scoregraph.write(rtitle.format(timestr)) scoregraph.write('</svg>\n') scoregraph.close() return def mkdeepgraph(game, deeps, deepcounts): deepgraph = open("{0}/deep-{1}.svg".format(svgpath, game.uname), "w") deepgraph.write(dochead) deepgraph.write(stylesheet.format("808000")) deepgraph.write(framerect) deepdivs, deepmax = ylimits(max(deepcounts)) scale = 500 / deepmax for lev, count in zip(deeps, deepcounts): barx = lev * 25 + 75 barh = round(scale * count) bary = 550 - barh deepgraph.write(barstr.format(25, barh, barx, bary)) if lev % 3 == 0: deepgraph.write(xllabel.format(barx + 12.5, lev)) for yl in range(deepdivs + 1): labeln = int(deepmax * yl / deepdivs) labelh = 550 + 8 - 500 * yl / deepdivs deepgraph.write(ylabel.format(labelh, labeln)) deepgraph.write(xlabelf.format("Deepest dungeon level")) deepgraph.write(ylabelf.format("# of games")) deepgraph.write(ltitle.format(sitename)) deepgraph.write(ctitle.format(game.name)) deepgraph.write(rtitle.format(timestr)) deepgraph.write('</svg>\n') deepgraph.close() return con = psycopg2.connect("dbname=rlg") cur = con.cursor() for game in rlgall.gamelist: xlq = "SELECT count(*) FROM {0} WHERE xl = %s;".format(game.uname) scrq = "SELECT count(*) FROM {0} WHERE score >= %s AND score < %s;".format(game.uname) deepq = "SELECT count(*) FROM {0} WHERE maxdepth = %s;".format(game.uname) xls = range(1, 16) scoreblocks = range(10) deeps = range(1, 31) xlcounts = [] scorecounts = [] deepcounts = [] if isinstance(game, rlgall.ARogueGame): scorewidth = 1500 else: scorewidth = 1000 for xl in xls: cur.execute(xlq, [xl]) xlcounts.append(cur.fetchone()[0]) for sn in scoreblocks: lscore = sn * scorewidth if sn == 9: hscore = scorewidth * 32 else: hscore = (sn + 1) * scorewidth cur.execute(scrq, (lscore, hscore)) scorecounts.append(cur.fetchone()[0]) for lev in deeps: cur.execute(deepq, [lev]) deepcounts.append(cur.fetchone()[0]) mkxlgraph(game, xls, xlcounts) mkscoregraph(game, scoreblocks, scorecounts) mkdeepgraph(game, deeps, deepcounts) cur.close() con.close() exit()