Skip to content

Commit

Permalink
Compatibility with python 2.6 and 3.2. Yay!
Browse files Browse the repository at this point in the history
  • Loading branch information
paradoxxxzero committed Mar 30, 2012
1 parent 2e71911 commit 4e3d585
Show file tree
Hide file tree
Showing 17 changed files with 106 additions and 36 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.svg
.livereload
dist
.tox
7 changes: 4 additions & 3 deletions pygal/graph/bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division
from pygal.graph.graph import Graph
from pygal.util import swap, ident

Expand Down Expand Up @@ -78,7 +79,7 @@ def view(rng):
class_='rect reactive tooltip-trigger')
self.svg.node(bar, 'desc', class_="values").text = val
tooltip_positions = map(
str, (x + bar_inner_width / 2., y + height / 2.))
str, (x + bar_inner_width / 2, y + height / 2))
self.svg.node(bar, 'desc',
class_="x centered"
).text = tooltip_positions[int(self._horizontal)]
Expand All @@ -103,14 +104,14 @@ def _compute(self):
self._box.ymin = min(min(self._values), self.zero)
self._box.ymax = max(max(self._values), self.zero)
x_step = len(self.series[0].values)
x_pos = [x / float(x_step) for x in range(x_step + 1)
x_pos = [x / x_step for x in range(x_step + 1)
] if x_step > 1 else [0, 1] # Center if only one value
y_pos = self._compute_scale(self._box.ymin, self._box.ymax,
) 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])
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):
Expand Down
32 changes: 26 additions & 6 deletions pygal/graph/base.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# -*- 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/>.
from __future__ import division
import io
from pygal.serie import Serie
from pygal.view import Margin, Box
from pygal.util import round_to_scale, cut, rad, humanize
Expand Down Expand Up @@ -44,7 +64,7 @@ def _compute_logarithmic_scale(self, min_, max_):
detail /= 2
for order in range(min_order, max_order + 1):
for i in range(int(detail)):
tick = (10 * i / detail or 1.) * 10 ** order
tick = (10 * i / detail or 1) * 10 ** order
tick = round_to_scale(tick, tick)
if min_ <= tick <= max_ and tick not in positions:
positions.append(tick)
Expand All @@ -61,7 +81,7 @@ def _compute_scale(self, min_, max_, min_scale=4, max_scale=20):
return log_scale
# else we fallback to normal scalling
order = round(log10(max(abs(min_), abs(max_)))) - 1
while (max_ - min_) / float(10 ** order) < min_scale:
while (max_ - min_) / (10 ** order) < min_scale:
order -= 1
step = float(10 ** order)
while (max_ - min_) / step > max_scale:
Expand Down Expand Up @@ -159,9 +179,9 @@ def _render(self):
else:
self.svg._pre_render(True)

def render(self):
def render(self, is_unicode=False):
self._render()
return self.svg.render()
return self.svg.render(is_unicode=is_unicode)

def render_tree(self):
self._render()
Expand All @@ -180,8 +200,8 @@ def render_response(self):
return Response(self.render(), mimetype='image/svg+xml')

def render_to_file(self, filename):
with open(filename, 'w') as f:
f.write(self.render())
with io.open(filename, 'w', encoding='utf-8') as f:
f.write(self.render(is_unicode=True))

def render_to_png(self, filename):
import cairosvg
Expand Down
19 changes: 19 additions & 0 deletions pygal/graph/graph.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
# -*- 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/>.
from __future__ import division
from pygal.graph.base import BaseGraph
from pygal.view import View, LogView
from pygal.util import is_major
Expand Down
5 changes: 3 additions & 2 deletions pygal/graph/line.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division
from pygal.graph.graph import Graph
from pygal.util import cached_property
from pygal.interpolate import interpolation
Expand Down Expand Up @@ -55,9 +56,9 @@ def line(self, serie_node, serie):
continue

