Browse Source

Include DateY fixes from #109

113_errors
Florian Mounier 11 years ago
parent
commit
58330ff679
  1. 73
      pygal/graph/datey.py
  2. 18
      pygal/graph/xy.py
  3. 9
      pygal/svg.py
  4. 58
      pygal/test/test_date.py
  5. 1
      pygal/test/test_graph.py

73
pygal/graph/datey.py

@ -30,8 +30,12 @@ def jour(n) :
x=(1,20,35,54,345,898)
x=tuple(map(jour,x))
x_label=(0,100,200,300,400,500,600,700,800,900,1000)
x_label=map(jour,x_label)
y=(1,3,4,2,3,1)
graph=pygal.DateY(x_label_rotation=20)
graph.x_label_format = "%Y-%m-%d"
graph.x_labels = x_label
graph.add("graph1",list(zip(x,y))+[None,None])
graph.render_in_browser()
"""
@ -75,27 +79,19 @@ class DateY(XY):
for serie in self.all_series:
serie.values = [(self._tonumber(v[0]), v[1]) for v in serie.values]
xvals = [val[0]
for serie in self.series
for val in serie.values
if val[0] is not None]
yvals = [val[1]
for serie in self.series
for val in serie.values
if val[1] is not None]
if xvals:
xmin = min(xvals)
xmax = max(xvals)
if self.xvals:
xmin = min(self.xvals)
xmax = max(self.xvals)
rng = (xmax - xmin)
else:
rng = None
if yvals:
ymin = min(yvals)
ymax = max(yvals)
if self.yvals:
ymin = self._min
ymax = self._max
if self.include_x_axis:
ymin = min(ymin or 0, 0)
ymax = max(ymax or 0, 0)
ymin = min(self._min or 0, 0)
ymax = max(self._max or 0, 0)
for serie in self.all_series:
serie.points = serie.values
@ -106,25 +102,46 @@ class DateY(XY):
serie.interpolated = self._interpolate(vals[0], vals[1])
if self.interpolate and rng:
xvals = [val[0]
for serie in self.all_series
for val in serie.interpolated]
yvals = [val[1]
for serie in self.all_series
for val in serie.interpolated]
if xvals:
xmin = min(xvals)
xmax = max(xvals)
self.xvals = [val[0]
for serie in self.all_series
for val in serie.interpolated]
self.yvals = [val[1]
for serie in self.all_series
for val in serie.interpolated]
if self.xvals:
xmin = min(self.xvals)
xmax = max(self.xvals)
rng = (xmax - xmin)
else:
rng = None
if rng:
# Calculate/prcoess the x_labels
if self.x_labels and all(
map(lambda x: isinstance(
x, (datetime.datetime, datetime.date)), self.x_labels)):
# Process the given x_labels
x_labels_num = []
for label in self.x_labels:
x_labels_num.append(self._tonumber(label))
x_pos = x_labels_num
# Update the xmin/xmax to fit all of the x_labels and the data
xmin = min(xmin, min(x_pos))
xmax = max(xmax, max(x_pos))
self._box.xmin, self._box.xmax = xmin, xmax
self._box.ymin, self._box.ymax = ymin, ymax
else:
# Automatically generate the x_labels
if rng:
self._box.xmin, self._box.xmax = xmin, xmax
self._box.ymin, self._box.ymax = ymin, ymax
x_pos = compute_scale(
self._box.xmin, self._box.xmax, self.logarithmic,
self.order_min)
x_pos = compute_scale(
self._box.xmin, self._box.xmax, self.logarithmic, self.order_min)
# Always auto-generate the y labels
y_pos = compute_scale(
self._box.ymin, self._box.ymax, self.logarithmic, self.order_min)

18
pygal/graph/xy.py

@ -44,12 +44,22 @@ class XY(Line):
for val in serie.values
if val[1] is not None]
@cached_property
def _min(self):
return (self.range[0] if (self.range and self.range[0] is not None)
else (min(self.yvals) if self.yvals else None))
@cached_property
def _max(self):
return (self.range[1] if (self.range and self.range[1] is not None)
else (max(self.yvals) if self.yvals else None))
def _has_data(self):
"""Check if there is any data"""
return sum(
map(len, map(lambda s: s.safe_values, self.series))) != 0 and any((
sum(map(abs, self.xvals)) != 0,
sum(map(abs, self.yvals)) != 0))
sum(map(abs, self.xvals)) != 0,
sum(map(abs, self.yvals)) != 0))
def _compute(self):
if self.xvals:
@ -60,8 +70,8 @@ class XY(Line):
xrng = None
if self.yvals:
ymin = min(self.yvals)
ymax = max(self.yvals)
ymin = self._min
ymax = self._max
if self.include_x_axis:
ymin = min(ymin or 0, 0)

9
pygal/svg.py

@ -26,7 +26,7 @@ from pygal._compat import to_str, u
import io
import os
import json
from datetime import date
from datetime import date, datetime
from numbers import Number
from lxml import etree
from math import cos, sin, pi
@ -97,7 +97,12 @@ class Svg(object):
"""Add the js to the svg"""
common_script = self.node(self.defs, 'script', type='text/javascript')
common_script.text = " = ".join(
("window.config", json.dumps(self.graph.config.to_dict())))
("window.config", json.dumps(
self.graph.config.to_dict(),
default=lambda o: (
o.isoformat() if isinstance(o, (datetime, date))
else json.JSONEncoder().default(o))
)))
for js in self.graph.js:
if '://' in js:

58
pygal/test/test_date.py

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
# This file is part of pygal
#
# A python svg graph plotting library
# Copyright © 2012-2014 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 pygal import DateY
from pygal.test.utils import texts
from datetime import datetime
def test_date():
datey = DateY(truncate_label=1000)
datey.add('dates', [
(datetime(2013, 1, 2), 300),
(datetime(2013, 1, 12), 412),
(datetime(2013, 2, 2), 823),
(datetime(2013, 2, 22), 672)
])
q = datey.render_pyquery()
assert list(
map(lambda t: t.split(' ')[0],
q(".axis.x text").map(texts))) == [
'2013-01-02',
'2013-01-13',
'2013-01-25',
'2013-02-05',
'2013-02-17'
]
datey.x_labels = [
datetime(2013, 1, 1),
datetime(2013, 2, 1),
datetime(2013, 3, 1)
]
q = datey.render_pyquery()
assert list(
map(lambda t: t.split(' ')[0],
q(".axis.x text").map(texts))) == [
'2013-01-01',
'2013-02-01',
'2013-03-01'
]

1
pygal/test/test_graph.py

@ -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/>.
import os
import pygal
import uuid

Loading…
Cancel
Save