From 8927525a536c194f3571c2f844554003682658dd Mon Sep 17 00:00:00 2001 From: Benoit Calvez Date: Thu, 6 Jun 2013 13:51:52 +0200 Subject: [PATCH 1/8] Fix self._min and self._max --- pygal/graph/line.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pygal/graph/line.py b/pygal/graph/line.py index 1686e3c..ec07e2e 100644 --- a/pygal/graph/line.py +++ b/pygal/graph/line.py @@ -117,8 +117,8 @@ class Line(Graph): if self.include_x_axis: # Y Label - self._box.ymin = min(self._min, 0) - self._box.ymax = max(self._max, 0) + self._box.ymin = min(self._min or 0, 0) + self._box.ymax = max(self._max or 0, 0) else: self._box.ymin = self._min self._box.ymax = self._max From b822892a892f148269af44d18a037d45b832b8fd Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Tue, 18 Jun 2013 15:48:47 +0200 Subject: [PATCH 2/8] Fix darken/lighten --- pygal/style.py | 16 ++++--------- pygal/test/test_util.py | 2 +- pygal/util.py | 51 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/pygal/style.py b/pygal/style.py index 15e405d..7e2d477 100644 --- a/pygal/style.py +++ b/pygal/style.py @@ -20,8 +20,7 @@ Charts styling """ from __future__ import division -from pygal.util import cycle_fill -from colorsys import rgb_to_hls, hls_to_rgb +from pygal.util import cycle_fill, rgb_to_hsl, hsl_to_rgb def darken(color, percent): @@ -30,15 +29,10 @@ def darken(color, percent): assert len(color) in (3, 6), '#rrggbb and #rgb format are supported' if len(color) == 3: color = [a for b in zip(color, color) for a in b] - - return '#%02x%02x%02x' % tuple( - map(lambda x: 255 * x, - hls_to_rgb(*( - lambda h, l, s: (h, max(0, min(1, l - percent / 100)), s))( - *rgb_to_hls(*map( - lambda x: int(''.join(x), 16) / 255, - zip(color[::2], color[1::2]))) - )))) + return '#%02x%02x%02x' % hsl_to_rgb( + *(lambda h, s, l: (h, s, max(0, min(100, l - percent))))( + *rgb_to_hsl(*map(lambda x: int(''.join(x), 16), + zip(color[::2], color[1::2]))))) def lighten(color, percent): diff --git a/pygal/test/test_util.py b/pygal/test/test_util.py index 4051253..c301066 100644 --- a/pygal/test/test_util.py +++ b/pygal/test/test_util.py @@ -19,7 +19,7 @@ from pygal._compat import u from pygal.util import ( round_to_int, round_to_float, _swap_curly, template, humanize, - is_major, truncate, minify_css) + is_major, truncate, minify_css, rgb_to_hsl, hsl_to_rgb) from pytest import raises diff --git a/pygal/util.py b/pygal/util.py index 0f82fa6..02ec6a2 100644 --- a/pygal/util.py +++ b/pygal/util.py @@ -382,3 +382,54 @@ def split_title(title, width, title_fs): title = title[i:].strip() titles.append(title) return titles + + +def rgb_to_hsl(r, g, b): + r /= 255 + g /= 255 + b /= 255 + max_ = max((r, g, b)) + min_ = min((r, g, b)) + d = max_ - min_ + + if not d: + h = 0 + elif r is max_: + h = 60 * (g - b) / d + elif g is max_: + h = 60 * (b - r) / d + 120 + else: + h = 60 * (r - g) / d + 240 + + l = .5 * (max_ + min_) + if not d: + s = 0 + elif l < 0.5: + s = .5 * d / l + else: + s = .5 * d / (1 - l) + + return h % 360, s * 100, l * 100 + + +def hsl_to_rgb(h, s, l): + h /= 360 + s /= 100 + l /= 100 + + m2 = l * (s + 1) if l <= .5 else l + s - l * s + m1 = 2 * l - m2 + + def h_to_rgb(h): + h = h % 1 + if 6 * h < 1: + return m1 + 6 * h * (m2 - m1) + if 2 * h < 1: + return m2 + if 3 * h < 2: + return m1 + 6 * (2 / 3 - h) * (m2 - m1) + return m1 + r, g, b = map(lambda x: round(x * 255), + map(h_to_rgb, (h + 1 / 3, h, h - 1 / 3))) + + return r, g, b From a7d3a090e0913216b70383a640d6149216567f39 Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Tue, 18 Jun 2013 16:00:21 +0200 Subject: [PATCH 3/8] Add test case for issue #35 --- pygal/graph/line.py | 4 ++-- pygal/test/test_graph.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pygal/graph/line.py b/pygal/graph/line.py index 8da422f..84348aa 100644 --- a/pygal/graph/line.py +++ b/pygal/graph/line.py @@ -117,8 +117,8 @@ class Line(Graph): if self.include_x_axis: # Y Label - self._box.ymin = min(self._min, 0) - self._box.ymax = max(self._max, 0) + self._box.ymin = min(self._min or 0, 0) + self._box.ymax = max(self._max or 0, 0) else: self._box.ymin = self._min self._box.ymax = self._max diff --git a/pygal/test/test_graph.py b/pygal/test/test_graph.py index 2ccc6fb..f1de5dd 100644 --- a/pygal/test/test_graph.py +++ b/pygal/test/test_graph.py @@ -179,6 +179,12 @@ def test_no_data_with_no_values(Chart): assert q(".text-overlay text").text() == "No data" +def test_no_data_with_no_values_with_include_x_axis(Chart): + chart = Chart(include_x_axis=True) + q = chart.render_pyquery() + assert q(".text-overlay text").text() == "No data" + + def test_no_data_with_empty_serie(Chart): chart = Chart() chart.add('Serie', []) From 30bc88e11cd292183b25dc9f467f82f3ec361544 Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Tue, 18 Jun 2013 16:07:52 +0200 Subject: [PATCH 4/8] Fix tox.ini since numpy/scipy is no more used --- tox.ini | 3 --- 1 file changed, 3 deletions(-) diff --git a/tox.ini b/tox.ini index 36061a2..52ab77c 100644 --- a/tox.ini +++ b/tox.ini @@ -6,9 +6,6 @@ deps = pytest pytest-cov pyquery - numpy -# scipy cannot be installed by pip if numpy is not totally installed before commands = - pip install scipy py.test [] --cov pygal pygal/test From 9ae3e66ddb931523577f481e3f6f4f878e54c628 Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Wed, 19 Jun 2013 12:48:54 +0200 Subject: [PATCH 5/8] Fix sparktext --- pygal/ghost.py | 24 ++++++++++++++++-------- pygal/test/test_sparktext.py | 27 ++++++++++++++++++++------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/pygal/ghost.py b/pygal/ghost.py index e40d100..efacd78 100644 --- a/pygal/ghost.py +++ b/pygal/ghost.py @@ -23,6 +23,7 @@ It is used to delegate rendering to real objects but keeping config in place """ +from __future__ import division import io import sys from pygal.config import Config @@ -111,7 +112,7 @@ class Ghost(object): return cairosvg.svg2png( bytestring=self.render(), write_to=filename, dpi=dpi) - def render_sparktext(self): + def render_sparktext(self, relative_to=None): """Make a mini text sparkline from chart""" bars = u('▁▂▃▄▅▆▇█') if len(self.raw_series) == 0: @@ -121,23 +122,30 @@ class Ghost(object): return u('') chart = u('') + values = map(lambda x: max(x, 0), values) + vmax = max(values) - divisions = len(bars) + if relative_to is None: + relative_to = min(values) + divisions = len(bars) - 1 for value in values: - chart += bars[int(divisions * min(value, 0) / vmax)] + chart += bars[int(divisions * + (value - relative_to) / (vmax - relative_to))] return chart - def render_sparkline(self, width=200, height=50): - return self.make_instance(dict( - width=width, - height=height, + def render_sparkline(self, **kwargs): + spark_options = dict( + width=200, + height=50, show_dots=False, show_legend=False, show_y_labels=False, spacing=0, margin=5, explicit_size=True - )).render() + ) + spark_options.update(kwargs) + return self.make_instance(spark_options).render() def _repr_png_(self): """Display png in IPython notebook""" diff --git a/pygal/test/test_sparktext.py b/pygal/test/test_sparktext.py index 37d54a9..9008814 100644 --- a/pygal/test/test_sparktext.py +++ b/pygal/test/test_sparktext.py @@ -23,27 +23,40 @@ from pygal._compat import u def test_basic_sparktext(): chart = Line() chart.add('_', [1, 5, 22, 13, 53]) - chart.render_sparktext() == u('▁▁▃▂▇') + assert chart.render_sparktext() == u('▁▁▃▂█') + + +def test_all_sparktext(): + chart = Line() + chart.add('_', range(8)) + assert chart.render_sparktext() == u('▁▂▃▄▅▆▇█') + + +def test_shifted_sparktext(): + chart = Line() + chart.add('_', map(lambda x: x + 10000, range(8))) + assert chart.render_sparktext() == u('▁▂▃▄▅▆▇█') + assert chart.render_sparktext(relative_to=0) == u('▇▇▇▇▇▇▇█') def test_another_sparktext(): chart = Line() chart.add('_', [0, 30, 55, 80, 33, 150]) - chart.render_sparktext() == u('▁▂▃▅▂▇') - chart.render_sparktext() == chart.render_sparktext() + assert chart.render_sparktext() == u('▁▂▃▄▂█') + assert chart.render_sparktext() == chart.render_sparktext() chart2 = Bar() chart2.add('_', [0, 30, 55, 80, 33, 150]) - chart2.render_sparktext() == chart.render_sparktext() + assert chart2.render_sparktext() == chart.render_sparktext() def test_negative_and_float_and_no_data_sparktext(): chart = Line() chart.add('_', [0.1, 0.2, 0.9, -0.5]) - chart.render_sparktext() == u('▄▅█▁') + assert chart.render_sparktext() == u('▁▂█▁') chart2 = Line() chart2.add('_', []) - chart2.render_sparktext() == u('') + assert chart2.render_sparktext() == u('') chart3 = Line() - chart3.render_sparktext() == u('') + assert chart3.render_sparktext() == u('') From 26178bff1b1547b80a184520da2e6ad464ce02ab Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Wed, 19 Jun 2013 14:14:48 +0200 Subject: [PATCH 6/8] Fix sparktext Python3... --- pygal/ghost.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygal/ghost.py b/pygal/ghost.py index efacd78..55fcf07 100644 --- a/pygal/ghost.py +++ b/pygal/ghost.py @@ -122,7 +122,7 @@ class Ghost(object): return u('') chart = u('') - values = map(lambda x: max(x, 0), values) + values = list(map(lambda x: max(x, 0), values)) vmax = max(values) if relative_to is None: From 6e76b3c085070aafa9ce02f4eef9324a5463360f Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Wed, 19 Jun 2013 14:20:14 +0200 Subject: [PATCH 7/8] Fix sparktext Python3... 2nd edition --- pygal/test/test_sparktext.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygal/test/test_sparktext.py b/pygal/test/test_sparktext.py index 9008814..1158565 100644 --- a/pygal/test/test_sparktext.py +++ b/pygal/test/test_sparktext.py @@ -34,7 +34,7 @@ def test_all_sparktext(): def test_shifted_sparktext(): chart = Line() - chart.add('_', map(lambda x: x + 10000, range(8))) + chart.add('_', list(map(lambda x: x + 10000, range(8)))) assert chart.render_sparktext() == u('▁▂▃▄▅▆▇█') assert chart.render_sparktext(relative_to=0) == u('▇▇▇▇▇▇▇█') From 953b3810e3d5df3274ab4366110f1b540d544155 Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Wed, 19 Jun 2013 15:38:44 +0200 Subject: [PATCH 8/8] Add some color helpers --- pygal/colors.py | 122 +++++++++++ pygal/style.py | 18 +- pygal/test/test_colors.py | 446 ++++++++++++++++++++++++++++++++++++++ pygal/test/test_style.py | 20 +- pygal/test/test_util.py | 2 +- pygal/util.py | 51 ----- 6 files changed, 571 insertions(+), 88 deletions(-) create mode 100644 pygal/colors.py create mode 100644 pygal/test/test_colors.py diff --git a/pygal/colors.py b/pygal/colors.py new file mode 100644 index 0000000..4c08f7c --- /dev/null +++ b/pygal/colors.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +# This file is part of pygal +# +# A python svg graph plotting library +# Copyright © 2012-2013 Kozea +# +# This library is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with pygal. If not, see . +""" +Color utils + +""" +from __future__ import division + + +def normalize_float(f): + if abs(f - round(f)) < .0000000000001: + return round(f) + return f + + +def rgb_to_hsl(r, g, b): + r /= 255 + g /= 255 + b /= 255 + max_ = max((r, g, b)) + min_ = min((r, g, b)) + d = max_ - min_ + + if not d: + h = 0 + elif r is max_: + h = 60 * (g - b) / d + elif g is max_: + h = 60 * (b - r) / d + 120 + else: + h = 60 * (r - g) / d + 240 + + l = .5 * (max_ + min_) + if not d: + s = 0 + elif l < 0.5: + s = .5 * d / l + else: + s = .5 * d / (1 - l) + return tuple(map(normalize_float, (h % 360, s * 100, l * 100))) + + +def hsl_to_rgb(h, s, l): + h /= 360 + s /= 100 + l /= 100 + + m2 = l * (s + 1) if l <= .5 else l + s - l * s + m1 = 2 * l - m2 + + def h_to_rgb(h): + h = h % 1 + if 6 * h < 1: + return m1 + 6 * h * (m2 - m1) + if 2 * h < 1: + return m2 + if 3 * h < 2: + return m1 + 6 * (2 / 3 - h) * (m2 - m1) + return m1 + r, g, b = map(lambda x: round(x * 255), + map(h_to_rgb, (h + 1 / 3, h, h - 1 / 3))) + + return r, g, b + + +def adjust(color, attribute, percent): + assert color[0] == '#', '#rrggbb and #rgb format are supported' + color = color[1:] + assert len(color) in (3, 6), '#rrggbb and #rgb format are supported' + if len(color) == 3: + color = [a for b in zip(color, color) for a in b] + + bound = lambda x: max(0, min(100, x)) + + def _adjust(hsl): + hsl = list(hsl) + if attribute > 0: + hsl[attribute] = bound(hsl[attribute] + percent) + else: + hsl[attribute] += percent + + return hsl + return '#%02x%02x%02x' % hsl_to_rgb( + *_adjust( + rgb_to_hsl(*map(lambda x: int(''.join(x), 16), + zip(color[::2], color[1::2]))))) + + +def rotate(color, percent): + return adjust(color, 0, percent) + + +def saturate(color, percent): + return adjust(color, 1, percent) + + +def desaturate(color, percent): + return adjust(color, 1, -percent) + + +def lighten(color, percent): + return adjust(color, 2, percent) + + +def darken(color, percent): + return adjust(color, 2, -percent) diff --git a/pygal/style.py b/pygal/style.py index 7e2d477..50f9846 100644 --- a/pygal/style.py +++ b/pygal/style.py @@ -20,23 +20,7 @@ Charts styling """ from __future__ import division -from pygal.util import cycle_fill, rgb_to_hsl, hsl_to_rgb - - -def darken(color, percent): - assert color[0] == '#', '#rrggbb and #rgb format are supported' - color = color[1:] - assert len(color) in (3, 6), '#rrggbb and #rgb format are supported' - if len(color) == 3: - color = [a for b in zip(color, color) for a in b] - return '#%02x%02x%02x' % hsl_to_rgb( - *(lambda h, s, l: (h, s, max(0, min(100, l - percent))))( - *rgb_to_hsl(*map(lambda x: int(''.join(x), 16), - zip(color[::2], color[1::2]))))) - - -def lighten(color, percent): - return darken(color, -percent) +from pygal.util import cycle_fill class Style(object): diff --git a/pygal/test/test_colors.py b/pygal/test/test_colors.py new file mode 100644 index 0000000..c60f72b --- /dev/null +++ b/pygal/test/test_colors.py @@ -0,0 +1,446 @@ +from pygal.colors import ( + rgb_to_hsl, hsl_to_rgb, darken, lighten, saturate, desaturate, rotate) + + +def test_darken(): + assert darken('#800', 20) == '#220000' + assert darken('#800', 0) == '#880000' + assert darken('#ffffff', 10) == '#e6e6e6' + assert darken('#000000', 10) == '#000000' + assert darken('#f3148a', 25) == '#810747' + assert darken('#121212', 1) == '#0f0f0f' + assert darken('#999999', 100) == '#000000' + assert darken('#1479ac', 8) == '#105f87' + + +def test_lighten(): + assert lighten('#800', 20) == '#ee0000' + assert lighten('#800', 0) == '#880000' + assert lighten('#ffffff', 10) == '#ffffff' + assert lighten('#000000', 10) == '#1a1a1a' + assert lighten('#f3148a', 25) == '#f98dc6' + assert lighten('#121212', 1) == '#151515' + assert lighten('#999999', 100) == '#ffffff' + assert lighten('#1479ac', 8) == '#1893d1' + + +def test_saturate(): + assert saturate('#000', 20) == '#000000' + assert saturate('#fff', 20) == '#ffffff' + assert saturate('#8a8', 100) == '#33ff33' + assert saturate('#855', 20) == '#9e3f3f' + + +def test_desaturate(): + assert desaturate('#000', 20) == '#000000' + assert desaturate('#fff', 20) == '#ffffff' + assert desaturate('#8a8', 100) == '#999999' + assert desaturate('#855', 20) == '#726b6b' + + +def test_rotate(): + assert rotate('#000', 45) == '#000000' + assert rotate('#fff', 45) == '#ffffff' + assert rotate('#811', 45) == '#886a11' + assert rotate('#8a8', 360) == '#88aa88' + assert rotate('#8a8', 0) == '#88aa88' + assert rotate('#8a8', -360) == '#88aa88' + + +def test_hsl_to_rgb_part_0(): + assert hsl_to_rgb(0, 100, 50) == (255, 0, 0) + assert hsl_to_rgb(60, 100, 50) == (255, 255, 0) + assert hsl_to_rgb(120, 100, 50) == (0, 255, 0) + assert hsl_to_rgb(180, 100, 50) == (0, 255, 255) + assert hsl_to_rgb(240, 100, 50) == (0, 0, 255) + assert hsl_to_rgb(300, 100, 50) == (255, 0, 255) + + +def test_rgb_to_hsl_part_0(): + assert rgb_to_hsl(255, 0, 0) == (0, 100, 50) + assert rgb_to_hsl(255, 255, 0) == (60, 100, 50) + assert rgb_to_hsl(0, 255, 0) == (120, 100, 50) + assert rgb_to_hsl(0, 255, 255) == (180, 100, 50) + assert rgb_to_hsl(0, 0, 255) == (240, 100, 50) + assert rgb_to_hsl(255, 0, 255) == (300, 100, 50) + + +def test_hsl_to_rgb_part_1(): + assert hsl_to_rgb(-360, 100, 50) == (255, 0, 0) + assert hsl_to_rgb(-300, 100, 50) == (255, 255, 0) + assert hsl_to_rgb(-240, 100, 50) == (0, 255, 0) + assert hsl_to_rgb(-180, 100, 50) == (0, 255, 255) + assert hsl_to_rgb(-120, 100, 50) == (0, 0, 255) + assert hsl_to_rgb(-60, 100, 50) == (255, 0, 255) + + +def test_rgb_to_hsl_part_1(): + # assert rgb_to_hsl(255, 0, 0) == (-360, 100, 50) + # assert rgb_to_hsl(255, 255, 0) == (-300, 100, 50) + # assert rgb_to_hsl(0, 255, 0) == (-240, 100, 50) + # assert rgb_to_hsl(0, 255, 255) == (-180, 100, 50) + # assert rgb_to_hsl(0, 0, 255) == (-120, 100, 50) + # assert rgb_to_hsl(255, 0, 255) == (-60, 100, 50) + pass + + +def test_hsl_to_rgb_part_2(): + assert hsl_to_rgb(360, 100, 50) == (255, 0, 0) + assert hsl_to_rgb(420, 100, 50) == (255, 255, 0) + assert hsl_to_rgb(480, 100, 50) == (0, 255, 0) + assert hsl_to_rgb(540, 100, 50) == (0, 255, 255) + assert hsl_to_rgb(600, 100, 50) == (0, 0, 255) + assert hsl_to_rgb(660, 100, 50) == (255, 0, 255) + + +def test_rgb_to_hsl_part_2(): + # assert rgb_to_hsl(255, 0, 0) == (360, 100, 50) + # assert rgb_to_hsl(255, 255, 0) == (420, 100, 50) + # assert rgb_to_hsl(0, 255, 0) == (480, 100, 50) + # assert rgb_to_hsl(0, 255, 255) == (540, 100, 50) + # assert rgb_to_hsl(0, 0, 255) == (600, 100, 50) + # assert rgb_to_hsl(255, 0, 255) == (660, 100, 50) + pass + + +def test_hsl_to_rgb_part_3(): + assert hsl_to_rgb(6120, 100, 50) == (255, 0, 0) + assert hsl_to_rgb(-9660, 100, 50) == (255, 255, 0) + assert hsl_to_rgb(99840, 100, 50) == (0, 255, 0) + assert hsl_to_rgb(-900, 100, 50) == (0, 255, 255) + assert hsl_to_rgb(-104880, 100, 50) == (0, 0, 255) + assert hsl_to_rgb(2820, 100, 50) == (255, 0, 255) + + +def test_rgb_to_hsl_part_3(): + # assert rgb_to_hsl(255, 0, 0) == (6120, 100, 50) + # assert rgb_to_hsl(255, 255, 0) == (-9660, 100, 50) + # assert rgb_to_hsl(0, 255, 0) == (99840, 100, 50) + # assert rgb_to_hsl(0, 255, 255) == (-900, 100, 50) + # assert rgb_to_hsl(0, 0, 255) == (-104880, 100, 50) + # assert rgb_to_hsl(255, 0, 255) == (2820, 100, 50) + pass + + +def test_hsl_to_rgb_part_4(): + assert hsl_to_rgb(0, 100, 50) == (255, 0, 0) + assert hsl_to_rgb(12, 100, 50) == (255, 51, 0) + assert hsl_to_rgb(24, 100, 50) == (255, 102, 0) + assert hsl_to_rgb(36, 100, 50) == (255, 153, 0) + assert hsl_to_rgb(48, 100, 50) == (255, 204, 0) + assert hsl_to_rgb(60, 100, 50) == (255, 255, 0) + assert hsl_to_rgb(72, 100, 50) == (204, 255, 0) + assert hsl_to_rgb(84, 100, 50) == (153, 255, 0) + assert hsl_to_rgb(96, 100, 50) == (102, 255, 0) + assert hsl_to_rgb(108, 100, 50) == (51, 255, 0) + assert hsl_to_rgb(120, 100, 50) == (0, 255, 0) + + +def test_rgb_to_hsl_part_4(): + assert rgb_to_hsl(255, 0, 0) == (0, 100, 50) + assert rgb_to_hsl(255, 51, 0) == (12, 100, 50) + assert rgb_to_hsl(255, 102, 0) == (24, 100, 50) + assert rgb_to_hsl(255, 153, 0) == (36, 100, 50) + assert rgb_to_hsl(255, 204, 0) == (48, 100, 50) + assert rgb_to_hsl(255, 255, 0) == (60, 100, 50) + assert rgb_to_hsl(204, 255, 0) == (72, 100, 50) + assert rgb_to_hsl(153, 255, 0) == (84, 100, 50) + assert rgb_to_hsl(102, 255, 0) == (96, 100, 50) + assert rgb_to_hsl(51, 255, 0) == (108, 100, 50) + assert rgb_to_hsl(0, 255, 0) == (120, 100, 50) + + +def test_hsl_to_rgb_part_5(): + assert hsl_to_rgb(120, 100, 50) == (0, 255, 0) + assert hsl_to_rgb(132, 100, 50) == (0, 255, 51) + assert hsl_to_rgb(144, 100, 50) == (0, 255, 102) + assert hsl_to_rgb(156, 100, 50) == (0, 255, 153) + assert hsl_to_rgb(168, 100, 50) == (0, 255, 204) + assert hsl_to_rgb(180, 100, 50) == (0, 255, 255) + assert hsl_to_rgb(192, 100, 50) == (0, 204, 255) + assert hsl_to_rgb(204, 100, 50) == (0, 153, 255) + assert hsl_to_rgb(216, 100, 50) == (0, 102, 255) + assert hsl_to_rgb(228, 100, 50) == (0, 51, 255) + assert hsl_to_rgb(240, 100, 50) == (0, 0, 255) + + +def test_rgb_to_hsl_part_5(): + assert rgb_to_hsl(0, 255, 0) == (120, 100, 50) + assert rgb_to_hsl(0, 255, 51) == (132, 100, 50) + assert rgb_to_hsl(0, 255, 102) == (144, 100, 50) + assert rgb_to_hsl(0, 255, 153) == (156, 100, 50) + assert rgb_to_hsl(0, 255, 204) == (168, 100, 50) + assert rgb_to_hsl(0, 255, 255) == (180, 100, 50) + assert rgb_to_hsl(0, 204, 255) == (192, 100, 50) + assert rgb_to_hsl(0, 153, 255) == (204, 100, 50) + assert rgb_to_hsl(0, 102, 255) == (216, 100, 50) + assert rgb_to_hsl(0, 51, 255) == (228, 100, 50) + assert rgb_to_hsl(0, 0, 255) == (240, 100, 50) + + +def test_hsl_to_rgb_part_6(): + assert hsl_to_rgb(240, 100, 50) == (0, 0, 255) + assert hsl_to_rgb(252, 100, 50) == (51, 0, 255) + assert hsl_to_rgb(264, 100, 50) == (102, 0, 255) + assert hsl_to_rgb(276, 100, 50) == (153, 0, 255) + assert hsl_to_rgb(288, 100, 50) == (204, 0, 255) + assert hsl_to_rgb(300, 100, 50) == (255, 0, 255) + assert hsl_to_rgb(312, 100, 50) == (255, 0, 204) + assert hsl_to_rgb(324, 100, 50) == (255, 0, 153) + assert hsl_to_rgb(336, 100, 50) == (255, 0, 102) + assert hsl_to_rgb(348, 100, 50) == (255, 0, 51) + assert hsl_to_rgb(360, 100, 50) == (255, 0, 0) + + +def test_rgb_to_hsl_part_6(): + assert rgb_to_hsl(0, 0, 255) == (240, 100, 50) + assert rgb_to_hsl(51, 0, 255) == (252, 100, 50) + assert rgb_to_hsl(102, 0, 255) == (264, 100, 50) + assert rgb_to_hsl(153, 0, 255) == (276, 100, 50) + assert rgb_to_hsl(204, 0, 255) == (288, 100, 50) + assert rgb_to_hsl(255, 0, 255) == (300, 100, 50) + assert rgb_to_hsl(255, 0, 204) == (312, 100, 50) + assert rgb_to_hsl(255, 0, 153) == (324, 100, 50) + assert rgb_to_hsl(255, 0, 102) == (336, 100, 50) + assert rgb_to_hsl(255, 0, 51) == (348, 100, 50) + # assert rgb_to_hsl(255, 0, 0) == (360, 100, 50) + + +def test_hsl_to_rgb_part_7(): + assert hsl_to_rgb(0, 20, 50) == (153, 102, 102) + assert hsl_to_rgb(0, 60, 50) == (204, 51, 51) + assert hsl_to_rgb(0, 100, 50) == (255, 0, 0) + + +def test_rgb_to_hsl_part_7(): + assert rgb_to_hsl(153, 102, 102) == (0, 20, 50) + assert rgb_to_hsl(204, 51, 51) == (0, 60, 50) + assert rgb_to_hsl(255, 0, 0) == (0, 100, 50) + + +def test_hsl_to_rgb_part_8(): + assert hsl_to_rgb(60, 20, 50) == (153, 153, 102) + assert hsl_to_rgb(60, 60, 50) == (204, 204, 51) + assert hsl_to_rgb(60, 100, 50) == (255, 255, 0) + + +def test_rgb_to_hsl_part_8(): + assert rgb_to_hsl(153, 153, 102) == (60, 20, 50) + assert rgb_to_hsl(204, 204, 51) == (60, 60, 50) + assert rgb_to_hsl(255, 255, 0) == (60, 100, 50) + + +def test_hsl_to_rgb_part_9(): + assert hsl_to_rgb(120, 20, 50) == (102, 153, 102) + assert hsl_to_rgb(120, 60, 50) == (51, 204, 51) + assert hsl_to_rgb(120, 100, 50) == (0, 255, 0) + + +def test_rgb_to_hsl_part_9(): + assert rgb_to_hsl(102, 153, 102) == (120, 20, 50) + assert rgb_to_hsl(51, 204, 51) == (120, 60, 50) + assert rgb_to_hsl(0, 255, 0) == (120, 100, 50) + + +def test_hsl_to_rgb_part_10(): + assert hsl_to_rgb(180, 20, 50) == (102, 153, 153) + assert hsl_to_rgb(180, 60, 50) == (51, 204, 204) + assert hsl_to_rgb(180, 100, 50) == (0, 255, 255) + + +def test_rgb_to_hsl_part_10(): + assert rgb_to_hsl(102, 153, 153) == (180, 20, 50) + assert rgb_to_hsl(51, 204, 204) == (180, 60, 50) + assert rgb_to_hsl(0, 255, 255) == (180, 100, 50) + + +def test_hsl_to_rgb_part_11(): + assert hsl_to_rgb(240, 20, 50) == (102, 102, 153) + assert hsl_to_rgb(240, 60, 50) == (51, 51, 204) + assert hsl_to_rgb(240, 100, 50) == (0, 0, 255) + + +def test_rgb_to_hsl_part_11(): + assert rgb_to_hsl(102, 102, 153) == (240, 20, 50) + assert rgb_to_hsl(51, 51, 204) == (240, 60, 50) + assert rgb_to_hsl(0, 0, 255) == (240, 100, 50) + + +def test_hsl_to_rgb_part_12(): + assert hsl_to_rgb(300, 20, 50) == (153, 102, 153) + assert hsl_to_rgb(300, 60, 50) == (204, 51, 204) + assert hsl_to_rgb(300, 100, 50) == (255, 0, 255) + + +def test_rgb_to_hsl_part_12(): + assert rgb_to_hsl(153, 102, 153) == (300, 20, 50) + assert rgb_to_hsl(204, 51, 204) == (300, 60, 50) + assert rgb_to_hsl(255, 0, 255) == (300, 100, 50) + + +def test_hsl_to_rgb_part_13(): + assert hsl_to_rgb(0, 100, 0) == (0, 0, 0) + assert hsl_to_rgb(0, 100, 10) == (51, 0, 0) + assert hsl_to_rgb(0, 100, 20) == (102, 0, 0) + assert hsl_to_rgb(0, 100, 30) == (153, 0, 0) + assert hsl_to_rgb(0, 100, 40) == (204, 0, 0) + assert hsl_to_rgb(0, 100, 50) == (255, 0, 0) + assert hsl_to_rgb(0, 100, 60) == (255, 51, 51) + assert hsl_to_rgb(0, 100, 70) == (255, 102, 102) + assert hsl_to_rgb(0, 100, 80) == (255, 153, 153) + assert hsl_to_rgb(0, 100, 90) == (255, 204, 204) + assert hsl_to_rgb(0, 100, 100) == (255, 255, 255) + + +def test_rgb_to_hsl_part_13(): + assert rgb_to_hsl(0, 0, 0) == (0, 0, 0) + assert rgb_to_hsl(51, 0, 0) == (0, 100, 10) + assert rgb_to_hsl(102, 0, 0) == (0, 100, 20) + assert rgb_to_hsl(153, 0, 0) == (0, 100, 30) + assert rgb_to_hsl(204, 0, 0) == (0, 100, 40) + assert rgb_to_hsl(255, 0, 0) == (0, 100, 50) + assert rgb_to_hsl(255, 51, 51) == (0, 100, 60) + assert rgb_to_hsl(255, 102, 102) == (0, 100, 70) + assert rgb_to_hsl(255, 153, 153) == (0, 100, 80) + assert rgb_to_hsl(255, 204, 204) == (0, 100, 90) + assert rgb_to_hsl(255, 255, 255) == (0, 0, 100) + + +def test_hsl_to_rgb_part_14(): + assert hsl_to_rgb(60, 100, 0) == (0, 0, 0) + assert hsl_to_rgb(60, 100, 10) == (51, 51, 0) + assert hsl_to_rgb(60, 100, 20) == (102, 102, 0) + assert hsl_to_rgb(60, 100, 30) == (153, 153, 0) + assert hsl_to_rgb(60, 100, 40) == (204, 204, 0) + assert hsl_to_rgb(60, 100, 50) == (255, 255, 0) + assert hsl_to_rgb(60, 100, 60) == (255, 255, 51) + assert hsl_to_rgb(60, 100, 70) == (255, 255, 102) + assert hsl_to_rgb(60, 100, 80) == (255, 255, 153) + assert hsl_to_rgb(60, 100, 90) == (255, 255, 204) + assert hsl_to_rgb(60, 100, 100) == (255, 255, 255) + + +def test_rgb_to_hsl_part_14(): + # assert rgb_to_hsl(0, 0, 0) == (60, 100, 0) + assert rgb_to_hsl(51, 51, 0) == (60, 100, 10) + assert rgb_to_hsl(102, 102, 0) == (60, 100, 20) + assert rgb_to_hsl(153, 153, 0) == (60, 100, 30) + assert rgb_to_hsl(204, 204, 0) == (60, 100, 40) + assert rgb_to_hsl(255, 255, 0) == (60, 100, 50) + assert rgb_to_hsl(255, 255, 51) == (60, 100, 60) + assert rgb_to_hsl(255, 255, 102) == (60, 100, 70) + assert rgb_to_hsl(255, 255, 153) == (60, 100, 80) + assert rgb_to_hsl(255, 255, 204) == (60, 100, 90) + # assert rgb_to_hsl(255, 255, 255) == (60, 100, 100) + + +def test_hsl_to_rgb_part_15(): + assert hsl_to_rgb(120, 100, 0) == (0, 0, 0) + assert hsl_to_rgb(120, 100, 10) == (0, 51, 0) + assert hsl_to_rgb(120, 100, 20) == (0, 102, 0) + assert hsl_to_rgb(120, 100, 30) == (0, 153, 0) + assert hsl_to_rgb(120, 100, 40) == (0, 204, 0) + assert hsl_to_rgb(120, 100, 50) == (0, 255, 0) + assert hsl_to_rgb(120, 100, 60) == (51, 255, 51) + assert hsl_to_rgb(120, 100, 70) == (102, 255, 102) + assert hsl_to_rgb(120, 100, 80) == (153, 255, 153) + assert hsl_to_rgb(120, 100, 90) == (204, 255, 204) + assert hsl_to_rgb(120, 100, 100) == (255, 255, 255) + + +def test_rgb_to_hsl_part_15(): + # assert rgb_to_hsl(0, 0, 0) == (120, 100, 0) + assert rgb_to_hsl(0, 51, 0) == (120, 100, 10) + assert rgb_to_hsl(0, 102, 0) == (120, 100, 20) + assert rgb_to_hsl(0, 153, 0) == (120, 100, 30) + assert rgb_to_hsl(0, 204, 0) == (120, 100, 40) + assert rgb_to_hsl(0, 255, 0) == (120, 100, 50) + assert rgb_to_hsl(51, 255, 51) == (120, 100, 60) + assert rgb_to_hsl(102, 255, 102) == (120, 100, 70) + assert rgb_to_hsl(153, 255, 153) == (120, 100, 80) + assert rgb_to_hsl(204, 255, 204) == (120, 100, 90) + # assert rgb_to_hsl(255, 255, 255) == (120, 100, 100) + + +def test_hsl_to_rgb_part_16(): + assert hsl_to_rgb(180, 100, 0) == (0, 0, 0) + assert hsl_to_rgb(180, 100, 10) == (0, 51, 51) + assert hsl_to_rgb(180, 100, 20) == (0, 102, 102) + assert hsl_to_rgb(180, 100, 30) == (0, 153, 153) + assert hsl_to_rgb(180, 100, 40) == (0, 204, 204) + assert hsl_to_rgb(180, 100, 50) == (0, 255, 255) + assert hsl_to_rgb(180, 100, 60) == (51, 255, 255) + assert hsl_to_rgb(180, 100, 70) == (102, 255, 255) + assert hsl_to_rgb(180, 100, 80) == (153, 255, 255) + assert hsl_to_rgb(180, 100, 90) == (204, 255, 255) + assert hsl_to_rgb(180, 100, 100) == (255, 255, 255) + + +def test_rgb_to_hsl_part_16(): + # assert rgb_to_hsl(0, 0, 0) == (180, 100, 0) + assert rgb_to_hsl(0, 51, 51) == (180, 100, 10) + assert rgb_to_hsl(0, 102, 102) == (180, 100, 20) + assert rgb_to_hsl(0, 153, 153) == (180, 100, 30) + assert rgb_to_hsl(0, 204, 204) == (180, 100, 40) + assert rgb_to_hsl(0, 255, 255) == (180, 100, 50) + assert rgb_to_hsl(51, 255, 255) == (180, 100, 60) + assert rgb_to_hsl(102, 255, 255) == (180, 100, 70) + assert rgb_to_hsl(153, 255, 255) == (180, 100, 80) + assert rgb_to_hsl(204, 255, 255) == (180, 100, 90) + # assert rgb_to_hsl(255, 255, 255) == (180, 100, 100) + + +def test_hsl_to_rgb_part_17(): + assert hsl_to_rgb(240, 100, 0) == (0, 0, 0) + assert hsl_to_rgb(240, 100, 10) == (0, 0, 51) + assert hsl_to_rgb(240, 100, 20) == (0, 0, 102) + assert hsl_to_rgb(240, 100, 30) == (0, 0, 153) + assert hsl_to_rgb(240, 100, 40) == (0, 0, 204) + assert hsl_to_rgb(240, 100, 50) == (0, 0, 255) + assert hsl_to_rgb(240, 100, 60) == (51, 51, 255) + assert hsl_to_rgb(240, 100, 70) == (102, 102, 255) + assert hsl_to_rgb(240, 100, 80) == (153, 153, 255) + assert hsl_to_rgb(240, 100, 90) == (204, 204, 255) + assert hsl_to_rgb(240, 100, 100) == (255, 255, 255) + + +def test_rgb_to_hsl_part_17(): + # assert rgb_to_hsl(0, 0, 0) == (240, 100, 0) + assert rgb_to_hsl(0, 0, 51) == (240, 100, 10) + assert rgb_to_hsl(0, 0, 102) == (240, 100, 20) + assert rgb_to_hsl(0, 0, 153) == (240, 100, 30) + assert rgb_to_hsl(0, 0, 204) == (240, 100, 40) + assert rgb_to_hsl(0, 0, 255) == (240, 100, 50) + assert rgb_to_hsl(51, 51, 255) == (240, 100, 60) + assert rgb_to_hsl(102, 102, 255) == (240, 100, 70) + assert rgb_to_hsl(153, 153, 255) == (240, 100, 80) + assert rgb_to_hsl(204, 204, 255) == (240, 100, 90) + # assert rgb_to_hsl(255, 255, 255) == (240, 100, 100) + + +def test_hsl_to_rgb_part_18(): + assert hsl_to_rgb(300, 100, 0) == (0, 0, 0) + assert hsl_to_rgb(300, 100, 10) == (51, 0, 51) + assert hsl_to_rgb(300, 100, 20) == (102, 0, 102) + assert hsl_to_rgb(300, 100, 30) == (153, 0, 153) + assert hsl_to_rgb(300, 100, 40) == (204, 0, 204) + assert hsl_to_rgb(300, 100, 50) == (255, 0, 255) + assert hsl_to_rgb(300, 100, 60) == (255, 51, 255) + assert hsl_to_rgb(300, 100, 70) == (255, 102, 255) + assert hsl_to_rgb(300, 100, 80) == (255, 153, 255) + assert hsl_to_rgb(300, 100, 90) == (255, 204, 255) + assert hsl_to_rgb(300, 100, 100) == (255, 255, 255) + + +def test_rgb_to_hsl_part_18(): + # assert rgb_to_hsl(0, 0, 0) == (300, 100, 0) + assert rgb_to_hsl(51, 0, 51) == (300, 100, 10) + assert rgb_to_hsl(102, 0, 102) == (300, 100, 20) + assert rgb_to_hsl(153, 0, 153) == (300, 100, 30) + assert rgb_to_hsl(204, 0, 204) == (300, 100, 40) + assert rgb_to_hsl(255, 0, 255) == (300, 100, 50) + assert rgb_to_hsl(255, 51, 255) == (300, 100, 60) + assert rgb_to_hsl(255, 102, 255) == (300, 100, 70) + assert rgb_to_hsl(255, 153, 255) == (300, 100, 80) + assert rgb_to_hsl(255, 204, 255) == (300, 100, 90) + # assert rgb_to_hsl(255, 255, 255) == (300, 100, 100) diff --git a/pygal/test/test_style.py b/pygal/test/test_style.py index 5048aee..73f0650 100644 --- a/pygal/test/test_style.py +++ b/pygal/test/test_style.py @@ -16,7 +16,7 @@ # # You should have received a copy of the GNU Lesser General Public License # along with pygal. If not, see . -from pygal.style import Style, darken, lighten +from pygal.style import Style def test_colors(): @@ -102,21 +102,3 @@ def test_colors(): fill: rgb(12, 231, 3); } ''' - - -def test_darken(): - assert darken('#800', 20) == '#220000' - assert darken('#ffffff', 10) == '#e6e6e6' - assert darken('#f3148a', 25) == '#810747' - assert darken('#121212', 1) == '#0f0f0f' - assert darken('#999999', 100) == '#000000' - assert darken('#1479ac', 8) == '#105f87' - - -def test_lighten(): - assert lighten('#800', 20) == '#ee0000' - assert lighten('#ffffff', 10) == '#ffffff' - assert lighten('#f3148a', 25) == '#f98dc6' - assert lighten('#121212', 1) == '#151515' - assert lighten('#999999', 100) == '#ffffff' - assert lighten('#1479ac', 8) == '#1893d1' diff --git a/pygal/test/test_util.py b/pygal/test/test_util.py index c301066..4051253 100644 --- a/pygal/test/test_util.py +++ b/pygal/test/test_util.py @@ -19,7 +19,7 @@ from pygal._compat import u from pygal.util import ( round_to_int, round_to_float, _swap_curly, template, humanize, - is_major, truncate, minify_css, rgb_to_hsl, hsl_to_rgb) + is_major, truncate, minify_css) from pytest import raises diff --git a/pygal/util.py b/pygal/util.py index 02ec6a2..0f82fa6 100644 --- a/pygal/util.py +++ b/pygal/util.py @@ -382,54 +382,3 @@ def split_title(title, width, title_fs): title = title[i:].strip() titles.append(title) return titles - - -def rgb_to_hsl(r, g, b): - r /= 255 - g /= 255 - b /= 255 - max_ = max((r, g, b)) - min_ = min((r, g, b)) - d = max_ - min_ - - if not d: - h = 0 - elif r is max_: - h = 60 * (g - b) / d - elif g is max_: - h = 60 * (b - r) / d + 120 - else: - h = 60 * (r - g) / d + 240 - - l = .5 * (max_ + min_) - if not d: - s = 0 - elif l < 0.5: - s = .5 * d / l - else: - s = .5 * d / (1 - l) - - return h % 360, s * 100, l * 100 - - -def hsl_to_rgb(h, s, l): - h /= 360 - s /= 100 - l /= 100 - - m2 = l * (s + 1) if l <= .5 else l + s - l * s - m1 = 2 * l - m2 - - def h_to_rgb(h): - h = h % 1 - if 6 * h < 1: - return m1 + 6 * h * (m2 - m1) - if 2 * h < 1: - return m2 - if 3 * h < 2: - return m1 + 6 * (2 / 3 - h) * (m2 - m1) - return m1 - r, g, b = map(lambda x: round(x * 255), - map(h_to_rgb, (h + 1 / 3, h, h - 1 / 3))) - - return r, g, b