From 741a97850ee743ec90811edb4d43a7ccfac805dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= Date: Tue, 26 Jan 2016 21:28:40 +0100 Subject: [PATCH 1/3] support for interruptable plots added --- docs/documentation/types/line.rst | 14 ++++++++++++++ docs/documentation/types/xy.rst | 3 +++ pygal/graph/line.py | 30 +++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/docs/documentation/types/line.rst b/docs/documentation/types/line.rst index 6109c4d..287aec1 100644 --- a/docs/documentation/types/line.rst +++ b/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 ~~~~~~~ diff --git a/docs/documentation/types/xy.rst b/docs/documentation/types/xy.rst index 9d03de6..b804688 100644 --- a/docs/documentation/types/xy.rst +++ b/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 diff --git a/pygal/graph/line.py b/pygal/graph/line.py index baf17d8..6754b1f 100644 --- a/pygal/graph/line.py +++ b/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""" From 0022f73650cef7b02b706c25de6185210eccaef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= Date: Tue, 26 Jan 2016 22:08:53 +0100 Subject: [PATCH 2/3] pyflakes hates my guts --- pygal/graph/line.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/pygal/graph/line.py b/pygal/graph/line.py index 6754b1f..fa48714 100644 --- a/pygal/graph/line.py +++ b/pygal/graph/line.py @@ -144,21 +144,23 @@ class Line(Graph): view_values = self._fill(view_values) 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 + # 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 + if y is None and len(cur_sequence) > 0: + # emit current subsequence sequences.append(cur_sequence) cur_sequence = [] - elif y is None: # just discard + elif y is None: # just discard continue else: - cur_sequence.append((x,y)) # append the element + cur_sequence.append((x,y)) # append the element - if len(cur_sequence) > 0: # emit last possible sequence + if len(cur_sequence) > 0: # emit last possible sequence sequences.append(cur_sequence) else: # plain vanilla rendering @@ -167,7 +169,8 @@ class Line(Graph): for seq in sequences: self.svg.line( serie_node['plot'], seq, close=self._self_close, - class_='line reactive' + (' nofill' if not serie.fill else '')) + class_='line reactive' + + (' nofill' if not serie.fill else '')) def _compute(self): """Compute y min and max and y scale and set labels""" From 0da234757b5bf20d3f3a4737bd8d4c03000d60a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= Date: Tue, 26 Jan 2016 22:17:11 +0100 Subject: [PATCH 3/3] pyflakes again --- pygal/graph/line.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygal/graph/line.py b/pygal/graph/line.py index fa48714..8707451 100644 --- a/pygal/graph/line.py +++ b/pygal/graph/line.py @@ -158,7 +158,7 @@ class Line(Graph): elif y is None: # just discard continue else: - cur_sequence.append((x,y)) # append the element + cur_sequence.append((x, y)) # append the element if len(cur_sequence) > 0: # emit last possible sequence sequences.append(cur_sequence)