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.

1143 lines
39 KiB

# -*- coding: utf-8 -*-
# This file is part of pygal
from pygal import (
11 years ago
Bar, Gauge, Pyramid, Funnel, Dot, StackedBar, StackedLine, XY,
CHARTS_BY_NAME, Config, Line, Histogram, Box,
Pie, Treemap, TimeLine, DateLine, Radar, HorizontalBar,
DateTimeLine, SolidGauge)
try:
from pygal.maps import world
except ImportError:
world = None
try:
from pygal.maps import fr
except ImportError:
fr = None
try:
from pygal.maps import ch
except ImportError:
ch = None
from flask import abort
11 years ago
from pygal.style import styles, Style, RotateStyle
from pygal.colors import rotate
from pygal import stats, formatters
from pygal.graph.horizontal import HorizontalGraph
11 years ago
from random import randint, choice
from datetime import datetime, date
def get_test_routes(app):
lnk = lambda v, l=None: {
'value': v,
'xlink': 'javascript:alert("Test %s")' % v,
'label': l}
@app.route('/test/unsorted')
def test_unsorted():
bar = Bar(style=styles['neon'], value_formatter=formatters.human_readable)
bar.add('A', {'red': 10, 'green': 12, 'blue': 14})
bar.add('B', {'green': 11, 'blue': 7})
bar.add('C', {'blue': 7})
bar.add('D', {})
bar.add('E', {'blue': 2, 'red': 13})
bar.x_labels = ('red', 'green', 'blue')
return bar.render_response()
@app.route('/test/bar_links')
def test_bar_links():
bar = StackedLine(style=styles['default'](
font_family='googlefont:Raleway'))
bar.js = ('http://l:2343/2.0.x/pygal-tooltips.js',)
bar.title = 'Wow ! Such Chart !'
bar.x_title = 'Many x labels'
bar.y_title = 'Much y labels'
bar.dynamic_print_values = True
bar.add('Red serie', [
{'value': 10,
'label': 'Ten',
'xlink': 'http://google.com?q=10'},
{'value': 20,
'label': 'Twenty is a good number yada yda yda yada '
'yadaaaaaaaaaaaaaaaaaaaaaa',
'xlink': 'http://google.com?q=20'},
30,
{'value': 40,
'label': 'Forty',
'xlink': 'http://google.com?q=40'}
])
bar.add('Blue serie', [40, {
'value': 30,
'label': 'Thirty',
'xlink': 'http://google.com?q=30'
}, 20, 10])
bar.x_labels = ['Yesterday', 'Today or any other day',
'Tomorrow', 'Someday']
bar.logarithmic = True
# bar.zero = 1
return bar.render_response()
@app.route('/test/xy_links')
def test_xy_links():
xy = XY(style=styles['neon'], interpolate='cubic')
xy.add('1234', [
{'value': (10, 5),
'label': 'Ten',
'xlink': 'http://google.com?q=10'},
{'value': (20, 20),
'tooltip': 'Twenty',
'xlink': 'http://google.com?q=20'},
(30, 15),
{'value': (40, -5),
'label': 'Forty',
'xlink': 'http://google.com?q=40'}
])
xy.add('4321', [(40, 10), {
'value': (30, 3),
'label': 'Thirty',
'xlink': 'http://google.com?q=30'
}, (20, 10), (10, 21)])
xy.x_labels = list(range(1, 50))
xy.y_labels = list(range(1, 50))
return xy.render_response()
12 years ago
@app.route('/test/long_title')
def test_long_title():
bar = Bar()
bar.add('Looooooooooooooooooooooooooooooooooong', [2, None, 12])
bar.title = (
'1 12 123 1234 12345 123456 1234567 12345678 123456789 1234567890 '
'12345678901 123456789012 1234567890123 12345678901234 '
'123456789012345 1234567890123456 12345678901234567 '
'123456789012345678 1234567890123456789 12345678901234567890 '
'123456789012345 1234567890123456 12345678901234567 '
'12345678901 123456789012 1234567890123 12345678901234 '
'1 12 123 1234 12345 123456 1234567 12345678 123456789 1234567890')
return bar.render_response()
11 years ago
@app.route('/test/multiline_title')
def test_multiline_title():
bar = Bar()
bar.add('Looooooooooooooooooooooooooooooooooong', [2, None, 12])
bar.title = (
'First line \n Second line \n Third line'
)
return bar.render_response()
@app.route('/test/long_labels')
def test_long_labels():
bar = Bar()
bar.add('Long', [2, None, 12])
bar.title = (
'1 12 123 1234 12345 123456 1234567 12345678 123456789 1234567890')
bar.x_labels = 'a' * 100, 'b ' * 50, 'cc ! ' * 20
bar.x_label_rotation = 45
12 years ago
return bar.render_response()
@app.route('/test/none')
def test_bar_none():
bar = Bar()
bar.add('Lol', [2, None, 12])
10 years ago
bar.x_labels = range(1, 4)
return bar.render_response()
@app.route('/test/print_values/<chart>')
def test_print_values_for(chart):
graph = CHARTS_BY_NAME[chart](
print_values=True, print_labels=True, print_zeroes=True,
style=styles['default'](
value_font_family='googlefont:Raleway',
value_colors=(None, None, 'blue', 'red', 'green')
))
graph.js = ('http://l:2343/2.0.x/pygal-tooltips.js',)
for i in range(12):
graph.add('', [{
'value': i + j,
'label': 'abcdefghijklmnopqrstuvwxyz'[i + j]
} for j in range(5)])
return graph.render_response()
@app.route('/test/treemap')
def test_treemap():
treemap = Treemap(style=RotateStyle('#ff5995', opacity=.6,
value_font_size=32,
value_colors=['#ffffff']))
11 years ago
treemap.title = 'Binary TreeMap'
treemap.print_values = True
treemap.print_labels = True
for i in range(1, 5):
treemap.add('', [{'label': 'Area %d' % i, 'value': i}])
treemap.add('', [2])
# treemap.add('A', [2, 1, 12, 4, 2, 1, 1, 3, 12, 3, 4, None, 9])
# treemap.add('B', [4, 2, 5, 10, 3, 4, 2, 7, 4, -10, None, 8, 3, 1])
# treemap.add('C', [3, 8, 3, 3, 5, 3, 3, 5, 4, 12])
# treemap.add('D', [23, 18])
# treemap.add('E', [1, 2, 1, 2, 3, 3, 1, 2, 3,
# 4, 3, 1, 2, 1, 1, 1, 1, 1])
# treemap.add('F', [31])
# treemap.add('G', [5, 9.3, 8.1, 12, 4, 3, 2])
# treemap.add('H', [12, 3, 3])
return treemap.render_response()
@app.route('/test/gauge')
def test_gauge():
gauge = Gauge()
gauge.range = [-10, 10]
gauge.add('Need l', [2.3, 5.12])
gauge.add('Need m', [-4])
gauge.add('Need z', [-10, 10.5])
gauge.add('No', [99, -99])
gauge.y_labels = [
{'label': 'X',
'value': 6},
{'label': '><',
'value': -6}
]
return gauge.render_response()
9 years ago
@app.route('/test/solidgauge/')
def test_solidgauge():
9 years ago
gauge = SolidGauge(half_pie=True,
inner_radius=0.70,
print_values=not True,
9 years ago
human_readable=True)
gauge.title = 'Hello World!'
percent_formatter = lambda x: '{:.10g}%'.format(x)
dollar_formatter = lambda x: '{:.10g}$'.format(x)
gauge.value_formatter = percent_formatter
gauge.add('Series 1', [{'value': 225000, 'max_value': 1275000}],
formatter=dollar_formatter)
gauge.add('Series 2', [{'value': 110, 'max_value': 100}])
gauge.add('Series 3', [{'value': 3}])
gauge.add(
'Series 4', [
{'value': 51, 'max_value': 100},
{'value': 12, 'max_value': 100}])
gauge.add('Series 5', [{'value': 79, 'max_value': 100}])
gauge.add('Series 6', 99)
gauge.add('Series 7', [{'value': 100, 'max_value': 100}])
9 years ago
return gauge.render_response()
@app.route('/test/gauge/log')
def test_gauge_log():
gauge = Gauge(logarithmic=True)
gauge.add('Need l', [200.3, 500.12])
gauge.add('Need z', [10, 1000.5])
return gauge.render_response()
@app.route('/test/pyramid')
def test_pyramid():
pyramid = Pyramid()
pyramid.x_labels = ['0-25', '25-45', '45-65', '65+']
pyramid.add('Man single', [2, 4, 2, 1])
pyramid.add('Woman single', [10, 6, 1, 1])
pyramid.add('Man maried', [10, 3, 4, 2])
pyramid.add('Woman maried', [3, 3, 5, 3])
return pyramid.render_response()
@app.route('/test/funnel')
def test_funnel():
funnel = Funnel()
funnel.add('1', [1, 2, 3])
funnel.add('3', [3, 4, 5])
funnel.add('6', [6, 5, 4])
funnel.add('12', [12, 2, 9])
return funnel.render_response()
@app.route('/test/dot')
def test_dot():
dot = Dot(logarithmic=True)
dot.x_labels = map(str, range(4))
dot.add('a', [1, lnk(3, 'Foo'), 5, 3])
dot.add('b', [2, -2, 0, 2, .1])
dot.add('c', [5, 1, 50, lnk(3, 'Bar')])
dot.add('d', [-5, 5, lnk(0, 'Babar'), 3])
return dot.render_response()
@app.route('/test/<chart>')
def test_for(chart):
graph = CHARTS_BY_NAME[chart]()
graph.add('1', [1, 3, 12, 3, 4, None, 9])
graph.add('2', [7, -4, 10, None, 8, 3, 1])
12 years ago
graph.add('3', [7, -14, -10, None, 8, 3, 1])
graph.add('4', [7, 4, -10, None, 8, 3, 1])
graph.x_labels = ('a', 'b', 'c', 'd')
graph.x_label_rotation = 90
return graph.render_response()
@app.route('/test/one/<chart>')
def test_one_for(chart):
graph = CHARTS_BY_NAME[chart]()
12 years ago
graph.add('1', [10])
graph.x_labels = 'a',
return graph.render_response()
@app.route('/test/xytitles/<chart>')
def test_xy_titles_for(chart):
graph = CHARTS_BY_NAME[chart]()
graph.title = 'My global title'
graph.x_title = 'My X title'
graph.y_title = 'My Y title'
graph.add('My number 1 serie', [1, 3, 12])
graph.add('My number 2 serie', [7, -4, 10])
graph.add('A', [17, -14, 11], secondary=True)
graph.x_label_rotation = 25
graph.legend_at_bottom = not True
graph.x_labels = (
'First point', 'Second point', 'Third point')
return graph.render_response()
12 years ago
@app.route('/test/no_data/<chart>')
def test_no_data_for(chart):
graph = CHARTS_BY_NAME[chart]()
graph.add('Empty 1', [])
graph.add('Empty 2', [])
graph.x_labels = 'empty'
graph.title = '123456789 ' * 30
return graph.render_response()
@app.route('/test/xy_single')
def test_xy_single():
graph = XY(interpolate='cubic')
graph.add('Single', [(1, 1)])
return graph.render_response()
12 years ago
@app.route('/test/no_data/at_all/<chart>')
def test_no_data_at_all_for(chart):
graph = CHARTS_BY_NAME[chart]()
return graph.render_response()
@app.route('/test/interpolate/<chart>')
def test_interpolate_for(chart):
graph = CHARTS_BY_NAME[chart](interpolate='lagrange',
interpolation_parameters={
'type': 'kochanek_bartels',
'c': 1,
'b': -1,
't': -1})
graph.add('1', [1, 3, 12, 3, 4])
graph.add('2', [7, -4, 10, None, 8, 3, 1])
return graph.render_response()
@app.route('/test/logarithmic/<chart>')
def test_logarithmic_for(chart):
graph = CHARTS_BY_NAME[chart](logarithmic=True)
if isinstance(graph, CHARTS_BY_NAME['XY']):
graph.add('xy', [
(.1, .234), (10, 243), (.001, 2), (1000000, 1231)])
else:
graph.add('1', [.1, 10, .01, 10000])
graph.add('2', [.234, 243, 2, 2379, 1231])
12 years ago
graph.x_labels = ('a', 'b', 'c', 'd', 'e')
graph.x_label_rotation = 90
return graph.render_response()
@app.route('/test/zero_at_34/<chart>')
@app.route('/test/zero_at_<int:zero>/<chart>')
def test_zero_at_34_for(chart, zero=34):
graph = CHARTS_BY_NAME[chart](fill=True, zero=zero)
graph.add('1', [100, 34, 12, 43, -48])
graph.add('2', [73, -14, 10, None, -58, 32, 91])
return graph.render_response()
@app.route('/test/range/<chart>')
def test_range_for(chart):
graph = CHARTS_BY_NAME[chart]()
graph.range = [0, 100]
graph.add('1', [1, 2, 10])
return graph.render_response()
11 years ago
@app.route('/test/fill_with_none/')
def test_fill_with_none():
graph = XY(fill=True)
graph.add('1', [(1, 2), (3, 3), (3.5, 5), (5, 1)])
graph.add('2', [(1, 9), (None, 5), (5, 23)])
return graph.render_response()
@app.route('/test/negative/<chart>')
def test_negative_for(chart):
graph = CHARTS_BY_NAME[chart]()
graph.add('1', [10, 0, -10])
return graph.render_response()
@app.route('/test/bar')
def test_bar():
bar = Bar(dynamic_print_values=True, show_minor_x_labels=False)
bar.add('1', [1, 2, 3])
bar.add('2', [4, 5, 6])
bar.x_labels = [2, 4, 6]
bar.x_labels_major = [4]
return bar.render_response()
@app.route('/test/formatters/<chart>')
def test_formatters_for(chart):
chart = CHARTS_BY_NAME[chart](
print_values=True, formatter=lambda x, chart, serie: '%s%s$' % (
x, serie.title))
chart.add('_a', [1, 2, {'value': 3, 'formatter': lambda x: '%s¥' % x}])
chart.add('_b', [4, 5, 6], formatter=lambda x: '%s€' % x)
chart.x_labels = [2, 4, 6]
chart.x_labels_major = [4]
return chart.render_response()
@app.route('/test/bar/position')
def test_bar_print_values_position():
bar = StackedBar(
print_values=True, print_values_position='top', zero=2,
style=styles['default'](
value_font_family='googlefont:Raleway',
value_font_size=46))
bar.add('1', [1, -2, 3])
bar.add('2', [4, -5, 6])
bar.x_labels = [2, 4, 6]
bar.x_labels_major = [4]
return bar.render_response()
@app.route('/test/histogram')
def test_histogram():
hist = Histogram(
print_values=True,
print_values_position='top',
style=styles['neon'])
hist.add('1', [
(2, 0, 1),
(4, 1, 3),
(3, 3.5, 5),
(1.5, 5, 10)
])
hist.add('2', [(2, 2, 8)])
hist.x_labels = [0, 3, 6, 9, 12]
return hist.render_response()
@app.route('/test/ylabels')
def test_ylabels():
chart = Bar()
chart.x_labels = 'Red', 'Blue', 'Green'
chart.y_labels = [
{'value': .0001,
'label': 'LOL'},
{'value': .0003,
'label': 'ROFL'},
{'value': .0004,
'label': 'MAO'},
{'value': .00045,
'label': 'LMFAO'},
{'value': .0005,
'label': 'GMCB'}]
chart.add('line', [.0002, .0005, .00035])
return chart.render_response()
@app.route('/test/secondary/<chart>')
def test_secondary_for(chart):
chart = CHARTS_BY_NAME[chart](fill=True)
chart.title = 'LOL ' * 23
chart.x_labels = 'abc'
chart.x_label_rotation = 25
chart.y_label_rotation = 50
chart.add('1', [30, 20, -2])
chart.add('1b', [-4, 50, 6], secondary=True)
chart.add('2b', [None, 10, 20], secondary=True)
chart.add('2', [8, 21, -0])
chart.add('3', [None, 20, 10])
chart.add('3b', [-1, 2, -3], secondary=True)
return chart.render_response()
@app.route('/test/secondary_xy')
def test_secondary_xy():
chart = XY()
chart.add(10 * '1', [(30, 5), (20, 12), (25, 4)])
chart.add(10 * '1b', [(4, 12), (5, 8), (6, 4)], secondary=True)
chart.add(10 * '2b', [(3, 24), (0, 17), (12, 9)], secondary=True)
chart.add(10 * '2', [(8, 23), (21, 1), (5, 0)])
chart.value_formatter = lambda x: str(int(x)) + '+'
return chart.render_response()
11 years ago
@app.route('/test/box')
def test_box():
chart = Box()
# chart.js = ('http://l:2343/2.0.x/pygal-tooltips.js',)
chart.box_mode = '1.5IQR'
11 years ago
chart.add('One', [15, 8, 2, -12, 9, 23])
chart.add('Two', [5, 8, 2, -9, 23, 12])
chart.add('Three', [8, -2, 12, -5, 9, 3])
chart.add('Four', [5, 8, 2, -9, -3, 12])
chart.add('Five', [8, 12, 12, -9, 5, 13])
chart.x_labels = map(str, range(5))
return chart.render_response()
@app.route('/test/stacked')
def test_stacked():
stacked = StackedLine(stack_from_top=True, logarithmic=True)
stacked.add('1', [1, 2])
stacked.add('2', [10, 12])
stacked.x_labels = ['a', 'b', 'c', 'd']
return stacked.render_response()
@app.route('/test/stacked/reverse')
def test_stacked_reverse():
stacked = StackedBar(stack_from_top=True)
stacked.add('1', [1, 2, 3])
stacked.add('2', [4, 5, 6])
return stacked.render_response()
@app.route('/test/show_dots')
def test_show_dots():
line = Line(show_dots=False)
line.add('1', [1, 2, 3])
line.add('2', [4, 5, 6])
return line.render_response()
12 years ago
@app.route('/test/config')
def test_config():
class LolConfig(Config):
10 years ago
js = ['http://l:2343/2.0.x/pygal-tooltips.js']
12 years ago
stacked = StackedBar(LolConfig())
stacked.add('', [1, 2, 3])
stacked.add('My beautiful serie of 2019', [4, 5, 6])
12 years ago
return stacked.render_response()
@app.route('/test/dateline')
def test_dateline():
dateline = DateLine(y_label_rotation=112)
dateline.x_labels = [
date(2013, 1, 1),
date(2013, 7, 1),
date(2014, 1, 1),
date(2014, 7, 1),
date(2015, 1, 1),
date(2015, 7, 1)
]
dateline.x_labels_major = [
date(2013, 1, 1),
date(2015, 7, 1)
]
dateline.add("Serie", [
(date(2013, 1, 2), 213),
(date(2013, 8, 2), 281),
(date(2013, 5, 31), 281),
(date(2014, 12, 7), 198),
(date(2014, 9, 6), 198),
(date(2015, 3, 21), 120)
])
return dateline.render_response()
@app.route('/test/timeline')
def test_timexy():
from datetime import time
timeline = TimeLine()
timeline.add('1', [
(time(1, 12, 29), 2),
(time(21, 2, 29), 10),
(time(12, 30, 59), 7)
])
timeline.add(
'2', [(time(12, 12, 12), 4), (time(), 8), (time(23, 59, 59), 6)])
timeline.x_label_rotation = 25
return timeline.render_response()
@app.route('/test/worldmap')
def test_worldmap():
wmap = world.World(print_values=True, style=choice(list(styles.values())))
10 years ago
# wmap.js = ('http://l:2343/2.0.x/pygal-tooltips.js',)
# wmap.add('1st', [('fr', 100), {
# 'value': ('us', 10),
# 'node': {'style': 'fill: red'}
# }
# ])
# wmap.add('2nd', [('jp', 1), ('ru', 7), ('uk', 0)])
# wmap.add('3rd', ['ch', 'cz', 'ca', 'cn'])
# wmap.add('4th', {'jp': 12, 'bo': 1, 'bu': 23, 'fr': 34})
# wmap.add('5th', [{
# 'value': ('tw', 10),
# 'label': 'First label',
# 'xlink': 'http://google.com?q=tw',
# }, {
# 'value': ('bw', 20),
# 'label': 'Second one',
# 'xlink': 'http://google.com?q=bw',
# 'node': {'style': 'fill: blue'}
# }, {
# 'value': ('mw', 40),
# 'label': 'Last'
# }])
wmap.add('_', {'us': 1})
wmap.add('-', {'us': 2})
wmap.add('.', {'us': 3})
11 years ago
wmap.title = 'World Map !!'
wmap.value_formatter = lambda x: '%d%%' % x
11 years ago
return wmap.render_response()
10 years ago
@app.route('/test/supranational')
def test_supranational():
wmap = world.SupranationalWorld(style=choice(list(styles.values())))
v = [
('europe', 0),
('oceania', 2),
('antartica', 4),
('south_america', 5),
('africa', 6),
('north_america', 7),
('asia', 8)
]
wmap.add('Serie with metadata', [
v[0],
{'value': v[1]},
{'value': v[2], 'label': 'Three'},
{'value': v[3], 'xlink': 'http://4.example.com/'},
{'value': v[4], 'xlink': 'http://5.example.com/', 'label': 'Five'},
{'value': v[5], 'xlink': {
'href': 'http://6.example.com/'}, 'label': 'Six'},
{'value': v[6], 'xlink': {
'href': 'http://7.example.com/',
'target': '_blank'}, 'label': 'Seven'}
])
# wmap.add('Asia', [('asia', 1)])
# wmap.add('Europe', [('europe', 1)])
# wmap.add('Africa', [('africa', 1)])
# wmap.add('North america', [('north_america', 1)])
# wmap.add('South america', [('south_america', 1)])
# wmap.add('Oceania', [('oceania', 1)])
# wmap.add('Antartica', [('antartica', 1)])
10 years ago
10 years ago
wmap.title = 'Supra World Map !!'
return wmap.render_response()
11 years ago
@app.route('/test/frenchmapdepartments')
def test_frenchmapdepartments():
if fr is None:
abort(404)
fmap = fr.Departments(style=choice(list(styles.values())))
fmap.add('', [(i, i) for i in range(1, 100)])
fmap.add('', [(970 + i, i) for i in range(1, 7)])
fmap.add('', [('2A', 1), ('2B', 2)])
11 years ago
fmap.title = 'French map'
return fmap.render_response()
10 years ago
@app.route('/test/swissmap')
def test_swissmap():
smap = ch.Cantons(style=choice(list(styles.values())))
10 years ago
for i in range(10):
smap.add('s%d' % i, [
(choice(list(ch.CANTONS.keys())), randint(0, 100))
10 years ago
for _ in range(randint(1, 5))])
smap.add('links', [{
'value': ('kt-vs', 10),
'label': '\o/',
'xlink': 'http://google.com?q=69'
}, {
'value': ('bt', 20),
'label': 'Y',
}])
smap.add('6th', [3, 5, 34, 12])
smap.title = 'Swiss map'
return smap.render_response()
11 years ago
@app.route('/test/frenchmapregions')
def test_frenchmapregions():
if fr is None:
abort(404)
fmap = fr.Regions(style=choice(list(styles.values())))
11 years ago
for i in range(10):
fmap.add('s%d' % i, [
(choice(list(fr.REGIONS.keys())), randint(0, 100))
11 years ago
for _ in range(randint(1, 5))])
fmap.add('links', [{
'value': ('02', 10),
'label': '\o/',
'xlink': 'http://google.com?q=69'
}, {
'value': ('72', 20),
'label': 'Y',
}])
fmap.add('6th', [91, 2, 41])
fmap.title = 'French map'
return fmap.render_response()
11 years ago
@app.route('/test/labels')
def test_labels():
line = Line()
line.add('test1', range(100))
line.x_labels = map(str, range(11))
return line.render_response()
@app.route('/test/64colors')
def test_64_colors():
n = 64
colors = [rotate('#ff0000', i * 360 / n) for i in range(n)]
pie = Pie(style=Style(colors=colors))
for i in range(n):
pie.add(str(i), 1)
return pie.render_response()
@app.route('/test/major_dots')
def test_major_dots():
line = Line(x_labels_major_count=2, show_only_major_dots=True)
line.add('test', range(12))
line.x_labels = [
'lol', 'lol1', 'lol2', 'lol3', 'lol4', 'lol5',
'lol6', 'lol7', 'lol8', 'lol9', 'lol10', 'lol11']
# line.x_labels_major = ['lol3']
return line.render_response()
@app.route('/test/x_major_labels/<chart>')
def test_x_major_labels_for(chart):
chart = CHARTS_BY_NAME[chart](show_minor_y_labels=False)
for i in range(12):
chart.add('test', range(12))
chart.x_labels = map(str, range(12))
# chart.x_labels_major_count = 4
# chart.x_labels_major = ['1', '5', '11', 6]
# chart.y_labels_major = [60, 120]
return chart.render_response()
@app.route('/test/y_major_labels/<chart>')
def test_y_major_labels_for(chart):
chart = CHARTS_BY_NAME[chart]()
chart.add('test', range(12))
# chart.add('test', zip(*[range(12), range(12)]))
chart.y_labels = range(12)
# chart.y_labels_major_count = 4
chart.y_labels_major = [1.0, 5.0, 11.0]
return chart.render_response()
@app.route('/test/stroke_config')
def test_stroke_config():
line = Line(stroke_style={'width': .5})
line.add('test_no_line', range(12), stroke=False)
line.add('test', reversed(range(12)), stroke_style={'width': 3})
line.add('test_no_dots', [5] * 12, show_dots=False,
stroke_style={'width': 2, 'dasharray': '12, 31'})
line.add('test_big_dots', [
randint(1, 12) for _ in range(12)], dots_size=5)
line.add('test_fill', [
randint(1, 3) for _ in range(12)], fill=True,
stroke_style={'width': 5, 'dasharray': '4, 12, 7, 20'})
line.x_labels = [
'lol', 'lol1', 'lol2', 'lol3', 'lol4', 'lol5',
'lol6', 'lol7', 'lol8', 'lol9', 'lol10', 'lol11']
return line.render_response()
@app.route('/test/radar')
def test_radar():
radar = Radar()
for i in range(10):
radar.add(str(i), [i * j for j in range(8)])
radar.x_labels = [
'lol',
'rofl',
'mao',
'lolroflmao',
'12345678901234567890'
]
radar.x_label_rotation = 35
radar.y_label_rotation = 35
radar.y_labels = [{
'label': '500',
'value': 10
}, {
'label': '1000',
'value': 20
}, {
'label': '5000',
'value': 30
}, {
'label': '10000',
'value': 40
}]
return radar.render_response()
@app.route('/test/pie_serie_radius')
def test_pie_serie_radius():
pie = Pie()
pie.js = ('http://a.zi:2343/2.0.x/pygal-tooltips.js',)
for i in range(10):
pie.add(str(i), i, inner_radius=(10 - i) / 10)
return pie.render_response()
@app.route('/test/half_pie')
def test_half_pie():
pie = Pie(half_pie=True)
for i in range(20):
pie.add(str(i), i, inner_radius=.1)
pie.legend_at_bottom = True
pie.legend_at_bottom_columns = 4
return pie.render_response()
@app.route('/test/interpolate/secondary')
def test_interpolate_secondary():
chart = Line(title=u'Some different points', interpolate='cubic')
chart.add('line', [1000, 2000, 7000])
chart.add('other line', [100, 500, 500], secondary=True)
chart.range = 0, 10000
chart.secondary_range = 0, 1000
return chart.render_response()
@app.route('/test/legend_at_bottom/<chart>')
def test_legend_at_bottom_for(chart):
graph = CHARTS_BY_NAME[chart]()
graph.add('1', [1, 3, 12, 3, 4, None, 9])
graph.add('2', [7, -4, 10, None, 8, 3, 1])
graph.add('3', [7, -14, -10, None, 8, 3, 1])
graph.add('4', [7, 4, -10, None, 8, 3, 1])
graph.x_labels = ('a', 'b', 'c', 'd', 'e', 'f', 'g')
graph.legend_at_bottom = True
return graph.render_response()
@app.route('/test/custom_metadata/<chart>')
def test_custom_metadata_for(chart):
c = CHARTS_BY_NAME[chart]()
c.add('1', [
{'style': 'fill: red', 'value': 1, 'node': {'r': 12}},
{'color': 'blue', 'value': 2, 'node': {'width': 12}},
{'style': 'fill: red; stroke: yellow', 'value': 3}])
c.add('2', [
{'value': 4, 'xlink': {
'href': 'javascript:alert("-")', 'target': 'top',
'class': 'lol'
}
},
{'color': 'green', 'value': 5},
6])
return c.render_response()
@app.route('/test/sparkline/<chart>')
def test_sparkline_for(chart):
graph = CHARTS_BY_NAME[chart](**dict(
width=200,
height=50,
show_dots=False,
show_legend=False,
show_y_labels=False,
show_x_labels=False,
spacing=0,
margin=5,
explicit_size=True
))
graph.add('1', [1, 3, 12, 3, 4, None, 9])
graph.add('2', [7, -4, 10, None, 8, 3, 1])
graph.add('3', [7, -14, -10, None, 8, 3, 1])
graph.add('4', [7, 4, -10, None, 8, 3, 1])
graph.x_labels = ('a', 'b', 'c', 'd', 'e', 'f', 'g')
graph.legend_at_bottom = True
return graph.render_response()
@app.route('/test/sparkline/label/<chart>')
def test_sparkline_label_for(chart):
graph = CHARTS_BY_NAME[chart](**dict(
width=200,
height=50,
show_dots=False,
show_legend=False,
# show_y_labels=False,
# show_x_labels=False,
spacing=0,
margin=5,
min_scale=2,
max_scale=2,
explicit_size=True
))
graph.add('1', [1, 3, 12, 3, 4, None, 9])
graph.add('2', [7, -4, 10, None, 8, 3, 1])
graph.add('3', [7, -14, -10, None, 8, 3, 1])
graph.add('4', [7, 4, -10, None, 8, 3, 1])
graph.x_labels = ('a', 'b', 'c', 'd', 'e', 'f', 'g')
graph.legend_at_bottom = True
return graph.render_response()
@app.route('/test/normal/<chart>')
def test_normal_for(chart):
graph = CHARTS_BY_NAME[chart]()
graph.add('1', [1, 3, 12, 3, 4, None, 9])
graph.add('2', [7, -4, 10, None, 8, 3, 1])
graph.add('3', [7, -14, -10, None, 8, 3, 1])
graph.add('4', [7, 4, -10, None, 8, 3, 1])
graph.x_labels = ('a', 'b', 'c', 'd', 'e', 'f', 'g')
graph.legend_at_bottom = True
return graph.render_response()
@app.route('/test/horizontal_force/<chart>')
def test_horizontal_force_for(chart):
class H(CHARTS_BY_NAME[chart], HorizontalGraph):
pass
graph = H()
graph.add('1', [1, 3, 12, 3, 4, None, 9])
graph.add('2', [7, -4, 10, None, 8, 3, 1])
graph.add('3', [7, -14, -10, None, 8, 3, 1])
graph.add('4', [7, 4, -10, None, 8, 3, 1])
graph.x_labels = ('a', 'b', 'c', 'd', 'e', 'f', 'g')
graph.legend_at_bottom = True
return graph.render_response()
@app.route('/test/inverse_y_axis/<chart>')
10 years ago
def test_inverse_y_axis_for(chart):
graph = CHARTS_BY_NAME[chart](**dict(inverse_y_axis=True))
graph.add('inverse', [1, 2, 3, 12, 24, 36])
return graph.render_response()
@app.route('/test/only_zeroes')
def test_only_zeroes():
line = Line()
line.add('zeroes', [])
line.add('zeroes 2', [0])
return line.render_response()
@app.route('/test/rotations/<chart>')
def test_rotations_for(chart):
graph = CHARTS_BY_NAME[chart]()
# graph.x_label_rotation = 290
# graph.y_label_rotation = 0
graph.add('lalalla al alallaa a 1',
[1, 3, 12, 3, 4, None, 9])
graph.add('lalalla al alallaa a 2',
[7, -4, 10, None, 8, 3, 1], secondary=True)
graph.add('lalalla al alallaa a 3',
[7, -14, -10, None, 8, 3, 1])
graph.add('lalalla al alallaa a 4',
[7, 4, -10, None, 8, 3, 1], secondary=True)
graph.x_labels = ('a', 'b', 'c', 'd', 'e', 'f', 'g')
# graph.legend_at_bottom = True
return graph.render_response()
@app.route('/test/datetimeline')
def test_datetimeline():
line = DateTimeLine()
10 years ago
from datetime import timezone, timedelta
tz7 = timezone(timedelta(hours=7), 'GMT +7')
tzn4 = timezone(timedelta(hours=-4), 'GMT -4')
line.add('dt', [
10 years ago
(datetime(2013, 1, 12, 8, tzinfo=tz7), 300),
(datetime(2013, 1, 12, 8), 412),
(datetime(2013, 1, 12, 8, tzinfo=tzn4), 823)
])
9 years ago
line.x_label_rotation = 45
return line.render_response()
@app.route('/test/datetimeline_with_pytz')
def test_datetimeline_with_pytz():
import pytz
tz = pytz.timezone('US/Eastern')
line = DateTimeLine()
line.add('dt', [
(tz.localize(datetime(2013, 1, 12, 8)), 300),
(tz.localize(datetime(2013, 1, 12, 10)), 600),
(tz.localize(datetime(2013, 1, 12, 14)), 30),
(tz.localize(datetime(2013, 1, 12, 16)), 200)
])
from datetime import timezone
9 years ago
line.x_value_formatter = lambda x: (
x.replace(tzinfo=timezone.utc).astimezone(tz)).isoformat()
9 years ago
# line.x_value_formatter = lambda x: tz.normalize(
# x.replace(tzinfo=pytz.utc)).isoformat()
line.x_label_rotation = 45
return line.render_response()
@app.route('/test/order_min')
def test_order_min():
line = Line(order_min=-32)
line.add('_', [1, 32, 12, .4, .009])
return line.render_response()
@app.route('/test/custom_css_file')
def test_custom_css_file():
from tempfile import NamedTemporaryFile
custom_css = '''
{{ id }}text {
fill: green;
font-family: monospace;
}
{{ id }}.legends .legend text {
font-size: {{ font_sizes.legend }};
}
{{ id }}.axis {
stroke: #666;
}
{{ id }}.axis text {
font-size: {{ font_sizes.label }};
font-family: sans;
stroke: none;
}
{{ id }}.axis.y text {
text-anchor: end;
}
{{ id }}#tooltip text {
font-size: {{ font_sizes.tooltip }};
}
{{ id }}.dot {
fill: yellow;
}
{{ id }}.color-0 {
stroke: #ff1100;
fill: #ff1100;
}
{{ id }}.color-1 {
stroke: #ffee00;
fill: #ffee00;
}
{{ id }}.color-2 {
stroke: #66bb44;
fill: #66bb44;
}
{{ id }}.color-3 {
stroke: #88bbdd;
fill: #88bbdd;
}
{{ id }}.color-4 {
stroke: #0000ff;
fill: #0000ff;
}
'''
custom_css_file = '/tmp/pygal_custom_style.css'
with open(custom_css_file, 'w') as f:
f.write(custom_css)
config = Config(fill=True, interpolate='cubic')
config.css.append(custom_css_file)
chart = StackedLine(config)
chart.add('A', [1, 3, 5, 16, 13, 3, 7])
chart.add('B', [5, 2, 3, 2, 5, 7, 17])
chart.add('C', [6, 10, 9, 7, 3, 1, 0])
chart.add('D', [2, 3, 5, 9, 12, 9, 5])
chart.add('E', [7, 4, 2, 1, 2, 10, 0])
return chart.render_response()
@app.route('/test/legendlink/<chart>')
def test_legend_link_for(chart):
chart = CHARTS_BY_NAME[chart]()
# link on chart and label
chart.add({
'title': 'Red',
'tooltip': 'Cramoisi',
'xlink': {'href': 'http://en.wikipedia.org/wiki/Red'}
}, [{
'value': 2,
'label': 'This is red',
'tooltip': 'LOOLLOLOLO',
'xlink': {'href': 'http://en.wikipedia.org/wiki/Red'}}])
chart.add({'title': 'Yellow', 'xlink': {
'href': 'http://en.wikipedia.org/wiki/Yellow',
'target': '_blank'}}, 7)
return chart.render_response()
@app.route('/test/gradient/<chart>')
def test_gradient_for(chart):
config = Config()
config.style = styles['dark']
config.defs.append('''
<linearGradient id="gradient-0" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="#ff5995" />
<stop offset="100%" stop-color="#feed6c" />
</linearGradient>
''')
config.defs.append('''
<linearGradient id="gradient-1" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="#b6e354" />
<stop offset="100%" stop-color="#8cedff" />
</linearGradient>
''')
config.css.append('''inline:
.color-0 {
fill: url(#gradient-0) !important;
stroke: url(#gradient-0) !important;
}''')
config.css.append('''inline:
.color-1 {
fill: url(#gradient-1) !important;
stroke: url(#gradient-1) !important;
}''')
chart = CHARTS_BY_NAME[chart](config)
chart.add('1', [1, 3, 12, 3, 4, None, 9])
chart.add('2', [7, -4, 10, None, 8, 3, 1])
chart.x_labels = ('a', 'b', 'c', 'd', 'e', 'f', 'g')
chart.legend_at_bottom = True
chart.interpolate = 'cubic'
return chart.render_response()
@app.route('/test/erfinv/approx')
def test_erfinv():
from scipy import stats as sstats
chart = Line(show_dots=False)
chart.add('scipy', [
sstats.norm.ppf(x/1000) for x in range(1, 999)])
chart.add('approx', [stats.ppf(x/1000) for x in range(1, 999)])
9 years ago
# chart.add('approx', [
# special.erfinv(x/1000) - erfinv(x/1000)
# for x in range(-999, 1000)])
return chart.render_response()
@app.route('/test/ci/<chart>')
def test_ci_for(chart):
chart = CHARTS_BY_NAME[chart](
style=styles['default'](
value_font_family='googlefont:Raleway',
value_colors=(None, None, 'blue', 'red', 'green'),
ci_colors=(None, 'magenta')
))
chart.add('Series 1', [
{'value': 127.3, 'ci': {
'type': 'continuous', 'sample_size': 3534, 'stddev': 19,
'confidence': .99}},
{'value': 127.3, 'ci': {
'type': 'continuous', 'sample_size': 3534, 'stddev': 19}},
{'value': 127.3, 'ci': {
'type': 'continuous', 'sample_size': 3534, 'stddev': 19,
'confidence': .90}},
{'value': 127.3, 'ci': {
'type': 'continuous', 'sample_size': 3534, 'stddev': 19,
'confidence': .75}},
])
chart.add('Series 2', [
{'value': 34.5, 'ci': {
'type': 'dichotomous', 'sample_size': 3532}},
])
chart.add('Series 3', [
{'value': 100, 'ci': {'low': 50, 'high': 150}},
{'value': 100, 'ci': {'low': 75, 'high': 175}},
{'value': 50, 'ci': {'low': 50, 'high': 100}},
{'value': 125, 'ci': {'low': 120, 'high': 130}},
])
chart.range = (30, 200)
return chart.render_response()
@app.route('/test/interruptions')
def test_interruptions():
chart = Line(allow_interruptions=True)
chart.add(
'interrupt', [22, 34, 43, 12, None, 12, 55, None, 56],
allow_interruptions=False)
chart.add('not interrupt', [
-a if a else None
for a in (22, 34, 43, 12, None, 12, 55, None, 56)])
return chart.render_response()
return list(sorted(filter(
lambda x: x.startswith('test') and not x.endswith('_for'), locals()))
) + list(sorted(filter(
lambda x: x.startswith('test') and x.endswith('_for'), locals())))