Browse Source

format to private

pull/8/head
Florian Mounier 13 years ago
parent
commit
6ca2500fdf
  1. 1
      .gitignore
  2. 3
      pygal/config.py
  3. 4
      pygal/graph/bar.py
  4. 35
      pygal/graph/base.py
  5. 8
      pygal/graph/graph.py
  6. 4
      pygal/graph/line.py
  7. 4
      pygal/graph/radar.py
  8. 2
      pygal/graph/stackedbar.py
  9. 6
      pygal/graph/xy.py

1
.gitignore vendored

@ -2,3 +2,4 @@
.livereload
dist
.tox
.coverage

3
pygal/config.py

@ -104,6 +104,7 @@ class Config(object):
self.__dict__.update(kwargs)
def font_sizes(self, with_unit=True):
"""Getter for all font size configs"""
fs = FontSizes()
for name in dir(self):
if name.endswith('_font_size'):
@ -111,5 +112,5 @@ class Config(object):
fs,
name.replace('_font_size', ''),
('%dpx' % getattr(self, name)
) if with_unit else getattr(self, name))
) if with_unit else getattr(self, name))
return fs

4
pygal/graph/bar.py

@ -40,7 +40,7 @@ class Bar(Graph):
if None in (x, y):
continue
# x and y are left range coords and X, Y right ones
val = self.format(values[i][1][1])
val = self._format(values[i][1][1])
if self._horizontal:
x, y, X, Y = Y, X, y, x
width = X - x
@ -112,7 +112,7 @@ class Bar(Graph):
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)
self._y_labels = zip(map(self._format, y_pos), y_pos)
def _plot(self):
for serie in self.series:

35
pygal/graph/base.py

