From 848a6cd8259a0908a067a66530942f339213445d Mon Sep 17 00:00:00 2001 From: Nicolas Bonfante Date: Tue, 12 Jul 2016 16:59:15 +0200 Subject: [PATCH 1/4] Adding support for clockwise gauge --- pygal/config.py | 6 ++++++ pygal/graph/gauge.py | 38 +++++++++++++++++++++++++++++++++----- pygal/util.py | 4 ++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/pygal/config.py b/pygal/config.py index e1e7ce14..5369ff6b 100644 --- a/pygal/config.py +++ b/pygal/config.py @@ -258,6 +258,12 @@ class Config(CommonConfig): str) # Look # + clockwise = Key( + False, bool, "Look", + "Clockwise", + "Set to True to make the gauge clockwise." + ) + title = Key( None, str, "Look", "Graph title.", "Leave it to None to disable title.") diff --git a/pygal/graph/gauge.py b/pygal/graph/gauge.py index 974fafd1..b9cd5faf 100644 --- a/pygal/graph/gauge.py +++ b/pygal/graph/gauge.py @@ -23,9 +23,9 @@ from pygal._compat import is_str from pygal.graph.graph import Graph -from pygal.util import alter, compute_scale, cut, decorate +from pygal.util import alter, compute_scale, cut, decorate, compose from pygal.view import PolarThetaLogView, PolarThetaView - +TEMPCLOCK = False class Gauge(Graph): @@ -45,6 +45,11 @@ def _set_view(self): self.height - self.margin_box.y, self._box) + def clockwiser(self, point): + x_0, _ = self.view((0,90)) + new_x = 2*x_0 - point[0] + return (new_x, point[1]) + def needle(self, serie): """Draw a needle for each value""" serie_node = self.svg.serie(serie) @@ -52,8 +57,12 @@ def needle(self, serie): if theta is None: continue - def point(x, y): - return '%f %f' % self.view((x, y)) + def point(x, y): + if self.clockwise: + transform = compose(self.clockwiser, self.view) + else: + transform = self.view + return '%f %f' % transform((x, y)) val = self._format(serie, i) metadata = serie.metadata.get(i) @@ -75,18 +84,24 @@ def point(x, y): if self.logarithmic: w = min(w, self._min - self._min * 10 ** -10) + sweep_flag = '0' if self.clockwise else '1' + alter( self.svg.node( - gauges, 'path', d='M %s L %s A %s 1 0 1 %s Z' % ( + gauges, 'path', d='M %s L %s A %s 1 0 %s %s Z' % ( point(.85, theta), point(self.needle_width, theta - w), '%f %f' % (self.needle_width, self.needle_width), + sweep_flag, point(self.needle_width, theta + w), ), class_='line reactive tooltip-trigger'), metadata) x, y = self.view((.75, theta)) + if self.clockwise: + x, y = self.clockwiser((x, y)) + self._tooltip_data( gauges, val, x, y, xlabel=self._get_x_label(i)) @@ -96,6 +111,16 @@ def _y_axis(self, draw_axes=True): """Override y axis to plot a polar axis""" axis = self.svg.node(self.nodes['plot'], class_="axis x gauge") + liste_y_labels = self._y_labels + + if self.clockwise: + for i in range(int(len(self._y_labels)/2)): + (label_1, theta_1) = self._y_labels[i] + (label_2, theta_2) = self._y_labels[len(self._y_labels)-i-1] + temp_theta = theta_2 + self._y_labels[len(self._y_labels)-i-1] = (label_2, theta_1) + self._y_labels[i] = (label_1, temp_theta) + for i, (label, theta) in enumerate(self._y_labels): guides = self.svg.node(axis, class_='guides') @@ -112,6 +137,7 @@ def _y_axis(self, draw_axes=True): else '')) x, y = self.view((.9, theta)) + self.svg.node( guides, 'text', x=x, @@ -149,6 +175,7 @@ def _compute_y_labels(self): self.min_, self.max_, self.logarithmic, self.order_min, self.min_scale, self.max_scale ) + if self.y_labels: self._y_labels = [] for i, y_label in enumerate(self.y_labels): @@ -171,6 +198,7 @@ def _compute_y_labels(self): else: self._y_labels = list(zip(map(self._y_format, y_pos), y_pos)) + def _plot(self): """Plot all needles""" for serie in self.series: diff --git a/pygal/util.py b/pygal/util.py index 4bfcb2a0..6b28a6aa 100644 --- a/pygal/util.py +++ b/pygal/util.py @@ -384,3 +384,7 @@ def merge(dict1, dict2): dict1[key] = mergextend(val, dict1.get(key, ())) else: dict1[key] = val + +def compose(f, g): + return lambda x: f(g(x)) + From 60f3798fb03b0113a30e06bb75c6a7608dc7f98f Mon Sep 17 00:00:00 2001 From: Nicolas Bonfante Date: Tue, 12 Jul 2016 17:00:40 +0200 Subject: [PATCH 2/4] removing debugging variable --- pygal/graph/gauge.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pygal/graph/gauge.py b/pygal/graph/gauge.py index b9cd5faf..b4e6bb48 100644 --- a/pygal/graph/gauge.py +++ b/pygal/graph/gauge.py @@ -25,7 +25,6 @@ from pygal.graph.graph import Graph from pygal.util import alter, compute_scale, cut, decorate, compose from pygal.view import PolarThetaLogView, PolarThetaView -TEMPCLOCK = False class Gauge(Graph): From 19d080d47868e124a0cce8df99151612a578ca10 Mon Sep 17 00:00:00 2001 From: Nicolas Bonfante Date: Tue, 12 Jul 2016 17:15:54 +0200 Subject: [PATCH 3/4] flake 8 and isort --- pygal/config.py | 3 +-- pygal/graph/gauge.py | 3 ++- pygal/graph/graph.py | 9 ++++----- pygal/util.py | 6 ++---- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/pygal/config.py b/pygal/config.py index 5369ff6b..89c8b4e3 100644 --- a/pygal/config.py +++ b/pygal/config.py @@ -20,10 +20,9 @@ from copy import deepcopy +from pygal import formatters from pygal.interpolate import INTERPOLATIONS from pygal.style import DefaultStyle, Style -from pygal import formatters - CONFIG_ITEMS = [] callable = type(lambda: 1) diff --git a/pygal/graph/gauge.py b/pygal/graph/gauge.py index b4e6bb48..6b3e42bf 100644 --- a/pygal/graph/gauge.py +++ b/pygal/graph/gauge.py @@ -23,9 +23,10 @@ from pygal._compat import is_str from pygal.graph.graph import Graph -from pygal.util import alter, compute_scale, cut, decorate, compose +from pygal.util import alter, compose, compute_scale, cut, decorate from pygal.view import PolarThetaLogView, PolarThetaView + class Gauge(Graph): """Gauge graph class""" diff --git a/pygal/graph/graph.py b/pygal/graph/graph.py index 23e0669f..47d62137 100644 --- a/pygal/graph/graph.py +++ b/pygal/graph/graph.py @@ -22,14 +22,13 @@ from math import ceil, cos, sin, sqrt +from pygal import stats from pygal._compat import is_list_like, is_str, to_str from pygal.graph.public import PublicApi from pygal.interpolate import INTERPOLATIONS -from pygal import stats -from pygal.util import ( - cached_property, compute_scale, cut, decorate, - get_text_box, get_texts_box, majorize, rad, reverse_text_len, - split_title, truncate, filter_kwargs) +from pygal.util import (cached_property, compute_scale, cut, decorate, + filter_kwargs, get_text_box, get_texts_box, majorize, + rad, reverse_text_len, split_title, truncate) from pygal.view import LogView, ReverseView, View, XYLogView diff --git a/pygal/util.py b/pygal/util.py index 6b28a6aa..7272e3d6 100644 --- a/pygal/util.py +++ b/pygal/util.py @@ -23,10 +23,9 @@ import re from decimal import Decimal +from math import ceil, cos, floor, log10, pi, sin -from math import ceil, floor, log10, pi, cos, sin - -from pygal._compat import to_unicode, u, _ellipsis +from pygal._compat import _ellipsis, to_unicode, u def float_format(number): @@ -387,4 +386,3 @@ def merge(dict1, dict2): def compose(f, g): return lambda x: f(g(x)) - From 91a6ac232433ca9ac637bd1dcdc6d57efff5861d Mon Sep 17 00:00:00 2001 From: Nicolas Bonfante Date: Wed, 13 Jul 2016 09:17:26 +0200 Subject: [PATCH 4/4] flake 8 --- pygal/config.py | 2 +- pygal/graph/gauge.py | 17 +++++++---------- pygal/util.py | 3 --- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/pygal/config.py b/pygal/config.py index 89c8b4e3..dddc73b1 100644 --- a/pygal/config.py +++ b/pygal/config.py @@ -262,7 +262,7 @@ class Config(CommonConfig): "Clockwise", "Set to True to make the gauge clockwise." ) - + title = Key( None, str, "Look", "Graph title.", "Leave it to None to disable title.") diff --git a/pygal/graph/gauge.py b/pygal/graph/gauge.py index 6b3e42bf..a845541e 100644 --- a/pygal/graph/gauge.py +++ b/pygal/graph/gauge.py @@ -46,10 +46,10 @@ def _set_view(self): self._box) def clockwiser(self, point): - x_0, _ = self.view((0,90)) + x_0, _ = self.view((0, 90)) new_x = 2*x_0 - point[0] return (new_x, point[1]) - + def needle(self, serie): """Draw a needle for each value""" serie_node = self.svg.serie(serie) @@ -57,7 +57,7 @@ def needle(self, serie): if theta is None: continue - def point(x, y): + def point(x, y): if self.clockwise: transform = compose(self.clockwiser, self.view) else: @@ -85,7 +85,7 @@ def point(x, y): w = min(w, self._min - self._min * 10 ** -10) sweep_flag = '0' if self.clockwise else '1' - + alter( self.svg.node( gauges, 'path', d='M %s L %s A %s 1 0 %s %s Z' % ( @@ -101,7 +101,7 @@ def point(x, y): x, y = self.view((.75, theta)) if self.clockwise: x, y = self.clockwiser((x, y)) - + self._tooltip_data( gauges, val, x, y, xlabel=self._get_x_label(i)) @@ -111,15 +111,13 @@ def _y_axis(self, draw_axes=True): """Override y axis to plot a polar axis""" axis = self.svg.node(self.nodes['plot'], class_="axis x gauge") - liste_y_labels = self._y_labels - if self.clockwise: for i in range(int(len(self._y_labels)/2)): (label_1, theta_1) = self._y_labels[i] (label_2, theta_2) = self._y_labels[len(self._y_labels)-i-1] temp_theta = theta_2 self._y_labels[len(self._y_labels)-i-1] = (label_2, theta_1) - self._y_labels[i] = (label_1, temp_theta) + self._y_labels[i] = (label_1, temp_theta) for i, (label, theta) in enumerate(self._y_labels): guides = self.svg.node(axis, class_='guides') @@ -175,7 +173,7 @@ def _compute_y_labels(self): self.min_, self.max_, self.logarithmic, self.order_min, self.min_scale, self.max_scale ) - + if self.y_labels: self._y_labels = [] for i, y_label in enumerate(self.y_labels): @@ -198,7 +196,6 @@ def _compute_y_labels(self): else: self._y_labels = list(zip(map(self._y_format, y_pos), y_pos)) - def _plot(self): """Plot all needles""" for serie in self.series: diff --git a/pygal/util.py b/pygal/util.py index 7272e3d6..73881769 100644 --- a/pygal/util.py +++ b/pygal/util.py @@ -383,6 +383,3 @@ def merge(dict1, dict2): dict1[key] = mergextend(val, dict1.get(key, ())) else: dict1[key] = val - -def compose(f, g): - return lambda x: f(g(x))