classes = []
if x > self.view.width / 2.:
if x > self.view.width / 2:
classes.append('left')
if y > self.view.height / 2.:
if y > self.view.height / 2:
classes.append('top')
classes = ' '.join(classes)

Expand Down
5 changes: 3 additions & 2 deletions pygal/graph/pie.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division
from pygal.graph.graph import Graph
from math import cos, sin, pi
project = lambda rho, alpha: (
Expand All @@ -30,7 +31,7 @@ class Pie(Graph):

def slice(self, serie_node, start_angle, angle, perc,
small=False):
val = '{:.2%}'.format(perc)
val = '{0:.2%}'.format(perc)
slices = self.svg.node(serie_node['plot'], class_="slices")
slice_ = self.svg.node(slices, class_="slice")
center = ((self.width - self.margin.x) / 2.,
Expand Down Expand Up @@ -64,7 +65,7 @@ def slice(self, serie_node, start_angle, angle, perc,
self.svg.node(slice_, 'desc', class_="value").text = val
tooltip_position = map(
str, diff(center, project(
(r + small_r) / 2., start_angle + angle / 2.)))
(r + small_r) / 2, start_angle + angle / 2)))
self.svg.node(slice_, 'desc',
class_="x centered").text = tooltip_position[0]
self.svg.node(slice_, 'desc',
Expand Down
7 changes: 4 additions & 3 deletions pygal/graph/radar.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division
from pygal.graph.line import Line
from pygal.view import PolarView
from pygal.util import deg, cached_property
Expand Down Expand Up @@ -67,7 +68,7 @@ def _x_axis(self):
y=pos_text[1]
)
text.text = label
angle = - theta + pi / 2.
angle = - theta + pi / 2
if cos(angle) < 0:
angle -= pi
text.attrib['transform'] = 'rotate(%f %s)' % (
Expand All @@ -92,7 +93,7 @@ def _y_axis(self):
).text = label

def _compute(self):
delta = 2 * pi / float(self._len)
delta = 2 * pi / self._len
self._x_pos = [.5 * pi + i * delta for i in range(self._len + 1)]
for serie in self.series:
vals = list(serie.values)
Expand All @@ -112,7 +113,7 @@ def _compute(self):
interpolate = interpolation(
extended_x_pos, extended_vals, kind=self.interpolate)
serie.interpolated = []
p = float(self.interpolation_precision)
p = self.interpolation_precision
for s in range(int(p + 1)):
x = .5 * pi + 2 * pi * (s / p)
serie.interpolated.append((float(interpolate(x)), x))
Expand Down
3 changes: 2 additions & 1 deletion pygal/graph/stackedbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division
from pygal.graph.bar import Bar


Expand All @@ -35,7 +36,7 @@ def _compute(self):
min(min(negative_vals), 0), max(max(positive_vals), 0))
self._length = len(self.series[0].values)

