mirror of https://github.com/Kozea/pygal.git
Florian Mounier
12 years ago
2 changed files with 115 additions and 0 deletions
@ -0,0 +1,40 @@
|
||||
# -*- coding: utf-8 -*- |
||||
# This file is part of pygal |
||||
# |
||||
# A python svg graph plotting library |
||||
# Copyright © 2012 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 <http://www.gnu.org/licenses/>. |
||||
""" |
||||
Value adapters to use when a chart doesn't accept all value types |
||||
|
||||
""" |
||||
|
||||
|
||||
def positive(x): |
||||
if x is None: |
||||
return |
||||
if x < 0: |
||||
return 0 |
||||
return x |
||||
|
||||
|
||||
def not_zero(x): |
||||
if x == 0: |
||||
return |
||||
return x |
||||
|
||||
|
||||
def none_to_zero(x): |
||||
return x or 0 |
@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*- |
||||
# This file is part of pygal |
||||
# |
||||
# A python svg graph plotting library |
||||
# Copyright © 2012 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 <http://www.gnu.org/licenses/>. |
||||
""" |
||||
Pyramid chart |
||||
|
||||
""" |
||||
|
||||
from __future__ import division |
||||
from pygal.util import compute_scale, safe_enumerate |
||||
from pygal.adapters import positive |
||||
from pygal.graph.bar import Bar |
||||
|
||||
|
||||
class VerticalPyramid(Bar): |
||||
"""Pyramid graph""" |
||||
|
||||
_adapters = [positive] |
||||
|
||||
def _format(self, value): |
||||
return super(VerticalPyramid, self)._format(abs(value)) |
||||
|
||||
def _compute(self): |
||||
positive_vals = zip(*[serie.safe_values |
||||
for index, serie in enumerate(self.series) |
||||
if index % 2]) |
||||
negative_vals = zip(*[serie.safe_values |
||||
for index, serie in enumerate(self.series) |
||||
if not index % 2]) |
||||
positive_sum = map(sum, positive_vals) or [0] |
||||
negative_sum = map(sum, negative_vals) |
||||
|
||||
self._box.ymax = max(max(positive_sum), max(negative_sum)) |
||||
self._box.ymin = - self._box.ymax |
||||
|
||||
x_pos = [ |
||||
x / self._len |
||||
for x in range(self._len + 1) |
||||
] if self._len > 1 else [0, 1] # Center if only one value |
||||
y_pos = compute_scale( |
||||
self._box.ymin, self._box.ymax, self.logarithmic, self.order_min |
||||
) if not self.y_labels else map(float, self.y_labels) |
||||
|
||||
self._x_ranges = zip(x_pos, x_pos[1:]) |
||||
|
||||
self._x_labels = self.x_labels and zip(self.x_labels, [ |
||||
sum(x_range) / 2 for x_range in self._x_ranges]) |
||||
self._y_labels = zip(map(self._format, y_pos), y_pos) |
||||
|
||||
def _plot(self): |
||||
stack_vals = [[0, 0] for i in range(self._len)] |
||||
for index, serie in enumerate(self.series): |
||||
serie_node = self._serie(index) |
||||
stack_vals = self.bar( |
||||
serie_node, serie, [ |
||||
tuple( |
||||
(self._x_ranges[i][j], |
||||
v * (-1 if index % 2 else 1)) for j in range(2)) |
||||
for i, v in safe_enumerate(serie.values)], index, |
||||
stack_vals) |
Loading…
Reference in new issue