Browse Source

Fix interpolation

pull/8/head
Florian Mounier 13 years ago
parent
commit
554e5f4855
  1. 2
      pygal/config.py
  2. 28
      pygal/graph/base.py
  3. 14
      pygal/graph/line.py
  4. 11
      pygal/graph/radar.py
  5. 9
      pygal/graph/stackedline.py
  6. 9
      pygal/graph/xy.py
  7. 15
      pygal/svg.py

2
pygal/config.py

@ -114,6 +114,8 @@ class Config(object):
truncate_label = None
#: Pretty print the svg
pretty_print = False
#: If True don't try to adapt / filter wrong values
strict = False
def __init__(self, **kwargs):
"""Can be instanciated with config kwargs"""

28
pygal/graph/base.py

@ -48,6 +48,13 @@ class BaseGraph(object):
self._box = Box()
self.view = None
if self.series and self._has_data():
self._draw()
else:
self.svg.draw_no_data()
self.svg.pre_render()
def __getattr__(self, attr):
"""Search in config, then in self"""
if attr in dir(self.config):
@ -129,11 +136,6 @@ class BaseGraph(object):
"""Getter for the maximum series value"""
return (self.range and self.range[1]) or max(self._values)
@cached_property
def _cumul_max(self):
"""Getter for the maximum sum of series value"""
return max(map(sum, cut(self.series, 'safe_values')))
@cached_property
def _order(self):
"""Getter for the maximum series value"""
@ -148,27 +150,13 @@ class BaseGraph(object):
def _has_data(self):
"""Check if there is any data"""
if self._order == 0:
return False
if sum(map(len, map(lambda s: s.values, self.series))) == 0:
return False
return True
def _render(self):
"""Make the graph internally"""
if self.series and self._has_data():
self._draw()
self.svg.pre_render(False)
else:
self.svg.pre_render(True)
return sum(map(len, map(lambda s: s.values, self.series))) != 0
def render(self, is_unicode):
"""Render the graph, and return the svg string"""
self._render()
return self.svg.render(
is_unicode=is_unicode, pretty_print=self.pretty_print)
def render_tree(self):
"""Render the graph, and return lxml tree"""
self._render()
return self.svg.root

14
pygal/graph/line.py

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

11
pygal/graph/radar.py

@ -49,7 +49,7 @@ class Radar(Line):
def _values(self):
if self.interpolate:
return [val[0] for serie in self.series
for val in serie.points]
for val in serie.interpolated]
else:
return super(Line, self)._values
@ -109,6 +109,9 @@ class Radar(Line):
delta = 2 * pi / self._len
x_pos = [.5 * pi + i * delta for i in range(self._len + 1)]
for serie in self.series:
serie.points = [
(v, x_pos[i])
for i, v in enumerate(serie.values)]
if self.interpolate:
extend = 2
extended_x_pos = (
@ -119,12 +122,8 @@ class Radar(Line):
extended_vals = (serie.values[-extend:] +
serie.values +
serie.values[:extend])
serie.point = self._interpolate(
serie.interpolated = self._interpolate(
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.xmin = self._box.ymin = - self._max

9
pygal/graph/stackedline.py

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

9
pygal/graph/xy.py

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

15
pygal/svg.py

@ -172,7 +172,7 @@ class Svg(object):
self.graph._tooltip_data(node, val, x, y, classes="centered")
self.graph._static_value(serie_node, val, x, y)
def pre_render(self, no_data=False):
def pre_render(self):
"""Last things to do before rendering"""
self.add_styles()
self.add_scripts()
@ -181,12 +181,13 @@ class Svg(object):
if self.graph.explicit_size:
self.root.set('width', str(self.graph.width))
self.root.set('height', str(self.graph.height))
if no_data:
no_data = self.node(self.root, 'text',
x=self.graph.width / 2,
y=self.graph.height / 2,
class_='no_data')
no_data.text = self.graph.no_data_text
def draw_no_data(self):
no_data = self.node(self.root, 'text',
x=self.graph.width / 2,
y=self.graph.height / 2,
class_='no_data')
no_data.text = self.graph.no_data_text
def render(self, is_unicode=False, pretty_print=False):
"""Last thing to do before rendering"""

Loading…
Cancel
Save