From ec072bc736a5d2d3fc5ec5de37b20f5560203ad5 Mon Sep 17 00:00:00 2001 From: fgiuba Date: Mon, 11 Mar 2019 14:13:02 +0100 Subject: [PATCH 1/3] Add `value_attribute` option to `Table.render()` Table.render() now accepts the `value_attribute` parameter. If set to True, each element will be created with the `value` attribute that mirror the content of the element itself. This can be used to apply CSS conditional formatting rules with the CSS selector functions. --- pygal/table.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pygal/table.py b/pygal/table.py index a7c03dc5..99fa86c7 100644 --- a/pygal/table.py +++ b/pygal/table.py @@ -45,12 +45,13 @@ def __init__(self, chart): """Init the table""" self.chart = chart - def render(self, total=False, transpose=False, style=False): + def render(self, total=False, transpose=False, style=False, value_attribute=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 + `value_attribute` replicate element value into `value` attribute ( elements) """ self.chart.setup() @@ -138,13 +139,19 @@ def render(self, total=False, transpose=False, style=False): if tbody: parts.append( html.tbody( - *[html.tr(*[html.td(_(col)) for col in r]) for r in tbody] + *[html.tr(*( + [html.td(_(col), value=_(col)) for col in r] + if value_attribute else [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] + *[html.tr(*( + [html.th(_(col), value=_(col)) for col in r] + if value_attribute else [html.td(_(col)) for col in r] + )) for r in tfoot] ) ) From 1e29db6e396ba139594225c8e6442e1f67c60358 Mon Sep 17 00:00:00 2001 From: fgiuba Date: Mon, 11 Mar 2019 14:19:53 +0100 Subject: [PATCH 2/3] Update `render_table` docs (added value_attribute) --- docs/documentation/table.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/documentation/table.rst b/docs/documentation/table.rst index ac918aa7..11b3c31d 100644 --- a/docs/documentation/table.rst +++ b/docs/documentation/table.rst @@ -79,3 +79,21 @@ Transposed line_chart.value_formatter = lambda x: '%.2f%%' % x if x is not None else '∅' line_chart.render_table(style=True, total=True, transpose=True) + +Value Attribute (for CSS Conditional Formatting) +------------------------------------------------ + +Add to each element the `value` attribute with the same content of the element itself. +This can be useful for applying CSS conditional formatting rules. + +.. pygal-table-code:: + + line_chart = pygal.Bar() + line_chart.title = 'Browser usage evolution (in %)' + line_chart.x_labels = map(str, range(2002, 2013)) + line_chart.add('Firefox', [None, None, 0, 16.6, 25, 31, 36.4, 45.5, 46.3, 42.8, 37.1]) + line_chart.add('Chrome', [None, None, None, None, None, None, 0, 3.9, 10.8, 23.8, 35.3]) + line_chart.add('IE', [85.8, 84.6, 84.7, 74.5, 66, 58.6, 54.7, 44.8, 36.2, 26.6, 20.1]) + line_chart.add('Others', [14.2, 15.4, 15.3, 8.9, 9, 10.4, 8.9, 5.8, 6.7, 6.8, 7.5]) + line_chart.value_formatter = lambda x: '%.2f%%' % x if x is not None else '∅' + line_chart.render_table(style=True, total=True, value_attribute=True) \ No newline at end of file From 86fdbb7802df07b95de84d047fb17cc302f59851 Mon Sep 17 00:00:00 2001 From: fgiuba Date: Wed, 29 May 2019 16:21:31 +0200 Subject: [PATCH 3/3] render_table() `value_attribue` can be a callable --- pygal/table.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/pygal/table.py b/pygal/table.py index 99fa86c7..f1c5be7a 100644 --- a/pygal/table.py +++ b/pygal/table.py @@ -28,6 +28,10 @@ from pygal.util import template +def _default_value_attribute_fn(value): + return value + + class HTML(object): """Lower case adapter of lxml builder""" @@ -45,7 +49,7 @@ def __init__(self, chart): """Init the table""" self.chart = chart - def render(self, total=False, transpose=False, style=False, value_attribute=False): + def render(self, total=False, transpose=False, style=False, value_attribute=None): """Render the HTMTL table of the chart. `total` can be specified to include data sums @@ -54,6 +58,12 @@ def render(self, total=False, transpose=False, style=False, value_attribute=Fals `value_attribute` replicate element value into `value` attribute ( elements) """ + if value_attribute is True: + value_attribute_fn = _default_value_attribute_fn + elif callable(value_attribute): + value_attribute_fn = value_attribute + else: + value_attribute_fn = None self.chart.setup() ln = self.chart._len html = HTML() @@ -140,8 +150,8 @@ def render(self, total=False, transpose=False, style=False, value_attribute=Fals parts.append( html.tbody( *[html.tr(*( - [html.td(_(col), value=_(col)) for col in r] - if value_attribute else [html.td(_(col)) for col in r] + [html.td(_(col), value=_(value_attribute_fn(col))) for col in r] + if value_attribute_fn else [html.td(_(col)) for col in r] )) for r in tbody] ) ) @@ -149,8 +159,8 @@ def render(self, total=False, transpose=False, style=False, value_attribute=Fals parts.append( html.tfoot( *[html.tr(*( - [html.th(_(col), value=_(col)) for col in r] - if value_attribute else [html.td(_(col)) for col in r] + [html.th(_(col), value=_(value_attribute_fn(col))) for col in r] + if value_attribute_fn else [html.td(_(col)) for col in r] )) for r in tfoot] ) )