Browse Source

support for interruptable plots added

pull/300/head
Piotr Maślanka 9 years ago
parent
commit
741a97850e
  1. 14
      docs/documentation/types/line.rst
  2. 3
      docs/documentation/types/xy.rst
  3. 30
      pygal/graph/line.py

14
docs/documentation/types/line.rst

@ -16,6 +16,20 @@ Basic simple line graph:
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])
Interruptions
^^^^^^^^^^^^^
If you happen to want a break in the middle of a plot, you can pass None values. Additionally,
you will need to specify allow_interruptions=True in the constructor, in order for the behaviour
to be supported correctly
.. pygal-code::
interrupted_chart = pygal.Line(allow_interruptions=True)
interrupted_chart.add('Temperature', [22, 34, 43, 12, None, 12, 55, None, 56])
Stacked
~~~~~~~

3
docs/documentation/types/xy.rst

@ -63,6 +63,9 @@ DateTime
Date
++++
If you want to plot date/time-series with breaks inside the plot, pass allow_interruptions=True to
the constructor. See Line on how to do it
.. pygal-code::
from datetime import date

30
pygal/graph/line.py

@ -35,6 +35,7 @@ class Line(Graph):
def __init__(self, *args, **kwargs):
"""Set _self_close as False, it's True for Radar like Line"""
self._self_close = False
self.allow_interruptions = kwargs.get('allow_interruptions', False)
super(Line, self).__init__(*args, **kwargs)
@cached_property
@ -141,9 +142,32 @@ class Line(Graph):
view_values = list(map(self.view, points))
if serie.fill:
view_values = self._fill(view_values)
self.svg.line(
serie_node['plot'], view_values, close=self._self_close,
class_='line reactive' + (' nofill' if not serie.fill else ''))
if self.allow_interruptions:
# view_values are in form [(x1, y1), (x2, y2)]. We need to split that
# into multiple sequences if a None is present here
sequences = []
cur_sequence = []
for x, y in view_values:
if y is None and len(cur_sequence) > 0: # emit current subsequence
sequences.append(cur_sequence)
cur_sequence = []
elif y is None: # just discard
continue
else:
cur_sequence.append((x,y)) # append the element
if len(cur_sequence) > 0: # emit last possible sequence
sequences.append(cur_sequence)
else:
# plain vanilla rendering
sequences = [view_values]
for seq in sequences:
self.svg.line(
serie_node['plot'], seq, close=self._self_close,
class_='line reactive' + (' nofill' if not serie.fill else ''))
def _compute(self):
"""Compute y min and max and y scale and set labels"""

Loading…
Cancel
Save