details:   https://code.tryton.org/relatorio/commit/dbb1d2bd208e
branch:    default
user:      Cédric Krier <[email protected]>
date:      Sat Mar 21 18:50:21 2026 +0100
description:
        Remove support for chart template
diffstat:

 CHANGELOG                           |    1 +
 doc/indepthexample.rst              |   31 ------------
 doc/pie.png                         |  Bin 
 examples/complicated.odt            |  Bin 
 examples/demo_chart.py              |   24 ----------
 examples/demo_odf.py                |    3 -
 examples/demo_repository.py         |    4 -
 examples/hbar_chart                 |   32 -------------
 examples/line_chart                 |   27 -----------
 examples/pie_chart                  |   15 ------
 examples/vbar_chart                 |   32 -------------
 pyproject.toml                      |    5 --
 relatorio/templates/__init__.py     |    2 +-
 relatorio/templates/chart.py        |   86 ------------------------------------
 relatorio/templates/opendocument.py |    7 --
 tox.ini                             |    2 -
 16 files changed, 2 insertions(+), 269 deletions(-)

diffs (384 lines):

diff -r ac8bd2dc3064 -r dbb1d2bd208e CHANGELOG
--- a/CHANGELOG Sat Mar 21 16:46:15 2026 +0100
+++ b/CHANGELOG Sat Mar 21 18:50:21 2026 +0100
@@ -1,3 +1,4 @@
+* Remove support for chart template
 * Remove support for PDF
 
 Version 0.12.1 - 2026-04-03
diff -r ac8bd2dc3064 -r dbb1d2bd208e doc/indepthexample.rst
--- a/doc/indepthexample.rst    Sat Mar 21 16:46:15 2026 +0100
+++ b/doc/indepthexample.rst    Sat Mar 21 18:50:21 2026 +0100
@@ -101,37 +101,6 @@
 Note that the type of data is correctly set even though we did not have
 anything to do.
 
-Everybody loves charts
-----------------------
-
-Now we would like to make our basic report a bit more colorful, so let's add a
-little chart. We are using PyCha_ to generate them from our :file:`pie_chart`
-template:
-
-.. include:: ../examples/pie_chart
-    :literal:
-
-.. _PyCha: https://pypi.org/project/pycha/
-
-Once again we are using the same syntax as Genshi but this time this is a
-TextTemplate_. This file follow the YAML_ format thus we can render it into a
-data structure that will be sent to PyCha:
-
-    * the options dictionary will be sent to PyCha as-is
-    * the dataset in the chart dictionary is sent to PyCha through its
-      ``.addDataset`` method.
-
-.. _TextTemplate: 
https://genshi.edgewall.org/wiki/Documentation/text-templates.html
-.. _YAML: https://yaml.org/
-
-If you need more information about those go to the `pycha website`_.
-
-.. _pycha website: https://pypi.org/project/pycha/
-
-And here is the result:
-
-.. image:: pie.png
-
 A (not-so) real example
 -----------------------
 
diff -r ac8bd2dc3064 -r dbb1d2bd208e doc/pie.png
Binary file doc/pie.png has changed
diff -r ac8bd2dc3064 -r dbb1d2bd208e examples/complicated.odt
Binary file examples/complicated.odt has changed
diff -r ac8bd2dc3064 -r dbb1d2bd208e examples/demo_chart.py
--- a/examples/demo_chart.py    Sat Mar 21 16:46:15 2026 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-from os.path import abspath, dirname, join
-
-# test data
-from common import inv
-
-from relatorio import Report
-
-if __name__ == '__main__':
-    pie_report = Report(abspath(join(dirname(__file__), 'pie_chart')),
-            'image/png')
-    open(join(dirname(__file__), 'pie.png'), 'wb').write(
-            pie_report(o=inv).render().getvalue())
-    hbar_report = Report(abspath(join(dirname(__file__), 'hbar_chart')),
-            'image/svg')
-    open(join(dirname(__file__), 'hbar.svg'), 'wb').write(
-            hbar_report(o=inv).render().getvalue())
-    vbar_report = Report(abspath(join(dirname(__file__), 'vbar_chart')),
-            'image/svg')
-    open(join(dirname(__file__), 'vbar.svg'), 'wb').write(
-            vbar_report(o=inv).render().getvalue())
-    line_report = Report(abspath(join(dirname(__file__), 'line_chart')),
-            'image/png')
-    open(join(dirname(__file__), 'line.png'), 'wb').write(
-            line_report(o=inv).render().getvalue())
diff -r ac8bd2dc3064 -r dbb1d2bd208e examples/demo_odf.py
--- a/examples/demo_odf.py      Sat Mar 21 16:46:15 2026 +0100
+++ b/examples/demo_odf.py      Sat Mar 21 18:50:21 2026 +0100
@@ -29,9 +29,6 @@
     print("done")
 
     print("generating output_complicated.odt... ", end='')
