def __init__(self, graph): self.graph = graph if not graph.no_prefix: self.id = '#chart-%s ' % graph.uuid else: self.id = '' self.processing_instructions = [ etree.PI(u('xml'), u("version='1.0' encoding='utf-8'"))] self.root = etree.Element( "{%s}svg" % self.ns, nsmap={ None: self.ns, 'xlink': 'http://www.w3.org/1999/xlink', }) self.root.attrib['id'] = self.id.lstrip('#').rstrip() self.root.attrib['class'] = 'pygal-chart' self.root.append( etree.Comment(u( 'Generated with pygal %s ©Kozea 2011-2014 on %s' % ( __version__, date.today().isoformat())))) self.root.append(etree.Comment(u('http://pygal.org'))) self.root.append(etree.Comment(u('http://github.com/Kozea/pygal'))) self.defs = self.node(tag='defs') self.title = self.node(tag='title') self.title.text = graph.title or 'Pygal'
def add_styles(self): """Add the css to the svg""" colors = self.graph.config.style.get_colors(self.id) all_css = [] for css in ['base.css'] + list(self.graph.css): if '://' in css: self.processing_instructions.append( etree.PI( u('xml-stylesheet'), u('href="%s"' % css))) else: if css.startswith('inline:'): css_text = css[len('inline:'):] else: if not os.path.exists(css): css = os.path.join( os.path.dirname(__file__), 'css', css) with io.open(css, encoding='utf-8') as f: css_text = template( f.read(), style=self.graph.config.style, colors=colors, font_sizes=self.graph.config.font_sizes(), id=self.id) if not self.graph.pretty_print: css_text = minify_css(css_text) all_css.append(css_text) self.node( self.defs, 'style', type='text/css').text = '\n'.join(all_css)
def test_no_data(): line = Line() q = line.render_pyquery() assert q(".text-overlay text").text() == "No data" line.no_data_text = u("þæ®þ怀&ij¿’€") q = line.render_pyquery() assert q(".text-overlay text").text() == u("þæ®þ怀&ij¿’€")
def test_value_formatter(): line = Line(value_formatter=lambda x: str(x) + u('‰')) line.add('_', [10 ** 4, 10 ** 5, 23 * 10 ** 4]) q = line.render_pyquery() assert len(q(".y.axis .guides")) == 11 assert q(".axis.y text").map(texts) == list(map( lambda x: str(x) + u('‰'), map(float, range(20000, 240000, 20000))))
def render_sparktext(self, relative_to=None): """Make a mini text sparkline from chart""" bars = u('▁▂▃▄▅▆▇█') if len(self.raw_series) == 0: return u('') values = list(self.raw_series[0][1]) if len(values) == 0: return u('') chart = u('') values = list(map(lambda x: max(x, 0), values)) vmax = max(values) if relative_to is None: relative_to = min(values) if (vmax - relative_to) == 0: chart = bars[0] * len(values) return chart divisions = len(bars) - 1 for value in values: chart += bars[int(divisions * (value - relative_to) / (vmax - relative_to))] return chart
def add_styles(self): """Add the css to the svg""" colors = self.graph.style.get_colors(self.id, self.graph._order) strokes = self.get_strokes() all_css = [] for css in ["base.css"] + list(self.graph.css): if "://" in css: self.processing_instructions.append(etree.PI(u("xml-stylesheet"), u('href="%s"' % css))) else: if css.startswith("inline:"): css_text = css[len("inline:") :] else: if not os.path.exists(css): css = os.path.join(os.path.dirname(__file__), "css", css) class FontSizes(object): """Container for font sizes""" fs = FontSizes() for name in dir(self.graph.state): if name.endswith("_font_size"): setattr(fs, name.replace("_font_size", ""), ("%dpx" % getattr(self.graph, name))) with io.open(css, encoding="utf-8") as f: css_text = template( f.read(), style=self.graph.style, colors=colors, strokes=strokes, font_sizes=fs, id=self.id ) if not self.graph.pretty_print: css_text = minify_css(css_text) all_css.append(css_text) self.node(self.defs, "style", type="text/css").text = "\n".join(all_css)
def test_render_data_uri(Chart): """Test the render data uri""" chart = Chart(fill=True) chart.add(u('ééé'), [1, 2, 3]) chart.add(u('èèè'), [10, 21, 5]) assert chart.render_data_uri().startswith( 'data:image/svg+xml;charset=utf-8;base64,')
def add_styles(self): """Add the css to the svg""" colors = self.graph.style.get_colors(self.id, self.graph._order) strokes = self.get_strokes() all_css = [] auto_css = ["file://base.css"] if self.graph.style._google_fonts: auto_css.append( "//fonts.googleapis.com/css?family=%s" % quote_plus("|".join(self.graph.style._google_fonts)) ) for css in auto_css + list(self.graph.css): css_text = None if css.startswith("inline:"): css_text = css[len("inline:") :] elif css.startswith("file://"): css = css[len("file://") :] if not os.path.exists(css): css = os.path.join(os.path.dirname(__file__), "css", css) with io.open(css, encoding="utf-8") as f: css_text = template(f.read(), style=self.graph.style, colors=colors, strokes=strokes, id=self.id) if css_text is not None: if not self.graph.pretty_print: css_text = minify_css(css_text) all_css.append(css_text) else: if css.startswith("//") and self.graph.force_uri_protocol: css = "%s:%s" % (self.graph.force_uri_protocol, css) self.processing_instructions.append(etree.PI(u("xml-stylesheet"), u('href="%s"' % css))) self.node(self.defs, "style", type="text/css").text = "\n".join(all_css)
def __init__(self, graph): """Create the svg helper with the chart instance""" self.graph = graph if not graph.no_prefix: self.id = "#chart-%s " % graph.uuid else: self.id = "" self.processing_instructions = [etree.ProcessingInstruction(u("xml"), u("version='1.0' encoding='utf-8'"))] if etree.lxml: attrs = {"nsmap": {None: self.ns, "xlink": self.xlink_ns}} else: attrs = {"xmlns": self.ns} if hasattr(etree, "register_namespace"): etree.register_namespace("xlink", self.xlink_ns) else: etree._namespace_map[self.xlink_ns] = "xlink" self.root = etree.Element("svg", **attrs) self.root.attrib["id"] = self.id.lstrip("#").rstrip() self.root.attrib["class"] = "pygal-chart" self.root.append( etree.Comment( u( "Generated with pygal %s (%s) ©Kozea 2011-2015 on %s" % (__version__, "lxml" if etree.lxml else "etree", date.today().isoformat()) ) ) ) self.root.append(etree.Comment(u("http://pygal.org"))) self.root.append(etree.Comment(u("http://github.com/Kozea/pygal"))) self.defs = self.node(tag="defs") self.title = self.node(tag="title") self.title.text = graph.title or "Pygal"
def test_no_data_sparktext(): """Test no data sparktext""" chart2 = Line() chart2.add('_', []) assert chart2.render_sparktext() == u('') chart3 = Line() assert chart3.render_sparktext() == u('')
def test_same_max_and_relative_values_sparktext(): chart = Line() chart.add('_', [0, 0, 0, 0, 0]) assert chart.render_sparktext() == u('▁▁▁▁▁') chart2 = Line() chart2.add('_', [1, 1, 1, 1, 1]) assert chart2.render_sparktext(relative_to=1) == u('▁▁▁▁▁')
def test_truncate(): assert truncate('1234567890', 50) == '1234567890' assert truncate('1234567890', 5) == u('1234…') assert truncate('1234567890', 1) == u('…') assert truncate('1234567890', 9) == u('12345678…') assert truncate('1234567890', 10) == '1234567890' assert truncate('1234567890', 0) == '1234567890' assert truncate('1234567890', -1) == '1234567890'
def test_truncate(): """Test truncate function""" assert truncate('1234567890', 50) == '1234567890' assert truncate('1234567890', 5) == u('1234…') assert truncate('1234567890', 1) == u('…') assert truncate('1234567890', 9) == u('12345678…') assert truncate('1234567890', 10) == '1234567890' assert truncate('1234567890', 0) == '1234567890' assert truncate('1234567890', -1) == '1234567890'
def test_negative_and_float_and_no_data_sparktext(): chart = Line() chart.add('_', [0.1, 0.2, 0.9, -0.5]) assert chart.render_sparktext() == u('▁▂█▁') chart2 = Line() chart2.add('_', []) assert chart2.render_sparktext() == u('') chart3 = Line() assert chart3.render_sparktext() == u('')
def add_styles(self): """Add the css to the svg""" colors = self.graph.style.get_colors(self.id, self.graph._order) strokes = self.get_strokes() all_css = [] auto_css = [base_css] if self.graph.style._google_fonts: auto_css.append( '//fonts.googleapis.com/css?family=%s' % quote_plus( '|'.join(self.graph.style._google_fonts)) ) for css in auto_css + list(self.graph.css): css_text = None if type(css) == str and css.startswith('inline:'): css_text = css[len('inline:'):] elif type(css) == str and css.startswith('file://'): if not os.path.exists(css): css = os.path.join( os.path.dirname(__file__), 'css', css[len('file://'):]) with io.open(css, encoding='utf-8') as f: css_text = template( f.read(), style=self.graph.style, colors=colors, strokes=strokes, id=self.id) elif not type(css) == str: css_text = template( css.data, style=self.graph.style, colors=colors, strokes=strokes, id=self.id) if css_text is not None: if not self.graph.pretty_print: css_text = minify_css(css_text) all_css.append(css_text) else: if type(css) == str and css.startswith('//') and self.graph.force_uri_protocol: css = '%s:%s' % (self.graph.force_uri_protocol, css) self.processing_instructions.append( etree.PI( u('xml-stylesheet'), u('href="%s"' % css))) self.node( self.defs, 'style', type='text/css').text = '\n'.join(all_css)
def test_swap_curly(): """Test swap curly function""" for str in ('foo', u('foo foo foo bar'), 'foo béè b¡ð/ijə˘©þß®~¯æ', u('foo béè b¡ð/ijə˘©þß®~¯æ')): assert _swap_curly(str) == str assert _swap_curly('foo{bar}baz') == 'foo{{bar}}baz' assert _swap_curly('foo{{bar}}baz') == 'foo{bar}baz' assert _swap_curly('{foo}{{bar}}{baz}') == '{{foo}}{bar}{{baz}}' assert _swap_curly('{foo}{{{bar}}}{baz}') == '{{foo}}{{{bar}}}{{baz}}' assert _swap_curly('foo{ bar }baz') == 'foo{{ bar }}baz' assert _swap_curly('foo{ bar}baz') == 'foo{{ bar}}baz' assert _swap_curly('foo{bar }baz') == 'foo{{bar }}baz' assert _swap_curly('foo{{ bar }}baz') == 'foo{bar}baz' assert _swap_curly('foo{{bar }}baz') == 'foo{bar}baz' assert _swap_curly('foo{{ bar}}baz') == 'foo{bar}baz'
def test_another_sparktext(): chart = Line() chart.add('_', [0, 30, 55, 80, 33, 150]) assert chart.render_sparktext() == u('▁▂▃▄▂█') assert chart.render_sparktext() == chart.render_sparktext() chart2 = Bar() chart2.add('_', [0, 30, 55, 80, 33, 150]) assert chart2.render_sparktext() == chart.render_sparktext()
def test_another_sparktext(): """Test that same data produces same sparktext""" chart = Line() chart.add('_', [0, 30, 55, 80, 33, 150]) assert chart.render_sparktext() == u('▁▂▃▄▂█') assert chart.render_sparktext() == chart.render_sparktext() chart2 = Bar() chart2.add('_', [0, 30, 55, 80, 33, 150]) assert chart2.render_sparktext() == chart.render_sparktext()
def __init__(self, graph): self.graph = graph self.processing_instructions = [ etree.PI(u('xml'), u("version='1.0' encoding='utf-8'"))] self.root = etree.Element( "{%s}svg" % self.ns, nsmap={ None: self.ns, 'xlink': 'http://www.w3.org/1999/xlink', }) self.root.append( etree.Comment(u( 'Generated with pygal %s ©Kozea 2011-2013 on %s' % ( __version__, date.today().isoformat())))) self.root.append(etree.Comment(u('http://pygal.org'))) self.root.append(etree.Comment(u('http://github.com/Kozea/pygal'))) self.defs = self.node(tag='defs') self.title = self.node(tag='title') self.title.text = graph.title or 'Pygal'
def __init__(self, graph): """Create the svg helper with the chart instance""" self.graph = graph if not graph.no_prefix: self.id = '#chart-%s ' % graph.uuid else: self.id = '' self.processing_instructions = [ etree.ProcessingInstruction( u('xml'), u("version='1.0' encoding='utf-8'"))] if etree.lxml: attrs = { 'nsmap': { None: self.ns, 'xlink': self.xlink_ns } } else: attrs = { 'xmlns': self.ns } if hasattr(etree, 'register_namespace'): etree.register_namespace('xlink', self.xlink_ns) else: etree._namespace_map[self.xlink_ns] = 'xlink' self.root = etree.Element('svg', **attrs) self.root.attrib['id'] = self.id.lstrip('#').rstrip() self.root.attrib['class'] = 'pygal-chart' self.root.append( etree.Comment(u( 'Generated with pygal %s (%s) ©Kozea 2011-2015 on %s' % ( __version__, 'lxml' if etree.lxml else 'etree', date.today().isoformat())))) self.root.append(etree.Comment(u('http://pygal.org'))) self.root.append(etree.Comment(u('http://github.com/Kozea/pygal'))) self.defs = self.node(tag='defs') self.title = self.node(tag='title') self.title.text = graph.title or 'Pygal' for def_ in self.graph.defs: self.defs.append(etree.fromstring(def_))
def add_styles(self): """Add the css to the svg""" for css in ['base.css'] + list(self.graph.css): if urlparse(css).scheme: self.processing_instructions.append( etree.PI( u('xml-stylesheet'), u('href="%s"' % css))) else: if not os.path.exists(css): css = os.path.join( os.path.dirname(__file__), 'css', css) with io.open(css, encoding='utf-8') as f: css_text = template( f.read(), style=self.graph.style, font_sizes=self.graph.font_sizes()) if not self.graph.pretty_print: css_text = minify_css(css_text) self.node( self.defs, 'style', type='text/css').text = css_text
def add_styles(self): """Add the css to the svg""" colors = self.graph.style.get_colors(self.id, self.graph._order) strokes = self.get_strokes() all_css = [] auto_css = [] #['file://base.css'] if self.graph.style._google_fonts: auto_css.append( '//fonts.googleapis.com/css?family=%s' % quote_plus('|'.join(self.graph.style._google_fonts))) for css in auto_css + list(self.graph.css): css_text = None if css.startswith('inline:'): css_text = css[len('inline:'):] elif css.startswith('file://'): css = css[len('file://'):] if not os.path.exists(css): css = os.path.join(os.path.dirname(__file__), 'css', css) with io.open(css, encoding='utf-8') as f: css_text = template(f.read(), style=self.graph.style, colors=colors, strokes=strokes, id=self.id) if css_text is not None: if not self.graph.pretty_print: css_text = minify_css(css_text) all_css.append(css_text) else: if css.startswith('//') and self.graph.force_uri_protocol: css = '%s:%s' % (self.graph.force_uri_protocol, css) self.processing_instructions.append( etree.PI(u('xml-stylesheet'), u('href="%s"' % css))) if auto_css: self.node(self.defs, 'style', type='text/css').text = '\n'.join(all_css)
def humanize(number): """Format a number to engineer scale""" if is_list_like(number): return ', '.join(map(humanize, number)) if number is None: return u('∅') order = number and int(floor(log(abs(number)) / log(1000))) human_readable = ORDERS.split(" ")[int(order > 0)] if order == 0 or order > len(human_readable): return float_format(number / (1000**int(order))) return (float_format(number / (1000**int(order))) + human_readable[int(order) - int(order > 0)])
def test_human_readable(): """Test human_readable formatter""" f = formatters.human_readable assert f(1) == "1" assert f(1.0) == "1" assert f(10) == "10" assert f(12.5) == "12.5" assert f(1000) == "1k" assert f(5000) == "5k" assert f(100000) == "100k" assert f(1253) == "1.253k" assert f(1250) == "1.25k" assert f(0.1) == "100m" assert f(0.01) == "10m" assert f(0.001) == "1m" assert f(0.002) == "2m" assert f(0.0025) == "2.5m" assert f(0.0001) == u("100µ") assert f(0.000123) == u("123µ") assert f(0.00001) == u("10µ") assert f(0.000001) == u("1µ") assert f(0.0000001) == u("100n") assert f(0.0000000001) == u("100p") assert f(0) == "0" assert f(0.0) == "0" assert f(-1337) == "-1.337k" assert f(-0.000000042) == "-42n"
def test_human_readable(): """Test human_readable formatter""" f = formatters.human_readable assert f(1) == '1' assert f(1.) == '1' assert f(10) == '10' assert f(12.5) == '12.5' assert f(1000) == '1k' assert f(5000) == '5k' assert f(100000) == '100k' assert f(1253) == '1.253k' assert f(1250) == '1.25k' assert f(0.1) == '100m' assert f(0.01) == '10m' assert f(0.001) == '1m' assert f(0.002) == '2m' assert f(0.0025) == '2.5m' assert f(0.0001) == u('100µ') assert f(0.000123) == u('123µ') assert f(0.00001) == u('10µ') assert f(0.000001) == u('1µ') assert f(0.0000001) == u('100n') assert f(0.0000000001) == u('100p') assert f(0) == '0' assert f(0.) == '0' assert f(-1337) == '-1.337k' assert f(-.000000042) == '-42n'
def test_humanize(): """Test humanize function""" assert humanize(1) == '1' assert humanize(1.) == '1' assert humanize(10) == '10' assert humanize(12.5) == '12.5' assert humanize(1000) == '1k' assert humanize(5000) == '5k' assert humanize(100000) == '100k' assert humanize(1253) == '1.253k' assert humanize(1250) == '1.25k' assert humanize(0.1) == '100m' assert humanize(0.01) == '10m' assert humanize(0.001) == '1m' assert humanize(0.002) == '2m' assert humanize(0.0025) == '2.5m' assert humanize(0.0001) == u('100µ') assert humanize(0.000123) == u('123µ') assert humanize(0.00001) == u('10µ') assert humanize(0.000001) == u('1µ') assert humanize(0.0000001) == u('100n') assert humanize(0.0000000001) == u('100p') assert humanize(0) == '0' assert humanize(0.) == '0' assert humanize(-1337) == '-1.337k' assert humanize(-.000000042) == '-42n'
def test_humanize(): assert humanize(1) == '1' assert humanize(1.) == '1' assert humanize(10) == '10' assert humanize(12.5) == '12.5' assert humanize(1000) == '1k' assert humanize(5000) == '5k' assert humanize(100000) == '100k' assert humanize(1253) == '1.253k' assert humanize(1250) == '1.25k' assert humanize(0.1) == '100m' assert humanize(0.01) == '10m' assert humanize(0.001) == '1m' assert humanize(0.002) == '2m' assert humanize(0.0025) == '2.5m' assert humanize(0.0001) == u('100µ') assert humanize(0.000123) == u('123µ') assert humanize(0.00001) == u('10µ') assert humanize(0.000001) == u('1µ') assert humanize(0.0000001) == u('100n') assert humanize(0.0000000001) == u('100p') assert humanize(0) == '0' assert humanize(0.) == '0' assert humanize(-1337) == '-1.337k' assert humanize(-.000000042) == '-42n'
def __init__(self, graph): """Create the svg helper with the chart instance""" self.graph = graph if not graph.no_prefix: self.id = '#chart-%s ' % graph.uuid else: self.id = '' self.processing_instructions = [] if etree.lxml: attrs = {'nsmap': {None: self.ns, 'xlink': self.xlink_ns}} else: attrs = {'xmlns': self.ns} if hasattr(etree, 'register_namespace'): etree.register_namespace('xlink', self.xlink_ns) else: etree._namespace_map[self.xlink_ns] = 'xlink' self.root = etree.Element('svg', **attrs) self.root.attrib['id'] = self.id.lstrip('#').rstrip() if graph.classes: self.root.attrib['class'] = ' '.join(graph.classes) self.root.append( etree.Comment( u( 'Generated with pygal %s (%s) ©Kozea 2012-2016 on %s' % ( __version__, 'lxml' if etree.lxml else 'etree', date.today().isoformat() ) ) ) ) self.root.append(etree.Comment(u('http://pygal.org'))) self.root.append(etree.Comment(u('http://github.com/Kozea/pygal'))) self.defs = self.node(tag='defs') self.title = self.node(tag='title') self.title.text = graph.title or 'Pygal' for def_ in self.graph.defs: self.defs.append(etree.fromstring(def_))
def add_styles(self): """Add the css to the svg""" colors = self.graph.style.get_colors(self.id) all_css = [] for css in ['base.css'] + list(self.graph.css): if '://' in css: self.processing_instructions.append( etree.PI(u('xml-stylesheet'), u('href="%s"' % css))) else: if not os.path.exists(css): css = os.path.join(os.path.dirname(__file__), 'css', css) with io.open(css, encoding='utf-8') as f: css_text = template(f.read(), style=self.graph.style, colors=colors, font_sizes=self.graph.font_sizes(), id=self.id) if not self.graph.pretty_print: css_text = minify_css(css_text) all_css.append(css_text) self.node(self.defs, 'style', type='text/css').text = '\n'.join(all_css)
def add_styles(self): """Add the css to the svg""" colors = self.graph.style.get_colors(self.id) all_css = [] for css in ['base.css'] + list(self.graph.css): if '://' in css: self.processing_instructions.append( etree.PI( u('xml-stylesheet'), u('href="%s"' % css))) else: if css.startswith('inline:'): css_text = css[len('inline:'):] else: if not os.path.exists(css): css = os.path.join( os.path.dirname(__file__), 'css', css) class FontSizes(object): """Container for font sizes""" fs = FontSizes() for name in dir(self.graph.state): if name.endswith('_font_size'): setattr( fs, name.replace('_font_size', ''), ('%dpx' % getattr(self.graph, name))) with io.open(css, encoding='utf-8') as f: css_text = template( f.read(), style=self.graph.style, colors=colors, font_sizes=fs, id=self.id) if not self.graph.pretty_print: css_text = minify_css(css_text) all_css.append(css_text) self.node( self.defs, 'style', type='text/css').text = '\n'.join(all_css)
def humanize(number): """Format a number to engineer scale""" if is_list_like(number): return', '.join(map(humanize, number)) if number is None: return u('∅') order = number and int(floor(log(abs(number)) / log(1000))) human_readable = ORDERS.split(" ")[int(order > 0)] if order == 0 or order > len(human_readable): return float_format(number / (1000 ** int(order))) return ( float_format(number / (1000 ** int(order))) + human_readable[int(order) - int(order > 0)])
def __init__(self, graph): self.graph = graph if not graph.no_prefix: self.id = '#chart-%s ' % graph.uuid else: self.id = '' self.processing_instructions = [ etree.ProcessingInstruction( u('xml'), u("version='1.0' encoding='utf-8'"))] if etree.lxml: attrs = { 'nsmap': { None: self.ns, 'xlink': self.xlink_ns } } else: attrs = { 'xmlns': self.ns } if hasattr(etree, 'register_namespace'): etree.register_namespace('xlink', self.xlink_ns) else: etree._namespace_map[self.xlink_ns] = 'xlink' self.root = etree.Element('svg', **attrs) self.root.attrib['id'] = self.id.lstrip('#').rstrip() self.root.attrib['class'] = 'pygal-chart' self.root.append( etree.Comment(u( 'Generated with pygal %s (%s) ©Kozea 2011-2014 on %s' % ( __version__, 'lxml' if etree.lxml else 'etree', date.today().isoformat())))) self.root.append(etree.Comment(u('http://pygal.org'))) self.root.append(etree.Comment(u('http://github.com/Kozea/pygal'))) self.defs = self.node(tag='defs') self.title = self.node(tag='title') self.title.text = graph.title or 'Pygal'
def test_unicode_labels_python3(Chart): if sys.version_info[0] == 2: return chart = Chart() chart.add( u("Série1"), [ {"value": 1, "xlink": "http://1/", "label": eval("'{\}°ijæð©&×&<—×€¿_…\{_…'")}, {"value": 2, "xlink": {"href": "http://6.example.com/"}, "label": eval("'æ°€≠|€æ°€əæ'")}, {"value": 3, "label": eval("b'unicode <3'")}, ], ) chart.x_labels = eval("['&œ', '¿?', '††††††††', 'unicode <3']") chart.render_pyquery()
def __init__(self, graph): self.graph = graph if not graph.no_prefix: self.id = '#chart-%s ' % graph.uuid else: self.id = '' self.root = etree.Element( "{%s}svg" % self.ns, nsmap={ None: self.ns, 'xlink': 'http://www.w3.org/1999/xlink', }) self.root.attrib['id'] = self.id.lstrip('#').rstrip() self.root.attrib['class'] = 'pygal-chart' self.root.append( etree.Comment(u( 'Generated with pygal %s ©Kozea 2011-2014 on %s' % ( __version__, date.today().isoformat())))) self.root.append(etree.Comment(u('http://pygal.org'))) self.root.append(etree.Comment(u('http://github.com/Kozea/pygal'))) self.defs = self.node(tag='defs') self.title = self.node(tag='title') self.title.text = graph.title or 'Pygal' self.processing_instructions = []
class HumanReadable(Formatter): """Format a number to engineer scale""" ORDERS = u("yzafpnµm kMGTPEZY") def __init__(self, none_char=u('∅')): self.none_char = none_char def __call__(self, val): if val is None: return self.none_char order = val and int(floor(log(abs(val)) / log(1000))) orders = self.ORDERS.split(" ")[int(order > 0)] if order == 0 or order > len(orders): return float_format(val / (1000**int(order))) return (float_format(val / (1000**int(order))) + orders[int(order) - int(order > 0)])
def test_formatters(Chart): """Test custom formatters""" if Chart._dual or Chart == Box: return chart = Chart(formatter=lambda x, chart, serie: '%s%s$' % (x, serie.title)) chart.add('_a', [1, 2, {'value': 3, 'formatter': lambda x: u('%s¥') % x}]) chart.add('_b', [4, 5, 6], formatter=lambda x: u('%s€') % x) chart.x_labels = [2, 4, 6] chart.x_labels_major = [4] q = chart.render_pyquery() assert set( [v.text for v in q(".value")] ) == set((u('4€'), u('5€'), u('6€'), '1_a$', '2_a$', u('3¥')) + (('6_a$', u('15€')) if Chart in (Pie, SolidGauge) else ()))
def test_formatters(Chart): """Test custom formatters""" if Chart._dual or Chart == Box: return chart = Chart(formatter=lambda x, chart, serie: '%s%s$' % ( x, serie.title)) chart.add('_a', [1, 2, {'value': 3, 'formatter': lambda x: u('%s¥') % x}]) chart.add('_b', [4, 5, 6], formatter=lambda x: u('%s€') % x) chart.x_labels = [2, 4, 6] chart.x_labels_major = [4] q = chart.render_pyquery() assert set([v.text for v in q(".value")]) == set(( u('4€'), u('5€'), u('6€'), '1_a$', '2_a$', u('3¥')) + ( ('6_a$', u('15€')) if Chart in (Pie, SolidGauge) else ()))
def test_unicode_labels_decode(Chart): chart = Chart() chart.add( u("Série1"), [ {"value": 1, "xlink": "http://1/", "label": u("{\}°ijæð©&×&<—×€¿_…\{_…")}, {"value": 2, "xlink": {"href": "http://6.example.com/"}, "label": u("æ°€≠|€æ°€əæ")}, {"value": 3, "label": "unicode <3"}, ], ) chart.x_labels = [u("&œ"), u("¿?"), u("††††††††"), "unicode <3"] chart.render_pyquery()
def test_unicode_labels_python3(Chart): if sys.version_info[0] == 2: return chart = Chart() chart.add(u('Série1'), [{ 'value': 1, 'xlink': 'http://1/', 'label': eval("'{\}°ijæð©&×&<—×€¿_…\{_…'") }, { 'value': 2, 'xlink': { 'href': 'http://6.example.com/' }, 'label': eval("'æ°€≠|€æ°€əæ'") }, { 'value': 3, 'label': eval("b'unicode <3'") }]) chart.x_labels = eval("['&œ', '¿?', '††††††††', 'unicode <3']") chart.render_pyquery()
def test_unicode_labels_python2(Chart): """Test unicode labels in python 2""" if sys.version_info[0] == 3: return chart = Chart() chart.add(u('Série1'), [{ 'value': 1, 'xlink': 'http://1/', 'label': eval("u'{\}°ijæð©&×&<—×€¿_…\{_…'") }, { 'value': 2, 'xlink': { 'href': 'http://6.example.com/' }, 'label': eval("u'æ°€≠|€æ°€əæ'") }, { 'value': 3, 'label': eval("'unicode <3'") }]) if not chart._dual: chart.x_labels = eval("[u'&œ', u'¿?', u'††††††††', 'unicode <3']") chart.render_pyquery()
def test_unicode_labels_decode(Chart): chart = Chart() chart.add(u('Série1'), [{ 'value': 1, 'xlink': 'http://1/', 'label': u('{\}°ijæð©&×&<—×€¿_…\{_…') }, { 'value': 2, 'xlink': { 'href': 'http://6.example.com/' }, 'label': u('æ°€≠|€æ°€əæ') }, { 'value': 3, 'label': 'unicode <3' }]) chart.x_labels = [u('&œ'), u('¿?'), u('††††††††'), 'unicode <3'] chart.render_pyquery()
def test_shifted_sparktext(): chart = Line() chart.add('_', list(map(lambda x: x + 10000, range(8)))) assert chart.render_sparktext() == u('▁▂▃▄▅▆▇█') assert chart.render_sparktext(relative_to=0) == u('▇▇▇▇▇▇▇█')
def test_human_readable_custom(): """Test human_readable formatter option""" f = formatters.HumanReadable() assert f(None) == u('∅') f = formatters.HumanReadable(none_char='/') assert f(None) == '/'
def test_all_sparktext(): """Test all character sparktext""" chart = Line() chart.add('_', range(8)) assert chart.render_sparktext() == u('▁▂▃▄▅▆▇█')
def test_negative_and_float__sparktext(): """Test negative values""" """Test negative values""" chart = Line() chart.add('_', [0.1, 0.2, 0.9, -0.5]) assert chart.render_sparktext() == u('▁▂█▁')
Worldmap chart """ from __future__ import division from collections import defaultdict from pygal.ghost import ChartCollection from pygal.util import cut, cached_property, decorate from pygal.graph.graph import Graph from pygal._compat import u from pygal.etree import etree from numbers import Number import os DEPARTMENTS = { '01': u("Ain"), '02': u("Aisne"), '03': u("Allier"), '04': u("Alpes-de-Haute-Provence"), '05': u("Hautes-Alpes"), '06': u("Alpes-Maritimes"), '07': u("Ardèche"), '08': u("Ardennes"), '09': u("Ariège"), '10': u("Aube"), '11': u("Aude"), '12': u("Aveyron"), '13': u("Bouches-du-Rhône"), '14': u("Calvados"), '15': u("Cantal"), '16': u("Charente"),
""" from __future__ import division from collections import defaultdict from pygal.graph.map import BaseMap from pygal._compat import u from numbers import Number import os ''' https://en.wikipedia.org/wiki/List_of_districts_in_India ''' DISTRICTS = { 'AN-NI': u("Nicobar"), 'AN-NA': u("North and Middle Andaman"), 'AN-SA': u("South Andaman"), 'AP-AN': u("Anantapur"), 'AP-CH': u("Chittoor"), 'AP-EG': u("East Godavari"), 'AP-GU': u("Guntur"), 'AP-CU': u("Kadapa"), 'AP-KR': u("Krishna"), 'AP-KU': u("Kurnool"), 'AP-PR': u("Prakasam"), 'AP-NE': u("Nellore"), 'AP-SR': u("Srikakulam"), 'AP-VS': u("Visakhapatnam"), 'AP-VZ': u("Vizianagaram"), 'AP-WG': u("West Godavari"),
def test_basic_sparktext(): chart = Line() chart.add('_', [1, 5, 22, 13, 53]) assert chart.render_sparktext() == u('▁▁▃▂█')
def test_all_sparktext(): chart = Line() chart.add('_', range(8)) assert chart.render_sparktext() == u('▁▂▃▄▅▆▇█')
# # You should have received a copy of the GNU Lesser General Public License # along with pygal. If not, see <http://www.gnu.org/licenses/>. """ Various utils """ from __future__ import division from pygal._compat import to_str, u, is_list_like import re from decimal import Decimal from math import floor, pi, log, log10, ceil from itertools import cycle from functools import reduce from pygal.adapters import not_zero, positive ORDERS = u("yzafpnµm kMGTPEZY") def float_format(number): """Format a float to a precision of 3, without zeroes or dots""" return ("%.3f" % number).rstrip('0').rstrip('.') def humanize(number): """Format a number to engineer scale""" order = number and int(floor(log(abs(number)) / log(1000))) human_readable = ORDERS.split(" ")[int(order > 0)] if order == 0 or order > len(human_readable): return float_format(number / (1000**int(order))) return (float_format(number / (1000**int(order))) + human_readable[int(order) - int(order > 0)])
def __init__(self, none_char=u('∅')): self.none_char = none_char
def truncate(string, index): """Truncate a string at index and add ...""" if len(string) > index and index > 0: string = string[:index - 1] + u('…') return string