Browse Source

Fix #237 + protocol fix

pull/242/head
Florian Mounier 10 years ago
parent
commit
d0b8436d14
  1. 2
      demo/moulinrouge/__init__.py
  2. 7
      docs/api/pygal.graph.verticalpyramid.rst
  3. 7
      docs/api/pygal.test.test_donut.rst
  4. 1
      docs/changelog.rst
  5. 11
      docs/documentation/configuration/rendering.rst
  6. 13
      docs/documentation/output.rst
  7. 7
      docs/ext/pygal_sphinx_directives.py
  8. 8
      pygal/config.py
  9. 11
      pygal/graph/public.py
  10. 4
      pygal/svg.py
  11. 9
      pygal/test/test_config.py

2
demo/moulinrouge/__init__.py

@ -300,7 +300,7 @@ def create_app():
def raw_svgs(): def raw_svgs():
svgs = [] svgs = []
for color in styles['neon'].colors: for color in styles['neon'].colors:
chart = pygal.Pie(style=parametric_styles['RotateStyle'](color), chart = pygal.Pie(style=parametric_styles['rotate'](color),
width=400, height=300) width=400, height=300)
chart.title = color chart.title = color
chart.disable_xml_declaration = True chart.disable_xml_declaration = True

7
docs/api/pygal.graph.verticalpyramid.rst

@ -1,7 +0,0 @@
pygal.graph.verticalpyramid module
==================================
.. automodule:: pygal.graph.verticalpyramid
:members:
:undoc-members:
:show-inheritance:

7
docs/api/pygal.test.test_donut.rst

@ -1,7 +0,0 @@
pygal.test.test_donut module
============================
.. automodule:: pygal.test.test_donut
:members:
:undoc-members:
:show-inheritance:

1
docs/changelog.rst

@ -30,6 +30,7 @@ Changelog
* Fix timezones in DateTimeLine * Fix timezones in DateTimeLine
* Rename in Style foreground_light as foreground_strong * Rename in Style foreground_light as foreground_strong
* Rename in Style foreground_dark as foreground_subtle * Rename in Style foreground_dark as foreground_subtle
* Add a ``render_data_uri`` method
1.7.0 1.7.0
===== =====

11
docs/documentation/configuration/rendering.rst

@ -128,6 +128,7 @@ Default:
Css can also specified inline by prepending `inline:` to the css: Css can also specified inline by prepending `inline:` to the css:
.. code-block:: python .. code-block:: python
css = ['inline:.rect { fill: blue; }'] css = ['inline:.rect { fill: blue; }']
@ -141,3 +142,13 @@ js
] ]
See `pygal.js <https://github.com/Kozea/pygal.js/>`_ See `pygal.js <https://github.com/Kozea/pygal.js/>`_
force_uri_protocol
------------------
In case of rendering the svg as a data uri, it is mandatory to specify a protocol.
It can be set to http or https and will be used for '//domain/' like uri.
It is used along with ``render_data_uri``.

13
docs/documentation/output.rst

