stats2.py: add some 3D perspective to the graphs.
This commit is contained in:
parent
b47c2cba8a
commit
b7ad2ab241
1 changed files with 49 additions and 8 deletions
57
py/stats2.py
57
py/stats2.py
|
|
@ -26,12 +26,19 @@ rect.bar {{
|
|||
stroke-width:2;
|
||||
stroke-opacity:1;
|
||||
}}
|
||||
g.bar3d polygon {{
|
||||
fill:#{0};
|
||||
fill-opacity:1;
|
||||
stroke:#000000;
|
||||
stroke-width:1;
|
||||
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'
|
||||
ylabel = '<text x="90" y="{0:.2f}" 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'
|
||||
|
|
@ -43,6 +50,28 @@ ylabelf = """<g transform="translate(100, 300)">
|
|||
</g>
|
||||
"""
|
||||
|
||||
def makepolygon(coords):
|
||||
points = [ "{0:.2f},{1:.2f}".format(pt[0], pt[1]) for pt in coords ]
|
||||
pointstr = " ".join(points)
|
||||
return '<polygon points="{}"/>\n'.format(pointstr)
|
||||
|
||||
def bar3d(x, w, h):
|
||||
ydelta = w / 2
|
||||
xdelta = ydelta / 3
|
||||
flowerleft = (x, 550)
|
||||
flowerright = (x + w, 550)
|
||||
fupperleft = (x, 550 - h)
|
||||
fupperright = (x + w, 550 - h)
|
||||
blowerright = (x + w + xdelta, 550 - ydelta)
|
||||
bupperleft = (x + xdelta, 550 - h - ydelta)
|
||||
bupperright = (x + w + xdelta, 550 - h - ydelta)
|
||||
frontface = makepolygon([flowerleft, flowerright, fupperright, fupperleft])
|
||||
rightface = makepolygon([blowerright, flowerright, fupperright, bupperright])
|
||||
topface = makepolygon([bupperleft, bupperright, fupperright, fupperleft])
|
||||
gopen = '<g class="bar3d" clip-path="url(#framer)">\n'
|
||||
gclose = '</g>\n'
|
||||
return gopen + "".join([frontface, rightface, topface]) + gclose
|
||||
|
||||
class SVGChart():
|
||||
def __init__(self, filename):
|
||||
self.of = open(filename, "w", encoding="utf-8")
|
||||
|
|
@ -61,7 +90,7 @@ def ylimits(x):
|
|||
size = 0
|
||||
while True:
|
||||
for i in ll:
|
||||
if i * m > x:
|
||||
if i * m > x * 1.1:
|
||||
size = i
|
||||
lim = i * m
|
||||
break
|
||||
|
|
@ -90,13 +119,17 @@ def mkxlgraph(game, xldata):
|
|||
xlgraph = SVGChart("{0}/xl-{1}.svg".format(svgpath, game.uname))
|
||||
xlgraph.style("0000ff")
|
||||
xlgraph.write(framerect)
|
||||
xlgraph.write('<clipPath id="framer">\n')
|
||||
xlgraph.write(framerect)
|
||||
xlgraph.write('</clipPath>\n')
|
||||
xldivs, xlmax = ylimits(max([ pt[1] for pt in xldata ]))
|
||||
scale = 500 / xlmax
|
||||
for xl, count in xldata:
|
||||
barx = xl * 50 + 60
|
||||
barh = round(scale * count)
|
||||
barh = scale * count
|
||||
bary = 550 - barh
|
||||
xlgraph.write(barstr.format(30, barh, barx, bary))
|
||||
if count > 0:
|
||||
xlgraph.write(bar3d(barx, 30, barh))
|
||||
xlgraph.write(xllabel.format(barx + 15, xl))
|
||||
for yl in range(xldivs + 1):
|
||||
labeln = int(xlmax * yl / xldivs)
|
||||
|
|
@ -116,14 +149,18 @@ def mkscoregraph(game, scoredata):
|
|||
scoregraph = SVGChart("{0}/score-{1}.svg".format(svgpath, game.uname))
|
||||
scoregraph.style("ffff00")
|
||||
scoregraph.write(framerect)
|
||||
scoregraph.write('<clipPath id="framer">\n')
|
||||
scoregraph.write(framerect)
|
||||
scoregraph.write('</clipPath>\n')
|
||||
scoredivs, scoremax = ylimits(max([ pt[1] for pt in scoredata ]))
|
||||
scale = 500 / scoremax
|
||||
for block, count in scoredata:
|
||||
n = block // scorewidth
|
||||
barx = n * 75 + 100
|
||||
barh = round(scale * count)
|
||||
barh = scale * count
|
||||
bary = 550 - barh
|
||||
scoregraph.write(barstr.format(75, barh, barx, bary))
|
||||
if count > 0:
|
||||
scoregraph.write(bar3d(barx, 75, barh))
|
||||
scoregraph.write(xllabel.format(barx, block))
|
||||
for yl in range(scoredivs + 1):
|
||||
labeln = int(scoremax * yl / scoredivs)
|
||||
|
|
@ -139,13 +176,17 @@ def mkdeepgraph(game, deepdata):
|
|||
deepgraph = SVGChart("{0}/deep-{1}.svg".format(svgpath, game.uname))
|
||||
deepgraph.style("808000")
|
||||
deepgraph.write(framerect)
|
||||
deepgraph.write('<clipPath id="framer">\n')
|
||||
deepgraph.write(framerect)
|
||||
deepgraph.write('</clipPath>\n')
|
||||
deepdivs, deepmax = ylimits(max([ pt[1] for pt in deepdata ]))
|
||||
scale = 500 / deepmax
|
||||
for lev, count in deepdata:
|
||||
barx = lev * 25 + 75
|
||||
barh = round(scale * count)
|
||||
barh = scale * count
|
||||
bary = 550 - barh
|
||||
deepgraph.write(barstr.format(25, barh, barx, bary))
|
||||
if count > 0:
|
||||
deepgraph.write(bar3d(barx, 25, barh))
|
||||
if lev % 3 == 0:
|
||||
deepgraph.write(xllabel.format(barx + 12.5, lev))
|
||||
for yl in range(deepdivs + 1):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue