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:'):] elif css in ('base.css', 'style.css', 'graph.css'): css_text = template( {'base.css': base_css, 'style.css': style_css, 'graph.css': graph_css}[css].contents, style=self.graph.config.style, colors=colors, font_sizes=self.graph.config.font_sizes(), id=self.id) else: 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_format(): assert template('foo {{ baz }}', baz='bar') == 'foo bar' with raises(KeyError): assert template('foo {{ baz }}') == 'foo baz' class Object(object): pass obj = Object() obj.a = 1 obj.b = True obj.c = '3' assert template('foo {{ o.a }} {{o.b}}-{{o.c}}', o=obj) == 'foo 1 True-3'
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 = ['template://{}'.format(CSS_BASE)] 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('template://'): css = css[len('template://'):] css_text = template(css, style=self.graph.style, colors=colors, strokes=strokes, id=self.id) 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 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 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 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 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 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 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 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""" 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) 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 add_styles(self): """Add the css to the svg""" css_texts = [] 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) css_texts.append(css_text) self.node( self.defs, 'style', type='text/css').text = '\n'.join(css_texts)
def render(self, total=False, transpose=False, style=False): """Render the HTMTL table of the chart. `total` can be specified to include data sums `transpose` make labels becomes columns `style` include scoped style for the table """ self.chart.setup() ln = self.chart._len fmt = self.chart._format html = HTML() attrs = {} if style: attrs['id'] = 'table-%s' % uuid.uuid4() table = [] _ = lambda x: x if x is not None else '' if self.chart.x_labels: labels = [None] + list(self.chart.x_labels) if len(labels) < ln: labels += [None] * (ln + 1 - len(labels)) if len(labels) > ln + 1: labels = labels[:ln + 1] table.append(labels) if total: if len(table): table[0].append('Total') else: table.append([None] * (ln + 1) + ['Total']) acc = [0] * (ln + 1) for i, serie in enumerate(self.chart.all_series): row = [serie.title] if total: sum_ = 0 for j, value in enumerate(serie.values): if total: v = value or 0 acc[j] += v sum_ += v row.append(fmt(value)) if total: acc[-1] += sum_ row.append(fmt(sum_)) table.append(row) width = ln + 1 if total: width += 1 table.append(['Total']) for val in acc: table[-1].append(fmt(val)) # Align values len_ = max([len(r) for r in table] or [0]) for i, row in enumerate(table[:]): len_ = len(row) if len_ < width: table[i] = row + [None] * (width - len_) if not transpose: table = list(zip(*table)) thead = [] tbody = [] tfoot = [] if not transpose or self.chart.x_labels: # There's always series title but not always x_labels thead = [table[0]] tbody = table[1:] else: tbody = table if total: tfoot = [tbody[-1]] tbody = tbody[:-1] parts = [] if thead: parts.append( html.thead( *[html.tr(*[html.th(_(col)) for col in r]) for r in thead])) if tbody: parts.append( html.tbody( *[html.tr(*[html.td(_(col)) for col in r]) for r in tbody])) if tfoot: parts.append( html.tfoot( *[html.tr(*[html.th(_(col)) for col in r]) for r in tfoot])) table = tostring(html.table(*parts, **attrs)) if style: if style is True: css = ''' #{{ id }} { border-collapse: collapse; border-spacing: 0; empty-cells: show; border: 1px solid #cbcbcb; } #{{ id }} td, #{{ id }} th { border-left: 1px solid #cbcbcb; border-width: 0 0 0 1px; margin: 0; padding: 0.5em 1em; } #{{ id }} td:first-child, #{{ id }} th:first-child { border-left-width: 0; } #{{ id }} thead, #{{ id }} tfoot { color: #000; text-align: left; vertical-align: bottom; } #{{ id }} thead { background: #e0e0e0; } #{{ id }} tfoot { background: #ededed; } #{{ id }} tr:nth-child(2n-1) td { background-color: #f2f2f2; } ''' else: css = style table = tostring( html.style(template(css, **attrs), scoped='scoped')) + table table = table.decode('utf-8') self.chart.teardown() return table
def render(self, total=False, transpose=False, style=False): self.chart.setup() ln = self.chart._len fmt = self.chart._format html = HTML() attrs = {} if style: attrs['id'] = 'table-%s' % uuid.uuid4() table = [] _ = lambda x: x if x is not None else '' if self.chart.x_labels: labels = [None] + list(self.chart.x_labels) if len(labels) < ln: labels += [None] * (ln + 1 - len(labels)) if len(labels) > ln + 1: labels = labels[:ln + 1] table.append(labels) if total: if len(table): table[0].append('Total') else: table.append([None] * (ln + 1) + ['Total']) acc = [0] * (ln + 1) for i, serie in enumerate(self.chart.series): row = [serie.title] if total: sum_ = 0 for j, value in enumerate(serie.values): if total: v = value or 0 acc[j] += v sum_ += v row.append(fmt(value)) if total: acc[-1] += sum_ row.append(fmt(sum_)) table.append(row) width = ln + 1 if total: width += 1 table.append(['Total']) for val in acc: table[-1].append(fmt(val)) # Align values len_ = max([len(r) for r in table] or [0]) for i, row in enumerate(table[:]): len_ = len(row) if len_ < width: table[i] = row + [None] * (width - len_) if not transpose: table = list(zip(*table)) thead = [] tbody = [] tfoot = [] if not transpose or self.chart.x_labels: # There's always series title but not always x_labels thead = [table[0]] tbody = table[1:] else: tbody = table if total: tfoot = [tbody[-1]] tbody = tbody[:-1] parts = [] if thead: parts.append( html.thead( *[html.tr( *[html.th(_(col)) for col in r] ) for r in thead] ) ) if tbody: parts.append( html.tbody( *[html.tr( *[html.td(_(col)) for col in r] ) for r in tbody] ) ) if tfoot: parts.append( html.tfoot( *[html.tr( *[html.th(_(col)) for col in r] ) for r in tfoot] ) ) table = tostring( html.table( *parts, **attrs ) ) if style: if style is True: css = ''' #{{ id }} { border-collapse: collapse; border-spacing: 0; empty-cells: show; border: 1px solid #cbcbcb; } #{{ id }} td, #{{ id }} th { border-left: 1px solid #cbcbcb; border-width: 0 0 0 1px; margin: 0; padding: 0.5em 1em; } #{{ id }} td:first-child, #{{ id }} th:first-child { border-left-width: 0; } #{{ id }} thead, #{{ id }} tfoot { color: #000; text-align: left; vertical-align: bottom; } #{{ id }} thead { background: #e0e0e0; } #{{ id }} tfoot { background: #ededed; } #{{ id }} tr:nth-child(2n-1) td { background-color: #f2f2f2; } ''' else: css = style table = tostring(html.style( template(css, **attrs), scoped='scoped')) + table table = table.decode('utf-8') self.chart.teardown() return table
def render(self, total=False, transpose=False, style=False): html = HTML() attrs = {} if style: attrs['id'] = 'table-%s' % uuid.uuid4() table = [] _ = lambda x: x if x is not None else '' if self.x_labels: labels = list(self.x_labels) if len(labels) < self._len: labels += [None] * (self._len - len(labels)) if len(labels) > self._len: labels = labels[:self._len] table.append(labels) if total: if len(table): table[0].append('Total') else: table.append([None] * (self._len + 1) + ['Total']) acc = [0] * (self._len + 1) for i, serie in enumerate(self.series): row = [serie.title] if total: sum_ = 0 for j, value in enumerate(serie.values): if total: acc[j] += value sum_ += value row.append(self._format(value)) if total: acc[-1] += sum_ row.append(self._format(sum_)) table.append(row) width = self._len + 1 if total: width += 1 table.append(['Total']) for val in acc: table[-1].append(self._format(val)) # Align values len_ = max([len(r) for r in table] or [0]) for i, row in enumerate(table[:]): len_ = len(row) if len_ < width: table[i] = row + [None] * (width - len_) if not transpose: table = list(zip(*table)) thead = [] tbody = [] tfoot = [] if not transpose or self.x_labels: # There's always series title but not always x_labels thead = [table[0]] tbody = table[1:] else: tbody = table parts = [] if thead: parts.append( html.thead( *[html.tr(*[html.th(_(col)) for col in r]) for r in thead])) if tbody: parts.append( html.tbody( *[html.tr(*[html.td(_(col)) for col in r]) for r in tbody])) if tfoot: parts.append( html.tfoot( *[html.tr(*[html.th(_(col)) for col in r]) for r in tfoot])) table = tostring(html.table(*parts, **attrs)) if style: if style is True: css = ''' #{{ id }}{ width: 100%; } #{{ id }} tbody tr:nth-child(odd) td { background-color: #f9f9f9; } ''' else: css = style table = tostring( html.style(template(css, **attrs), scoped='scoped')) + table if self.disable_xml_declaration: table = table.decode('utf-8') return table