Browse Source

Simplify since charts are recreated from scratch every time

pull/8/head
Florian Mounier 12 years ago
parent
commit
9782569f47
  1. 13
      pygal/graph/horizontal.py
  2. 25
      pygal/graph/line.py
  3. 43
      pygal/graph/radar.py
  4. 10
      pygal/graph/stackedline.py
  5. 13
      pygal/graph/xy.py

13
pygal/graph/horizontal.py

@ -26,21 +26,16 @@ from pygal.graph.graph import Graph
class HorizontalGraph(Graph): class HorizontalGraph(Graph):
"""Horizontal graph""" """Horizontal graph"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.first_pass = True
self.horizontal = True self.horizontal = True
super(HorizontalGraph, self).__init__(*args, **kwargs) super(HorizontalGraph, self).__init__(*args, **kwargs)
def _compute(self): def _compute(self):
self.first_pass = False if self.x_labels:
# Stupid pylint
# pylint: disable-msg=E0203,W0201
if self.first_pass and self.x_labels:
self.x_labels = list(reversed(self.x_labels)) self.x_labels = list(reversed(self.x_labels))
# pylint: enable-msg=W0201,E0203
super(HorizontalGraph, self)._compute() super(HorizontalGraph, self)._compute()
self._x_labels, self._y_labels = self._y_labels, self._x_labels self._x_labels, self._y_labels = self._y_labels, self._x_labels
self._box.swap() self._box.swap()
# Y axis is inverted # Y axis is inverted
if self.first_pass: for serie in self.series:
for serie in self.series: serie.values = list(reversed(serie.values))
serie.values = list(reversed(serie.values))

25
pygal/graph/line.py

@ -38,18 +38,11 @@ class Line(Graph):
@cached_property @cached_property
def _values(self): def _values(self):
if self.interpolate: return [
return [ val[1]
val[1] for serie in self.series
for serie in self.series for val in serie.points
for val in serie.interpolated if val[1] is not None and (not self.logarithmic or val[1] > 0)]
if val[1] is not None and (not self.logarithmic or val[1] > 0)]
else:
return [
val[1]
for serie in self.series
for val in serie.points
if val[1] is not None and (not self.logarithmic or val[1] > 0)]
def _fill(self, values): def _fill(self, values):
"""Add extra values to fill the line""" """Add extra values to fill the line"""
@ -88,8 +81,6 @@ class Line(Graph):
y + self.value_font_size) y + self.value_font_size)
if self.stroke: if self.stroke:
if self.interpolate:
view_values = map(self.view, serie.interpolated)
if self.fill: if self.fill:
view_values = self._fill(view_values) view_values = self._fill(view_values)
self.svg.line( self.svg.line(
@ -102,12 +93,12 @@ class Line(Graph):
] if self._len != 1 else [.5] # Center if only one value ] if self._len != 1 else [.5] # Center if only one value
for serie in self.series: for serie in self.series:
if not hasattr(serie, 'points'): if self.interpolate:
serie.points = self._interpolate(serie.values, x_pos)
else:
serie.points = [ serie.points = [
(x_pos[i], v) (x_pos[i], v)
for i, v in enumerate(serie.values)] for i, v in enumerate(serie.values)]
if self.interpolate:
serie.interpolated = self._interpolate(serie.values, x_pos)
if self.include_x_axis: if self.include_x_axis:
self._box.ymin = min(self._min, 0) self._box.ymin = min(self._min, 0)

43
pygal/graph/radar.py

@ -23,7 +23,7 @@ Radar chart
from __future__ import division from __future__ import division
from pygal.graph.line import Line from pygal.graph.line import Line
from pygal.adapters import positive from pygal.adapters import positive, none_to_zero
from pygal.view import PolarView from pygal.view import PolarView
from pygal.util import deg, cached_property, compute_scale from pygal.util import deg, cached_property, compute_scale
from math import cos, pi from math import cos, pi
@ -32,7 +32,7 @@ from math import cos, pi
class Radar(Line): class Radar(Line):
"""Kiviat graph""" """Kiviat graph"""
_adapters = [positive] _adapters = [positive, none_to_zero]
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.x_pos = None self.x_pos = None
@ -49,7 +49,7 @@ class Radar(Line):
def _values(self): def _values(self):
if self.interpolate: if self.interpolate:
return [val[0] for serie in self.series return [val[0] for serie in self.series
for val in serie.interpolated] for val in serie.points]
else: else:
return super(Line, self)._values return super(Line, self)._values
@ -70,15 +70,16 @@ class Radar(Line):
for label, theta in self._x_labels: for label, theta in self._x_labels:
guides = self.svg.node(axis, class_='guides') guides = self.svg.node(axis, class_='guides')
end = self.view((r, theta)) end = self.view((r, theta))
self.svg.node(guides, 'path', self.svg.node(
d='M%s L%s' % (format_(center), format_(end)), guides, 'path',
class_='line') d='M%s L%s' % (format_(center), format_(end)),
class_='line')
r_txt = (1 - self._box.__class__.margin) * self._box.ymax r_txt = (1 - self._box.__class__.margin) * self._box.ymax
pos_text = self.view((r_txt, theta)) pos_text = self.view((r_txt, theta))
text = self.svg.node(guides, 'text', text = self.svg.node(
x=pos_text[0], guides, 'text',
y=pos_text[1] x=pos_text[0],
) y=pos_text[1])
text.text = label text.text = label
angle = - theta + pi / 2 angle = - theta + pi / 2
if cos(angle) < 0: if cos(angle) < 0:
@ -99,19 +100,15 @@ class Radar(Line):
close=True, close=True,
class_='guide line') class_='guide line')
x, y = self.view((r, self.x_pos[0])) x, y = self.view((r, self.x_pos[0]))
self.svg.node(guides, 'text', self.svg.node(
x=x - 5, guides, 'text',
y=y x=x - 5,
).text = label y=y).text = label
def _compute(self): def _compute(self):
delta = 2 * pi / self._len delta = 2 * pi / self._len
x_pos = [.5 * pi + i * delta for i in range(self._len + 1)] x_pos = [.5 * pi + i * delta for i in range(self._len + 1)]
for serie in self.series: for serie in self.series:
vals = [val if val != None else 0 for val in serie.values]
serie.points = [
(v, x_pos[i])
for i, v in enumerate(vals)]
if self.interpolate: if self.interpolate:
extend = 2 extend = 2
extended_x_pos = ( extended_x_pos = (
@ -119,9 +116,15 @@ class Radar(Line):
x_pos + x_pos +
[.5 * pi + i * delta for i in range( [.5 * pi + i * delta for i in range(
self._len + 1, self._len + 1 + extend)]) self._len + 1, self._len + 1 + extend)])
extended_vals = vals[-extend:] + vals + vals[:extend] extended_vals = (serie.values[-extend:] +
serie.interpolated = self._interpolate( serie.values +
serie.values[:extend])
serie.point = self._interpolate(
extended_vals, extended_x_pos, polar=True) extended_vals, extended_x_pos, polar=True)
else:
serie.points = [
(v, x_pos[i])
for i, v in enumerate(serie.values)]
self._box.margin *= 2 self._box.margin *= 2
self._box.xmin = self._box.ymin = - self._max self._box.xmin = self._box.ymin = - self._max

10
pygal/graph/stackedline.py

@ -49,9 +49,11 @@ class StackedLine(Line):
accumulation = [0] * self._len accumulation = [0] * self._len
for serie in self.series: for serie in self.series:
accumulation = map(sum, zip(accumulation, serie.values)) accumulation = map(sum, zip(accumulation, serie.values))
serie.points = [
(x_pos[i], v)
for i, v in enumerate(accumulation)]
if self.interpolate: if self.interpolate:
serie.interpolated = self._interpolate(accumulation, x_pos) serie.points = self._interpolate(accumulation, x_pos)
else:
serie.points = [
(x_pos[i], v)
for i, v in enumerate(accumulation)]
return super(StackedLine, self)._compute() return super(StackedLine, self)._compute()

13
pygal/graph/xy.py

@ -46,26 +46,25 @@ class XY(Line):
rng = (xmax - xmin) rng = (xmax - xmin)
for serie in self.series: for serie in self.series:
serie.points = serie.values
if self.interpolate: if self.interpolate:
vals = zip(*sorted(serie.points, key=lambda x: x[0])) vals = zip(*sorted(serie.points, key=lambda x: x[0]))
serie.interpolated = self._interpolate( serie.points = self._interpolate(
vals[1], vals[0], xy=True, xy_xmin=xmin, xy_rng=rng) vals[1], vals[0], xy=True, xy_xmin=xmin, xy_rng=rng)
if not serie.interpolated: else:
serie.interpolated = serie.values serie.points = serie.values
if self.interpolate: if self.interpolate:
xvals = [val[0] xvals = [val[0]
for serie in self.series for serie in self.series
for val in serie.interpolated] for val in serie.points]
yvals = [val[1] yvals = [val[1]
for serie in self.series for serie in self.series
for val in serie.interpolated] for val in serie.points]
self._box.xmin, self._box.xmax = min(xvals), max(xvals) self._box.xmin, self._box.xmax = min(xvals), max(xvals)
self._box.ymin, self._box.ymax = min(yvals), max(yvals) self._box.ymin, self._box.ymax = min(yvals), max(yvals)
x_pos = compute_scale( x_pos = compute_scale(
self._box.xmin, self._box.xmax, self.logarithmic, self.order_min) self._box.xmin, self._box.xmax, self.logarithmic, self.order_min)
y_pos = compute_scale( y_pos = compute_scale(
self._box.ymin, self._box.ymax, self.logarithmic, self.order_min) self._box.ymin, self._box.ymax, self.logarithmic, self.order_min)

Loading…
Cancel
Save