@ -31,26 +31,35 @@ class BaseGraph(object):
"""Graphs commons"""
def __init__(self, config=None, **kwargs):
"""Init the graph"""
self.config = config or Config()
self.config(**kwargs)
self.svg = Svg(self)
self.series = []
self._x_labels = self._y_labels = None
def add(self, title, values):
"""Add a serie to this graph"""
self.series.append(Serie(title, values, len(self.series)))
def _init(self):
"""Init the graph"""
self.margin = Margin(*([20] * 4))
self._box = Box()
def __getattr__(self, attr):
"""Search in config, then in self"""
if attr in dir(self.config):
return object.__getattribute__(self.config, attr)
return object.__getattribute__(self, attr)
@property
def format(self):
def _format(self):
"""Return the value formatter for this graph"""
return humanize if self.human_readable else str
def _compute_logarithmic_scale(self, min_, max_):
"""Compute an optimal scale for logarithmic"""
min_order = int(floor(log10(min_)))
max_order = int(ceil(log10(max_)))
positions = []
@ -71,6 +80,7 @@ class BaseGraph(object):
return positions
def _compute_scale(self, min_, max_, min_scale=4, max_scale=20):
"""Compute an optimal scale between min and max"""
if min_ == 0 and max_ == 0:
return [0]
if max_ - min_ == 0:
@ -99,19 +109,26 @@ class BaseGraph(object):
return positions
def _text_len(self, lenght, fs):
"""Approximation of text length"""
return lenght * 0.6 * fs
def _get_text_box(self, text, fs):
"""Approximation of text bounds"""
return (fs, self._text_len(len(text), fs))
def _get_texts_box(self, texts, fs):
"""Approximation of multiple texts bounds"""
max_len = max(map(len, texts))
return (fs, self._text_len(max_len, fs))
def _compute(self):
"""Initial computations to draw the graph"""
def _plot(self):
"""Actual plotting of the graph"""
def _compute_margin(self):
"""Compute graph margins from set texts"""
if self.show_legend:
h, w = self._get_texts_box(
cut(self.series, 'title'), self.legend_font_size)
@ -138,10 +155,12 @@ class BaseGraph(object):
@cached_property
def _legends(self):
"""Getter for series title"""
return [serie.title for serie in self.series]
@cached_property
def _values(self):
"""Getter for series values (flattened)"""
return [val
for serie in self.series
for val in serie.values
@ -149,18 +168,18 @@ class BaseGraph(object):
@cached_property
def _len(self):
"""Getter for the maximum series size"""
return max([len(serie.values) for serie in self.series])
def _draw(self):
"""Draw all the things"""
self._compute()
self._compute_margin()
self._decorate()
self._plot()
def add(self, title, values):
self.series.append(Serie(title, values, len(self.series)))
def _has_data(self):
"""Check if there is any data"""
if len(self.series) == 0:
return False
for serie in self.series:
@ -171,6 +190,7 @@ class BaseGraph(object):
return True
def _render(self):
"""Make the graph internally"""
self._init()
self.svg._init()
if self._has_data():
@ -180,30 +200,37 @@ class BaseGraph(object):
self.svg._pre_render(True)
def render(self, is_unicode=False):
"""Render the graph, and return the svg string"""
self._render()
return self.svg.render(is_unicode=is_unicode)
def render_tree(self):
"""Render the graph, and return lxml tree"""
self._render()
return self.svg.root
def render_pyquery(self):
"""Render the graph, and return a pyquery wrapped tree"""
from pyquery import PyQuery as pq
return pq(self.render_tree())
def render_in_browser(self):
"""Render the graph, open it in your browser with black magic"""
from lxml.html import open_in_browser
open_in_browser(self.render_tree(), encoding='utf-8')
def render_response(self):
"""Render the graph, and return a Flask response"""
from flask import Response
return Response(self.render(), mimetype='image/svg+xml')
def render_to_file(self, filename):
"""Render the graph, and write it to filename"""
with io.open(filename, 'w', encoding='utf-8') as f:
f.write(self.render(is_unicode=True))
def render_to_png(self, filename):
"""Render the graph, convert it to png and write it to filename"""
import cairosvg
from io import BytesIO
fakefile = BytesIO()

8
pygal/graph/graph.py

@ -26,6 +26,7 @@ class Graph(BaseGraph):
"""Graph super class containing generic common functions"""
def _decorate(self):
"""Draw all decorations"""
self._set_view()
self._make_graph()
self._x_axis()
@ -34,12 +35,14 @@ class Graph(BaseGraph):
self._title()
def _set_view(self):
"""Assign a view to current graph"""
self.view = (LogView if self.logarithmic else View)(
self.width - self.margin.x,
self.height - self.margin.y,
self._box)
def _make_graph(self):
"""Init common graph svg structure"""
self.graph_node = self.svg.node(
class_='graph %s-graph' % self.__class__.__name__.lower())
self.svg.node(self.graph_node, 'rect',
@ -78,6 +81,7 @@ class Graph(BaseGraph):
self.svg.node(self.tooltip_node, 'text')
def _x_axis(self):
"""Make the x axis: labels and guides"""
if not self._x_labels:
return
@ -105,6 +109,7 @@ class Graph(BaseGraph):
self.x_label_rotation, x, y)
def _y_axis(self):
"""Make the y axis: labels and guides"""
if not self._y_labels:
return
@ -137,6 +142,7 @@ class Graph(BaseGraph):
self.y_label_rotation, x, y)
def _legend(self):
"""Make the legend box"""
if not self.show_legend:
return
legends = self.svg.node(
@ -166,6 +172,7 @@ class Graph(BaseGraph):
).text = title
def _title(self):
"""Make the title"""
if self.title:
self.svg.node(self.graph_node, 'text', class_='title',
x=self.margin.left + self.view.width / 2,
@ -173,6 +180,7 @@ class Graph(BaseGraph):
).text = self.title
def _serie(self, serie):
"""Make serie node"""
return dict(
plot=self.svg.node(
self.plot,

4
pygal/graph/line.py

@ -27,7 +27,7 @@ class Line(Graph):
"""Line graph"""
def _get_value(self, values, i):
return self.format(values[i][1])
return self._format(values[i][1])
@cached_property
def _values(self):
@ -114,7 +114,7 @@ class Line(Graph):
) if not self.y_labels else map(float, self.y_labels)
self._x_labels = self.x_labels and zip(self.x_labels, self._x_pos)
self._y_labels = zip(map(self.format, self._y_pos), self._y_pos)
self._y_labels = zip(map(self._format, self._y_pos), self._y_pos)
def _plot(self):
for serie in self.series:

4
pygal/graph/radar.py

@ -31,7 +31,7 @@ class Radar(Line):
return values
def _get_value(self, values, i):
return self.format(values[i][0])
return self._format(values[i][0])
@cached_property
def _values(self):
@ -126,5 +126,5 @@ class Radar(Line):
self._box.ymin, self._box.ymax, max_scale=8
) if not self.y_labels else map(int, self.y_labels)
self._x_labels = self.x_labels and zip(self.x_labels, self._x_pos)
self._y_labels = zip(map(self.format, self._y_pos), self._y_pos)
self._y_labels = zip(map(self._format, self._y_pos), self._y_pos)
self._box.xmin = self._box.ymin = - self._box.ymax

2
pygal/graph/stackedbar.py

@ -45,7 +45,7 @@ class StackedBar(Bar):
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)
self._y_labels = zip(map(self._format, y_pos), y_pos)
def _plot(self):
stack_vals = [[0, 0] for i in range(self._length)]

6
pygal/graph/xy.py

@ -26,7 +26,7 @@ class XY(Line):
"""XY Line graph"""
def _get_value(self, values, i):
return 'x=%s, y=%s' % tuple(map(self.format, values[i]))
return 'x=%s, y=%s' % tuple(map(self._format, values[i]))
def _compute(self):
xvals = [val[0]
@ -69,5 +69,5 @@ class XY(Line):
x_pos = self._compute_scale(self._box.xmin, self._box.xmax)
y_pos = self._compute_scale(self._box.ymin, self._box.ymax)
self._x_labels = zip(map(self.format, x_pos), x_pos)
self._y_labels = zip(map(self.format, y_pos), y_pos)
self._x_labels = zip(map(self._format, x_pos), x_pos)
self._y_labels = zip(map(self._format, y_pos), y_pos)

Loading…
Cancel
Save