Browse Source

Added new option to config 'half_pie' to allow only creating half of a pie chart, for Kozea#123 [Fixes: #123]

pull/130/head
Phil 11 years ago committed by Florian Mounier
parent
commit
b7a678e479
  1. 1
      CHANGELOG
  2. 8
      demo/moulinrouge/tests.py
  3. 7
      pygal/config.py
  4. 22
      pygal/graph/pie.py
  5. 38
      pygal/test/test_donut.py

1
CHANGELOG

@ -1,5 +1,6 @@
V 1.5.0 UNRELEASED V 1.5.0 UNRELEASED
Add per serie configuration Add per serie configuration
Add half pie (thanks philt2001)
V 1.4.6 V 1.4.6
Add support for \n separated multiline titles (thanks sirlark) Add support for \n separated multiline titles (thanks sirlark)

8
demo/moulinrouge/tests.py

@ -479,6 +479,14 @@ def get_test_routes(app):
return pie.render_response() return pie.render_response()
@app.route('/test/half_pie')
def test_half_pie():
pie = Pie(half_pie=True)
for i in range(10):
pie.add(str(i), i, inner_radius=.1)
return pie.render_response()
@app.route('/test/legend_at_bottom/<chart>') @app.route('/test/legend_at_bottom/<chart>')
def test_legend_at_bottom_for(chart): def test_legend_at_bottom_for(chart):
graph = CHARTS_BY_NAME[chart]() graph = CHARTS_BY_NAME[chart]()

7
pygal/config.py

@ -234,7 +234,12 @@ class Config(CommonConfig):
tooltip_border_radius = Key(0, int, "Look", "Tooltip border radius") tooltip_border_radius = Key(0, int, "Look", "Tooltip border radius")
# Label # inner_radius = Key(
0, float, "Look", "Piechart inner radius (donut), must be <.9")
half_pie = Key(
False, bool, "Look", "Create a half-pie chart")
x_labels = Key( x_labels = Key(
None, list, "Label", None, list, "Label",
"X labels, must have same len than data.", "X labels, must have same len than data.",

22
pygal/graph/pie.py

@ -41,12 +41,20 @@ class Pie(Graph):
serie_angle = 0 serie_angle = 0
total_perc = 0 total_perc = 0
original_start_angle = start_angle original_start_angle = start_angle
center = ((self.width - self.margin.x) / 2., if self.half_pie:
(self.height - self.margin.y) / 2.) center = ((self.width - self.margin.x) / 2.,
(self.height - self.margin.y) / 1.25)
else:
center = ((self.width - self.margin.x) / 2.,
(self.height - self.margin.y) / 2.)
radius = min(center) radius = min(center)
for i, val in enumerate(serie.values): for i, val in enumerate(serie.values):
perc = val / total perc = val / total
angle = 2 * pi * perc if self.half_pie:
angle = 2 * pi * perc / 2
else:
angle = 2 * pi * perc
serie_angle += angle serie_angle += angle
val = '{0:.2%}'.format(perc) val = '{0:.2%}'.format(perc)
metadata = serie.metadata.get(i) metadata = serie.metadata.get(i)
@ -77,7 +85,13 @@ class Pie(Graph):
def _plot(self): def _plot(self):
total = sum(map(sum, map(lambda x: x.values, self.series))) total = sum(map(sum, map(lambda x: x.values, self.series)))
current_angle = 0 if total == 0:
return
if self.half_pie:
current_angle = 3*pi/2
else:
current_angle = 0
for index, serie in enumerate(self.series): for index, serie in enumerate(self.series):
angle = self.slice( angle = self.slice(
self._serie(index), current_angle, serie, total) self._serie(index), current_angle, serie, total)

38
pygal/test/test_donut.py

@ -16,15 +16,10 @@
# #
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>. # along with pygal. If not, see <http://www.gnu.org/licenses/>.
import os
import uuid
from pygal import Pie from pygal import Pie
def test_donut(): def test_donut():
file_name = '/tmp/test_graph-%s.svg' % uuid.uuid4()
if os.path.exists(file_name):
os.remove(file_name)
chart = Pie(inner_radius=.3, pretty_print=True) chart = Pie(inner_radius=.3, pretty_print=True)
chart.title = 'Browser usage in February 2012 (in %)' chart.title = 'Browser usage in February 2012 (in %)'
chart.add('IE', 19.5) chart.add('IE', 19.5)
@ -32,17 +27,12 @@ def test_donut():
chart.add('Chrome', 36.3) chart.add('Chrome', 36.3)
chart.add('Safari', 4.5) chart.add('Safari', 4.5)
chart.add('Opera', 2.3) chart.add('Opera', 2.3)
chart.render_to_file(file_name) assert chart.render()
with open(file_name) as f:
assert 'pygal' in f.read()
os.remove(file_name)
def test_multiseries_donut(): def test_multiseries_donut():
#this just demos that the multiseries pie does not respect the inner_radius # this just demos that the multiseries pie does not respect
file_name = '/tmp/test_graph-%s.svg' % uuid.uuid4() # the inner_radius
if os.path.exists(file_name):
os.remove(file_name)
chart = Pie(inner_radius=.3, pretty_print=True) chart = Pie(inner_radius=.3, pretty_print=True)
chart.title = 'Browser usage by version in February 2012 (in %)' chart.title = 'Browser usage by version in February 2012 (in %)'
chart.add('IE', [5.7, 10.2, 2.6, 1]) chart.add('IE', [5.7, 10.2, 2.6, 1])
@ -50,7 +40,21 @@ def test_multiseries_donut():
chart.add('Chrome', [.3, .9, 17.1, 15.3, .6, .5, 1.6]) chart.add('Chrome', [.3, .9, 17.1, 15.3, .6, .5, 1.6])
chart.add('Safari', [4.4, .1]) chart.add('Safari', [4.4, .1])
chart.add('Opera', [.1, 1.6, .1, .5]) chart.add('Opera', [.1, 1.6, .1, .5])
chart.render_to_file(file_name) assert chart.render()
with open(file_name) as f:
assert 'pygal' in f.read()
os.remove(file_name) def test_half_pie():
pie = Pie()
pie.add('IE', 19.5)
pie.add('Firefox', 36.6)
pie.add('Chrome', 36.3)
pie.add('Safari', 4.5)
pie.add('Opera', 2.3)
half = Pie(half_pie=True)
half.add('IE', 19.5)
half.add('Firefox', 36.6)
half.add('Chrome', 36.3)
half.add('Safari', 4.5)
half.add('Opera', 2.3)
assert pie.render() != half.render()

Loading…
Cancel
Save