Skip to content

Commit

Permalink
Add title.
Browse files Browse the repository at this point in the history
  • Loading branch information
onyxfish committed May 19, 2016
1 parent 4b545f4 commit 81239a0
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 15 deletions.
2 changes: 1 addition & 1 deletion docs/example.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion example.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
(8, 4)
]

chart = leather.Chart()
chart = leather.Chart('Example chart')
chart.add_lines(data)
chart.add_dots(data)
chart.to_svg('docs/example.svg')
17 changes: 10 additions & 7 deletions leather/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,23 @@ class Axis(Renderable):
"""
A horizontal or vertical chart axis.
"""
def __init__(self, ticks=5, tick_width='1px', tick_size=4, tick_color='#eee', label_color='#9c9c9c', zero_color='#a8a8a8'):
def __init__(self, ticks=5):
self.ticks = ticks
self.tick_width = tick_width
self.tick_size = tick_size
self.tick_color = tick_color
self.label_color = label_color
self.zero_color = zero_color
self.tick_width = '1px'
self.tick_size = 4
self.tick_color = '#eee'
self.label_color = '#9c9c9c'
self.zero_color = '#a8a8a8'

self.label_font_family = 'Monaco'
self.label_font_size = '14px'
self.label_font_char_height = 14
self.label_font_char_width = 8

def compute_text_margin(self, scale, orient):
def estimate_label_margin(self, scale, orient):
"""
Estimate the space needed for the tick labels.
"""
if orient == 'left':
max_len = max(len(six.text_type(t)) for t in scale.ticks(self.ticks))
return max_len * self.label_font_char_width
Expand Down
59 changes: 53 additions & 6 deletions leather/chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@ class Chart(object):
"""
Container for all chart types.
"""
def __init__(self):
def __init__(self, title=None):
self._title = title

self.title_color = '#333'
self.title_font_family = 'Monaco'
self.title_font_size = '16px'
self.title_font_char_height = 20
self.title_font_char_width = 9

self._layers = []
self._types = [None, None]
self._scales = [None, None]
Expand Down Expand Up @@ -129,6 +137,8 @@ def to_svg_group(self, width, height, margin=None):
"""
Render the completechart to an SVG group element that can be placed
inside an :code:`<svg>` tag.
See :meth:`to_svg` for argument descriptions.
"""
if not self._layers:
raise ValueError('You must add at least one series to the chart before rendering.')
Expand All @@ -142,6 +152,8 @@ def to_svg_group(self, width, height, margin=None):
bottom=default_margin,
left=default_margin
)
elif isinstance(margin, int):
margin = Box(margin, margin, margin, margin)
elif not isinstance(margin, Box):
margin = Box(*margin)

Expand All @@ -151,15 +163,38 @@ def to_svg_group(self, width, height, margin=None):
root_group = ET.Element('g')
root_group.set('transform', svg.translate(margin.left, margin.top))

header_group = ET.Element('g')
header_margin = 0

# Title
if self._title:
label = ET.Element('text',
x=six.text_type(0),
y=six.text_type(0),
fill=self.title_color
)
label.set('font-family', self.title_font_family)
label.set('font-size', self.title_font_size)
label.text = six.text_type(self._title)

header_group.append(label)
header_margin += self.title_font_char_height

body_group = ET.Element('g')
body_group.set('transform', svg.translate(0, header_margin))

body_width = root_width
body_height = root_height - header_margin

# Axes
x_scale, x_axis = self._validate_dimension(X)
y_scale, y_axis = self._validate_dimension(Y)

bottom_margin = x_axis.compute_text_margin(x_scale, 'bottom')
left_margin = y_axis.compute_text_margin(y_scale, 'left')
bottom_margin = x_axis.estimate_label_margin(x_scale, 'bottom')
left_margin = y_axis.estimate_label_margin(y_scale, 'left')

canvas_width = root_width - left_margin
canvas_height = root_height - bottom_margin
canvas_width = body_width - left_margin
canvas_height = body_height - bottom_margin

axes_group = ET.Element('g')
axes_group.set('transform', svg.translate(left_margin, 0))
Expand All @@ -174,7 +209,10 @@ def to_svg_group(self, width, height, margin=None):
series_group.append(series.to_svg(canvas_width, canvas_height, x_scale, y_scale))

axes_group.append(series_group)
root_group.append(axes_group)
body_group.append(axes_group)

root_group.append(header_group)
root_group.append(body_group)

return root_group

Expand All @@ -184,6 +222,15 @@ def to_svg(self, path, width=600, height=600, margin=None):
:param path:
Filepath or file-like object to write to.
:param width:
The output width, in SVG user units.
:param height:
The output height, in SVG user units.
:param margin:
An instance of :class:`.Box`, a sequence of offsets in the format
:code:`(top, right, bottom, left)` or a single :code:`int` to be
used for all sides. Or, :code:`None`, in which case a default offset
equal to 5% of :code:`width`.
"""
root = ET.Element('svg',
width=six.text_type(width),
Expand Down

0 comments on commit 81239a0

Please sign in to comment.