dbt-selly/dbt-env/lib/python3.8/site-packages/leather/shapes/line.py

95 lines
2.5 KiB
Python

#!/usr/bin/env python
import xml.etree.ElementTree as ET
import six
from leather.data_types import Text
from leather.series import CategorySeries
from leather.shapes.base import Shape
from leather import theme
from leather.utils import X, Y
class Line(Shape):
"""
Render a series of data as a line.
:param stroke_color:
The color to stroke the lines. If not provided, default chart colors
will be used.
:param width:
The width of the lines. Defaults to :data:`.theme.default_line_width`.
"""
def __init__(self, stroke_color=None, width=None):
self._stroke_color = stroke_color
self._width = width or theme.default_line_width
def validate_series(self, series):
"""
Verify this shape can be used to render a given series.
"""
if isinstance(series, CategorySeries):
raise ValueError('Line can not be used to render CategorySeries.')
if series.data_type(X) is Text or series.data_type(Y) is Text:
raise ValueError('Line does not support Text values.')
def _new_path(self, stroke_color):
"""
Start a new path.
"""
path = ET.Element('path',
stroke=stroke_color,
fill='none'
)
path.set('stroke-width', six.text_type(self._width))
return path
def to_svg(self, width, height, x_scale, y_scale, series, palette):
"""
Render lines to SVG elements.
"""
group = ET.Element('g')
group.set('class', 'series lines')
if self._stroke_color:
stroke_color = self._stroke_color
else:
stroke_color = next(palette)
path = self._new_path(stroke_color)
path_d = []
for d in series.data():
if d.x is None or d.y is None:
if path_d:
path.set('d', ' '.join(path_d))
group.append(path)
path_d = []
path = self._new_path(stroke_color)
continue
proj_x = x_scale.project(d.x, 0, width)
proj_y = y_scale.project(d.y, height, 0)
if not path_d:
command = 'M'
else:
command = 'L'
path_d.extend([
command,
six.text_type(proj_x),
six.text_type(proj_y)
])
if path_d:
path.set('d', ' '.join(path_d))
group.append(path)
return group