debian-python-pygal/pygal/graph/time.py

150 lines
3.8 KiB
Python

# -*- coding: utf-8 -*-
# This file is part of pygal
#
# A python svg graph plotting library
# Copyright © 2012-2016 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/>.
"""
XY time extensions: handle convertion of date, time, datetime, timedelta
into float for xy plot and back to their type for display
"""
from datetime import date, datetime, time, timedelta
from pygal._compat import is_str, timestamp
from pygal.adapters import positive
from pygal.graph.xy import XY
def datetime_to_timestamp(x):
"""Convert a datetime into a utc float timestamp"""
if isinstance(x, datetime):
return timestamp(x)
return x
def datetime_to_time(x):
"""Convert a datetime into a time"""
if isinstance(x, datetime):
return x.time()
return x
def date_to_datetime(x):
"""Convert a date into a datetime"""
if not isinstance(x, datetime) and isinstance(x, date):
return datetime.combine(x, time())
return x
def time_to_datetime(x):
"""Convert a time into a datetime"""
if isinstance(x, time):
return datetime.combine(date(1970, 1, 1), x)
return x
def timedelta_to_seconds(x):
"""Convert a timedelta into an amount of seconds"""
if isinstance(x, timedelta):
return x.total_seconds()
return x
def time_to_seconds(x):
"""Convert a time in a seconds sum"""
if isinstance(x, time):
return ((
((x.hour * 60) + x.minute) * 60 + x.second
) * 10 ** 6 + x.microsecond) / 10 ** 6
if is_str(x):
return x
# Clamp to valid time
return x and max(0, min(x, 24 * 3600 - 10 ** -6))
def seconds_to_time(x):
"""Convert a number of second into a time"""
t = int(x * 10 ** 6)
ms = t % 10 ** 6
t = t // 10 ** 6
s = t % 60
t = t // 60
m = t % 60
t = t // 60
h = t
return time(h, m, s, ms)
class DateTimeLine(XY):
"""DateTime abscissa xy graph class"""
_x_adapters = [datetime_to_timestamp, date_to_datetime]
@property
def _x_format(self):
"""Return the value formatter for this graph"""
def datetime_to_str(x):
dt = datetime.utcfromtimestamp(x)
return self.x_value_formatter(dt)
return datetime_to_str
class DateLine(DateTimeLine):
"""Date abscissa xy graph class"""
@property
def _x_format(self):
"""Return the value formatter for this graph"""
def date_to_str(x):
d = datetime.utcfromtimestamp(x).date()
return self.x_value_formatter(d)
return date_to_str
class TimeLine(DateTimeLine):
"""Time abscissa xy graph class"""
_x_adapters = [positive, time_to_seconds, datetime_to_time]
@property
def _x_format(self):
"""Return the value formatter for this graph"""
def date_to_str(x):
t = seconds_to_time(x)
return self.x_value_formatter(t)
return date_to_str
class TimeDeltaLine(XY):
"""TimeDelta abscissa xy graph class"""
_x_adapters = [timedelta_to_seconds]
@property
def _x_format(self):
"""Return the value formatter for this graph"""
def timedelta_to_str(x):
td = timedelta(seconds=x)
return self.x_value_formatter(td)
return timedelta_to_str