x_pos = [x / float(self._length)
x_pos = [x / self._length
for x in range(self._length + 1)
] if self._length > 1 else [0, 1] # Center if only one value
y_pos = self._compute_scale(self._box.ymin, self._box.ymax
Expand Down
3 changes: 2 additions & 1 deletion pygal/graph/xy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division
from pygal.graph.line import Line
from pygal.interpolate import interpolation
from math import isnan
Expand Down Expand Up @@ -48,7 +49,7 @@ def _compute(self):
serie_xmax = max(vals[0])
serie.interpolated = []
r = (max(xvals) - xmin)
p = float(self.interpolation_precision)
p = self.interpolation_precision
for s in range(int(p + 1)):
x = xmin + r * (s / p)
if (serie_xmin <= x <= serie_xmax and not
Expand Down
14 changes: 8 additions & 6 deletions pygal/svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division
import io
import os
from lxml import etree
from pygal.util import template
Expand Down Expand Up @@ -44,23 +46,23 @@ def _init(self):

def add_style(self, css):
style = self.node(self.defs, 'style', type='text/css')
with open(css) as f:
with io.open(css, encoding='utf-8') as f:
templ = template(
f.read(),
style=self.graph.style,
font_sizes=self.graph.font_sizes(),
hidden='y' if self.graph._horizontal else 'x')
style.text = templ.decode('utf-8')
style.text = templ

def add_script(self, js):
script = self.node(self.defs, 'script', type='text/javascript')
with open(js) as f:
with io.open(js, encoding='utf-8') as f:
templ = template(
f.read(),
font_sizes=self.graph.font_sizes(False),
animation_steps=self.graph.animation_steps
)
script.text = templ.decode('utf-8')
script.text = templ

def node(self, parent=None, tag='g', attrib=None, **extras):
if parent is None:
Expand Down Expand Up @@ -119,11 +121,11 @@ def _pre_render(self, no_data=False):
class_='no_data')
no_data.text = self.graph.no_data_text

def render(self):
def render(self, is_unicode=False):
svg = etree.tostring(
self.root, pretty_print=True,
xml_declaration=not self.graph.disable_xml_declaration,
encoding='utf-8')
if self.graph.disable_xml_declaration:
if self.graph.disable_xml_declaration or is_unicode:
svg = svg.decode('utf-8')
return svg
4 changes: 4 additions & 0 deletions pygal/test/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ def test_logarithmic():


def test_logarithmic_bad_interpolation():
try:
import scipy
except ImportError:
return
line = Line(logarithmic=True, interpolate='cubic')
line.add('_', [.001, .00000001, 1])
q = line.render_pyquery()
Expand Down
5 changes: 5 additions & 0 deletions pygal/test/test_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ def test_render_to_file():


def test_render_to_png():
try:
import cairosvg
except ImportError:
return

file_name = '/tmp/test_graph.png'
if os.path.exists(file_name):
os.remove(file_name)
Expand Down
7 changes: 4 additions & 3 deletions pygal/test/test_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division
from pygal import Line
from pygal.test.utils import texts
from math import cos, sin
Expand All @@ -24,9 +25,9 @@
def test_simple_line():
line = Line()
rng = range(-30, 31, 5)
line.add('test1', [cos(x / 10.) for x in rng])
line.add('test2', [sin(x / 10.) for x in rng])
line.add('test3', [cos(x / 10.) - sin(x / 10.) for x in rng])
line.add('test1', [cos(x / 10) for x in rng])
line.add('test2', [sin(x / 10) for x in rng])
line.add('test3', [cos(x / 10) - sin(x / 10) for x in rng])
line.x_labels = map(str, rng)
line.title = "cos sin and cos - sin"
q = line.render_pyquery()
Expand Down
13 changes: 7 additions & 6 deletions pygal/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division
from decimal import Decimal
from math import floor, pi, log, log10
ORDERS = u"yzafpnµm kMGTPEZY"
Expand All @@ -29,9 +30,9 @@ def humanize(number):
order = number and int(floor(log(abs(number)) / log(1000)))
human_readable = ORDERS.split(" ")[int(order > 0)]
if order == 0 or order > len(human_readable):
return float_format(number / float(1000 ** int(order)))
return float_format(number / (1000 ** int(order)))
return (
float_format(number / float(1000 ** int(order))) +
float_format(number / (1000 ** int(order))) +
human_readable[int(order) - int(order > 0)])


Expand All @@ -42,13 +43,13 @@ def is_major(number):

def round_to_int(number, precision):
precision = int(precision)
rounded = (int(number) + precision / 2) / precision * precision
rounded = (int(number) + precision / 2) // precision * precision
return rounded


def round_to_float(number, precision):
rounded = Decimal(
floor((number + precision / 2) / precision)) * Decimal(str(precision))
rounded = Decimal(str(floor((number + precision / 2) // precision))
) * Decimal(str(precision))
return float(rounded)


Expand All @@ -67,7 +68,7 @@ def cut(list_, index=0):


def rad(deg):
return pi * deg / 180.
return pi * deg / 180


def deg(deg):
Expand Down
Loading

0 comments on commit 4e3d585

Please sign in to comment.