# -*- coding: utf-8 -*- # This file is part of pygal from datetime import date, datetime from random import choice, randint from flask import abort from pygal import ( CHARTS_BY_NAME, XY, Bar, Box, Config, DateLine, DateTimeLine, Dot, Funnel, Gauge, Histogram, HorizontalBar, Line, Pie, Pyramid, Radar, SolidGauge, StackedBar, StackedLine, TimeLine, Treemap, formatters, stats ) from pygal.colors import rotate from pygal.graph.horizontal import HorizontalGraph from pygal.style import RotateStyle, Style, styles 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 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() @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() @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 return bar.render_response() @app.route('/test/none') def test_bar_none(): bar = Bar() bar.add('Lol', [2, None, 12]) bar.x_labels = range(1, 4) return bar.render_response() @app.route('/test/print_values/') 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'] ) ) 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() @app.route('/test/solidgauge/') def test_solidgauge(): gauge = SolidGauge( half_pie=True, inner_radius=0.70, print_values=not True, 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}]) 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/') 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]) 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/') def test_call_api_for(chart): graph = CHARTS_BY_NAME[chart]() graph(1, 3, 12, 3, 4, None, 9, title='1') graph(7, -4, 10, None, 8, 3, 1, title='2') graph(7, -14, -10, None, 8, 3, 1, title='3') graph(7, 4, -10, None, 8, 3, 1, title='4') graph.x_labels = ('a', 'b', 'c', 'd') graph.x_label_rotation = 90 return graph.render_response() @app.route('/test/one/') def test_one_for(chart): graph = CHARTS_BY_NAME[chart]() graph.add('1', [10]) graph.x_labels = 'a', return graph.render_response() @app.route('/test/xytitles/') 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() @app.route('/test/no_data/') 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() @app.route('/test/no_data/at_all/') def test_no_data_at_all_for(chart): graph = CHARTS_BY_NAME[chart]() return graph.render_response() @app.route('/test/interpolate/') 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/') 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]) graph.x_labels = ('a', 'b', 'c', 'd', 'e') graph.x_label_rotation = 90 return graph.render_response() @app.route('/test/zero_at_34/') @app.route('/test/zero_at_/') 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/') def test_range_for(chart): graph = CHARTS_BY_NAME[chart]() graph.range = [0, 100] graph.add('1', [1, 2, 10]) return graph.render_response() @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/') 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/') 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/') 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() @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' 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() @app.route('/test/config') def test_config(): class LolConfig(Config): js = ['http://l:2343/2.0.x/pygal-tooltips.js'] stacked = StackedBar(LolConfig()) stacked.add('', [1, 2, 3]) stacked.add('My beautiful serie of 2019', [4, 5, 6]) 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())) ) # 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}) wmap.title = 'World Map !!' wmap.value_formatter = lambda x: '%d%%' % x return wmap.render_response() @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)]) wmap.title = 'Supra World Map !!' return wmap.render_response() @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)]) fmap.title = 'French map' return fmap.render_response() @app.route('/test/swissmap') def test_swissmap(): smap = ch.Cantons(style=choice(list(styles.values()))) for i in range(10): smap.add( 's%d' % i, [(choice(list(ch.CANTONS.keys())), randint(0, 100)) 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() @app.route('/test/frenchmapregions') def test_frenchmapregions(): if fr is None: abort(404) fmap = fr.Regions(style=choice(list(styles.values()))) for i in range(10): fmap.add( 's%d' % i, [(choice(list(fr.REGIONS.keys())), randint(0, 100)) 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() @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(1, title=str(i) if i % 5 == 1 else None) 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/') 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/') 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/') 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/') 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/') 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/') 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/') 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/') 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/') 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/') 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() from datetime import timezone, timedelta tz7 = timezone(timedelta(hours=7), 'GMT +7') tzn4 = timezone(timedelta(hours=-4), 'GMT -4') line.add( 'dt', [(datetime(2013, 1, 12, 8, tzinfo=tz7), 300), (datetime(2013, 1, 12, 8), 412), (datetime(2013, 1, 12, 8, tzinfo=tzn4), 823)] ) 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 line.x_value_formatter = lambda x: ( x.replace(tzinfo=timezone.utc).astimezone(tz)).isoformat() # 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/') def test_legend_link_for(chart): chart = CHARTS_BY_NAME[chart]() # link on chart and label chart.add([{ 'value': 2, 'label': 'This is red', 'tooltip': 'LOOLLOLOLO', 'xlink': { 'href': 'http://en.wikipedia.org/wiki/Red' } }], title={ 'title': 'Red', 'tooltip': 'Cramoisi', '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/') def test_gradient_for(chart): config = Config() config.style = styles['dark'] config.defs.append( ''' ''' ) config.defs.append( ''' ''' ) 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)]) # chart.add('approx', [ # special.erfinv(x/1000) - erfinv(x/1000) # for x in range(-999, 1000)]) return chart.render_response() @app.route('/test/ci/') 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() ) ) )