-    # Add a chart to the invoice
-    inv['chart'] = (
-        Report(abspath(join(pwd, 'pie_chart')), 'image/png'), 'image/png')
     report = Report(abspath(join(pwd, 'complicated.odt')), ODT_MIME)
     try:
         content = report(o=inv).render().getvalue()
diff -r ac8bd2dc3064 -r dbb1d2bd208e examples/demo_repository.py
--- a/examples/demo_repository.py       Sat Mar 21 16:46:15 2026 +0100
+++ b/examples/demo_repository.py       Sat Mar 21 18:50:21 2026 +0100
@@ -16,12 +16,8 @@
 repository.add_report(Invoice, ODS_MIME, 'pivot.ods', report_name='pivot')
 repository.add_report(Invoice, ODP_MIME,
                       'presentation.odp', report_name='presentation')
-repository.add_report(Invoice, 'image/png', 'pie_chart', report_name='pie')
 
 if __name__ == '__main__':
-    # Add a chart to the invoice
-    inv['chart'] = repository.by_id(Invoice, 'pie')[:2]
-
     # Generate all reports on the invoice class
     for report_name, ext in (('basic', '.odt'),
                              ('complicated', '.odt'),
diff -r ac8bd2dc3064 -r dbb1d2bd208e examples/hbar_chart
--- a/examples/hbar_chart       Sat Mar 21 16:46:15 2026 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-options:
-  width: 600
-  height: 500
-  legend: 
-    hide: false
-    position: 
-      right: 40
-  padding: {bottom: 70, left: 70, right: 10, top: 10}
-  axis:
-    y:
-      interval: 15
-      padding: 5
-    x:
-      ticks:
-      {% for idx, line in enumerate(o.lines) %}
-        - v: $idx
-          label: $line.item.name
-      {% end %}
-chart:
-  type: hbar
-  output_type: svg
-  dataset:
-    - - Sales
-      -
-      {% for idx, line in enumerate(o.lines) %}
-        - [$idx, $line.amount]
-      {% end %}
-    - - Absolute sales
-      -
-      {% for idx, line in enumerate(o.lines) %}
-        - [$idx, ${abs(line.amount)}]
-      {% end %}
diff -r ac8bd2dc3064 -r dbb1d2bd208e examples/line_chart
--- a/examples/line_chart       Sat Mar 21 16:46:15 2026 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-options:
-  width: 600
-  height: 500
-  legend: 
-    hide: false
-    position: 
-      right: 40
-  padding: {bottom: 70, left: 70, right: 10, top: 10}
-  axis:
-    y:
-      interval: 10
-      padding: 10
-    x:
-      ticks:
-      {% for idx, line in enumerate(o.lines) %}
-        - v: $idx
-          label: $line.item.name
-      {% end %}
-chart:
-  type: line
-  output_type: png
-  dataset:
-    - - Sales
-      -
-      {% for idx, line in enumerate(o.lines) %}
-        - [$idx, $line.amount]
-      {% end %}
diff -r ac8bd2dc3064 -r dbb1d2bd208e examples/pie_chart
--- a/examples/pie_chart        Sat Mar 21 16:46:15 2026 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-options:
-    width: 600
-    height: 400
-    background: {hide: true}
-    legend: {hide: true}
-    axis: {labelFontSize: 14}
-    padding: {bottom: 10, left: 10, right: 10, top: 10}
-chart:
-    type: pie
-    output_type: png
-    dataset:
-    {% for line in o.lines %}
-      - - ${line.item.name}
-        - - [0, $line.amount]
-    {% end %}
diff -r ac8bd2dc3064 -r dbb1d2bd208e examples/vbar_chart
--- a/examples/vbar_chart       Sat Mar 21 16:46:15 2026 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-options:
-  width: 600
-  height: 500
-  legend: 
-    hide: false
-    position: 
-      right: 40
-  padding: {bottom: 70, left: 70, right: 10, top: 10}
-  axis:
-    y:
-      interval: 20
-      padding: 5
-    x:
-      ticks:
-      {% for idx, line in enumerate(o.lines) %}
-        - v: $idx
-          label: $line.item.name
-      {% end %}
-chart:
-  type: vbar
-  output_type: svg
-  dataset:
-    - - Sales
-      -
-      {% for idx, line in enumerate(o.lines) %}
-        - [$idx, $line.amount]
-      {% end %}
-    - - Absolute sales
-      -
-      {% for idx, line in enumerate(o.lines) %}
-        - [$idx, ${abs(line.amount)}]
-      {% end %}
diff -r ac8bd2dc3064 -r dbb1d2bd208e pyproject.toml
--- a/pyproject.toml    Sat Mar 21 16:46:15 2026 +0100
+++ b/pyproject.toml    Sat Mar 21 18:50:21 2026 +0100
@@ -29,11 +29,6 @@
 relatorio-render = 'relatorio.render:run'
 
 [project.optional-dependencies]
-chart = [
-    'pycairo',
-    'pycha >= 0.4.0',
-    'pyyaml >= 5.3',
-    ]
 fodt = [
     'python-magic',
     ]
diff -r ac8bd2dc3064 -r dbb1d2bd208e relatorio/templates/__init__.py
--- a/relatorio/templates/__init__.py   Sat Mar 21 16:46:15 2026 +0100
+++ b/relatorio/templates/__init__.py   Sat Mar 21 18:50:21 2026 +0100
@@ -1,6 +1,6 @@
 # This file is part of relatorio.  The COPYRIGHT file at the top level of
 # this repository contains the full copyright notices and license terms.
-plugins = ['base', 'opendocument', 'chart']
+plugins = ['base', 'opendocument']
 
 for name in plugins:
     __import__('relatorio.templates.%s' % name)
diff -r ac8bd2dc3064 -r dbb1d2bd208e relatorio/templates/chart.py
--- a/relatorio/templates/chart.py      Sat Mar 21 16:46:15 2026 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-# This file is part of relatorio.  The COPYRIGHT file at the top level of
-# this repository contains the full copyright notices and license terms.
-from io import BytesIO, StringIO
-
-import genshi
-import genshi.output
-from genshi.template import NewTextTemplate
-
-from relatorio.reporting import MIMETemplateLoader
-from relatorio.templates.base import RelatorioStream
-
-try:
-    import cairo
-    import pycha
-    import pycha.bar
-    import pycha.line
-    import pycha.pie
-    import yaml
-
-    PYCHA_TYPE = {'pie': pycha.pie.PieChart,
-                  'vbar': pycha.bar.VerticalBarChart,
-                  'hbar': pycha.bar.HorizontalBarChart,
-                  'line': pycha.line.LineChart,
-                 }
-except ImportError:
-    yaml = cairo = None
-    PYCHA_TYPE = {}
-_encode = genshi.output.encode
-
-__metaclass__ = type
-
-
-class Template(NewTextTemplate):
-    "A chart templating object"
-
-    def generate(self, *args, **kwargs):
-        generated = super(Template, self).generate(*args, **kwargs)
-        return RelatorioStream(generated, CairoSerializer())
-
-    @staticmethod
-    def id_function(mimetype):
-        "The function used to return the codename."
-        if mimetype in ('image/png', 'image/svg'):
-            return 'chart'
-
-
-class CairoSerializer:
-
-    def __init__(self):
-        self.text_serializer = genshi.output.TextSerializer()
-
-    def __call__(self, stream, method=None, encoding='utf-8', out=None):
-        if not PYCHA_TYPE:
-            raise NotImplementedError
-        if out is None:
-            result = BytesIO()
-        else:
-            result = out
-        yml = StringIO(_encode(self.text_serializer(stream)))
-        chart_yaml = yaml.safe_load(yml.read())
-        chart_info = chart_yaml['chart']
-        chart_type = chart_info['output_type']
-        if chart_type == 'png':
-            surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
-                                         chart_yaml['options']['width'],
-                                         chart_yaml['options']['height'])
-        elif chart_type == 'svg':
-            surface = cairo.SVGSurface(result, chart_yaml['options']['width'],
-                                       chart_yaml['options']['height'])
-        else:
-            raise NotImplementedError
-
-        chart = PYCHA_TYPE[chart_info['type']](surface, chart_yaml['options'])
-        chart.addDataset(chart_info['dataset'])
-        chart.render()
-
-        if chart_type == 'png':
-            surface.write_to_png(result)
-        elif chart_type == 'svg':
-            surface.finish()
-
-        if out is None:
-            return result
-
-
-MIMETemplateLoader.add_factory('chart', Template, Template.id_function)
diff -r ac8bd2dc3064 -r dbb1d2bd208e relatorio/templates/opendocument.py
--- a/relatorio/templates/opendocument.py       Sat Mar 21 16:46:15 2026 +0100
+++ b/relatorio/templates/opendocument.py       Sat Mar 21 18:50:21 2026 +0100
@@ -33,11 +33,6 @@
 from relatorio.reporting import MIMETemplateLoader, Report
 from relatorio.templates.base import RelatorioStream
 
-try:
-    from relatorio.templates.chart import Template as ChartTemplate
-except ImportError:
-    ChartTemplate = None
-
 __metaclass__ = type
 warnings.filterwarnings('always', module='relatorio.templates.opendocument')
 
@@ -104,8 +99,6 @@
         bitstream, mimetype = expr[:2]
         if isinstance(bitstream, Report):
             bitstream = bitstream(**self.context).render()
-        elif ChartTemplate and isinstance(bitstream, ChartTemplate):
-            bitstream = bitstream.generate(**self.context).render()
         elif not hasattr(bitstream, 'seek') or not hasattr(bitstream, 'read'):
             bitstream = BytesIO(bitstream)
         if bitstream:
diff -r ac8bd2dc3064 -r dbb1d2bd208e tox.ini
--- a/tox.ini   Sat Mar 21 16:46:15 2026 +0100
+++ b/tox.ini   Sat Mar 21 18:50:21 2026 +0100
@@ -12,8 +12,6 @@
 deps =
     coverage
     unittest-xml-reporting
-    pyyaml
-    pycha
 passenv = *
 
 [coverage:run]

Reply via email to