Python to generate nice looking SVG graph http://pygal.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

193 lines
6.9 KiB

# -*- coding: utf-8 -*-
# This file is part of pygal
#
# A python svg graph plotting library
# Copyright © 2012 Kozea
#
# This library is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from flask import Flask, render_template
from logging import getLogger, INFO, DEBUG
import pygal
from pygal.config import Config
from pygal.util import cut
from pygal.style import styles, DefaultStyle
from pygal.serie import Serie
from base64 import (
urlsafe_b64encode as b64encode,
urlsafe_b64decode as b64decode)
import string
import random
import pickle
def random_label():
chars = string.letters + string.digits + u' àéèçêâäëï'
return ''.join(
[random.choice(chars)
for i in range(
random.randrange(4, 30))])
def random_value(min=0, max=15):
return random.randrange(min, max, 1)
def create_app():
"""Creates the pygal test web app"""
app = Flask(__name__)
try:
from log_colorizer import make_colored_stream_handler
handler = make_colored_stream_handler()
except ImportError:
from logging import StreamHandler
handler = StreamHandler()
getLogger('werkzeug').addHandler(handler)
getLogger('werkzeug').setLevel(INFO)
getLogger('pygal').addHandler(handler)
getLogger('pygal').setLevel(DEBUG)
def _random(data, order):
max = 10 ** order
min = 10 ** random.randrange(0, order)
series = []
for i in range(random.randrange(1, 10)):
values = [(
random_value((-max, min)[random.randrange(0, 2)], max),
random_value((-max, min)[random.randrange(0, 2)], max))
for i in range(data)]
series.append(Serie(random_label(), values, len(series)))
return series
def _random_series(type, data, order):
max = 10 ** order
min = 10 ** random.randrange(0, order)
series = []
for i in range(random.randrange(1, 10)):
if type == 'Pie':
values = random_value(min, max)
elif type == 'XY':
values = [(
random_value((-max, min)[random.randrange(0, 2)], max),
random_value((-max, min)[random.randrange(0, 2)], max))
for i in range(data)]
else:
values = [random_value((-max, min)[random.randrange(1, 2)],
max) for i in range(data)]
series.append(Serie(random_label(), values, len(series)))
return series
@app.route("/")
def index():
return render_template('index.jinja2', styles=styles)
@app.route("/svg/<type>/<series>/<config>")
def svg(type, series, config):
graph = getattr(pygal, type)(pickle.loads(b64decode(str(config))))
graph.series = pickle.loads(b64decode(str(series)))
return graph.render_response()
@app.route("/all")
@app.route("/all/style=<style>")
@app.route("/all/interpolate=<interpolate>")
def all(style='default', interpolate=None):
width, height = 600, 400
data = random.randrange(1, 10)
order = random.randrange(1, 10)
xy_series = _random(data, order)
other_series = []
for serie in xy_series:
other_series.append(
Serie(serie.title, cut(serie.values, 1), serie.index))
xy_series = b64encode(pickle.dumps(xy_series))
other_series = b64encode(pickle.dumps(other_series))
config = Config()
config.width = width
config.height = height
config.fill = bool(random.randrange(0, 2))
config.human_readable = True
config.interpolate = interpolate
config.style = styles[style]
config.x_labels = [random_label() for i in range(data)]
svgs = []
for type in ('Bar', 'Line', 'XY', 'StackedBar',
'StackedLine', 'HorizontalBar',
'HorizontalStackedBar',
'Pie', 'Radar'):
svgs.append({'type': type,
'series': xy_series if type == 'XY' else other_series,
'config': b64encode(pickle.dumps(config))})
return render_template('svgs.jinja2',
svgs=svgs,
width=width,
height=height)
@app.route("/rotation")
def rotation():
width, height = 375, 245
config = Config()
config.width = width
config.height = height
config.fill = True
config.style = styles['neon']
data = random.randrange(1, 10)
order = random.randrange(1, 10)
series = b64encode(pickle.dumps(_random_series(type, data, order)))
labels = [random_label() for i in range(data)]
svgs = []
config.show_legend = bool(random.randrange(0, 2))
for angle in range(0, 91, 5):
config.title = "%d rotation" % angle
config.x_labels = labels
config.x_label_rotation = angle
svgs.append({'type': 'Bar',
'series': series,
'config': b64encode(pickle.dumps(config))})
return render_template('svgs.jinja2',
svgs=svgs,
width=width,
height=height)
@app.route("/interpolation")
def interpolation():
width, height = 600, 400
config = Config()
config.width = width
config.height = height
config.fill = True
config.style = styles['neon']
data = random.randrange(1, 10)
order = random.randrange(1, 10)
series = b64encode(pickle.dumps(_random_series(type, data, order)))
svgs = []
for interpolation in (
'linear', 'slinear', 'nearest', 'zero', 'quadratic', 'cubic',
'krogh', 'barycentric', 'univariate', 4, 5, 6, 7, 8):
config.title = "%s interpolation" % interpolation
config.interpolate = interpolation
svgs.append({'type': 'StackedLine',
'series': series,
'config': b64encode(pickle.dumps(config))})
return render_template('svgs.jinja2',
svgs=svgs,
width=width,
height=height)
return app