@ -67,6 +67,19 @@ It is possible to get the xml etree root element of the chart (or lxml etree nod
chart.render_tree() # Return the svg root etree node chart.render_tree() # Return the svg root etree node
Base 64 data URI
----------------
You can directly output a base 64 encoded data uri for <embed> or <image> inclusion:
.. code-block:: python
chart = pygal.Line()
...
chart.render_data_uri() # Return `data:image/svg+xml;charset=utf-8;base64,...`
Browser Browser
------- -------

7
docs/ext/pygal_sphinx_directives.py

@ -22,7 +22,6 @@ from docutils.parsers.rst import Directive
from traceback import format_exc, print_exc from traceback import format_exc, print_exc
from sphinx.directives.code import CodeBlock from sphinx.directives.code import CodeBlock
import base64
import docutils.core import docutils.core
import pygal import pygal
@ -86,13 +85,9 @@ class PygalDirective(Directive):
chart.config.width = width chart.config.width = width
chart.config.height = height chart.config.height = height
chart.explicit_size = True chart.explicit_size = True
rv = chart.render()
try: try:
svg = ( svg = '<embed src="%s" />' % chart.render_data_uri()
'<embed src="data:image/svg+xml;charset=utf-8;base64,%s" />' %
base64.b64encode(rv).decode('utf-8')
.replace('\n', ''))
except Exception: except Exception:
return [docutils.nodes.system_message( return [docutils.nodes.system_message(
'An exception as occured during graph generation:' 'An exception as occured during graph generation:'

8
pygal/config.py

@ -483,7 +483,13 @@ class Config(CommonConfig):
disable_xml_declaration = Key( disable_xml_declaration = Key(
False, bool, "Misc", False, bool, "Misc",
"Don't write xml declaration and return str instead of string", "Don't write xml declaration and return str instead of string",
"usefull for writing output directly in html") "useful for writing output directly in html")
force_uri_protocol = Key(
None, str, "Misc",
"Default uri protocol",
"In case of rendering the svg as a data uri, it is mandatory to "
"specify a protocol. It can be set to http or https")
explicit_size = Key( explicit_size = Key(
False, bool, "Misc", "Write width and height attributes") False, bool, "Misc", "Write width and height attributes")

11
pygal/graph/public.py

@ -21,6 +21,7 @@
import io import io
from pygal._compat import u, is_list_like from pygal._compat import u, is_list_like
from pygal.graph.base import BaseGraph from pygal.graph.base import BaseGraph
import base64
class PublicApi(BaseGraph): class PublicApi(BaseGraph):
@ -92,6 +93,16 @@ class PublicApi(BaseGraph):
return HttpResponse( return HttpResponse(
self.render(**kwargs), content_type='image/svg+xml') self.render(**kwargs), content_type='image/svg+xml')
def render_data_uri(self, **kwargs):
"""Output a base 64 encoded data uri"""
# Force protocol as data uri have none
kwargs.setdefault('force_uri_protocol', 'https')
return "data:image/svg+xml;charset=utf-8;base64,%s" % (
base64.urlsafe_b64encode(
self.render(**kwargs)
).decode('utf-8').replace('\n', '')
)
def render_to_file(self, filename, **kwargs): def render_to_file(self, filename, **kwargs):
"""Render the graph, and write it to filename""" """Render the graph, and write it to filename"""
with io.open(filename, 'w', encoding='utf-8') as f: with io.open(filename, 'w', encoding='utf-8') as f:

4
pygal/svg.py

@ -120,6 +120,8 @@ class Svg(object):
css_text = minify_css(css_text) css_text = minify_css(css_text)
all_css.append(css_text) all_css.append(css_text)
else: else:
if css.startswith('//') and self.graph.force_uri_protocol:
css = '%s:%s' % (self.graph.force_uri_protocol, css)
self.processing_instructions.append( self.processing_instructions.append(
etree.PI( etree.PI(
u('xml-stylesheet'), u('href="%s"' % css))) u('xml-stylesheet'), u('href="%s"' % css)))
@ -154,6 +156,8 @@ class Svg(object):
with io.open(js[len('file://'):], encoding='utf-8') as f: with io.open(js[len('file://'):], encoding='utf-8') as f:
script.text = f.read() script.text = f.read()
else: else:
if js.startswith('//') and self.graph.force_uri_protocol:
js = '%s:%s' % (self.graph.force_uri_protocol, js)
self.node(self.defs, 'script', type='text/javascript', href=js) self.node(self.defs, 'script', type='text/javascript', href=js)
def node(self, parent=None, tag='g', attrib=None, **extras): def node(self, parent=None, tag='g', attrib=None, **extras):

9
pygal/test/test_config.py

@ -491,3 +491,12 @@ def test_fill(Chart):
chart.add('_', [1, 2, 3]) chart.add('_', [1, 2, 3])
chart.add('?', [10, 21, 5]) chart.add('?', [10, 21, 5])
assert chart.render_pyquery() assert chart.render_pyquery()
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,')

Loading…
Cancel
Save