Browse Source

Start bar/histogram

pull/8/head
Florian Mounier 13 years ago
parent
commit
f105cd07b5
  1. 8
      pygal/bar.py
  2. 9
      pygal/css/graph.css
  3. 5
      pygal/line.py
  4. 13
      pygal/svg.py
  5. 2
      pygal/test/test_bar.py
  6. 11
      pygal/test/test_line.py

8
pygal/bar.py

@ -45,14 +45,14 @@ class Bar(BaseGraph):
def draw(self):
self.validate()
x_step = len(self.series[0].values) + 1
x_pos = [x / float(x_step) for x in range(x_step)
x_step = len(self.series[0].values)
x_pos = [x / float(x_step) for x in range(x_step + 1)
] if x_step > 1 else [0, 1] # Center if only one value
x_ranges = zip(x_pos, x_pos[1:])
vals = [val for serie in self.series for val in serie.values]
margin = Margin(*(4 * [10]))
ymin, ymax = min(vals), max(vals)
ymin, ymax = 0, max(vals)
if self.x_labels:
x_labels = [Label(label, sum(x_ranges[i]) / 2)
for i, label in enumerate(self.x_labels)]
@ -77,5 +77,5 @@ class Bar(BaseGraph):
for serie_index, serie in enumerate(self.series):
serie_node = self.svg.serie(serie_index)
self.svg.bar(serie_node, [
((x_ranges[i][0], v), (x_ranges[i][1], v))
tuple((x_ranges[i][j], v) for j in range(2))
for i, v in enumerate(serie.values)])

9
pygal/css/graph.css

@ -98,4 +98,13 @@ svg * {
stroke-width: 2px;
}
.series .rect {
opacity: .8;
}
.series .rect:hover {
opacity: 1;
}
{{ style.colors }}

5
pygal/line.py

@ -37,18 +37,19 @@ class Line(BaseGraph):
return labels
def validate(self):
assert len(self.series)
if self.x_labels:
assert len(self.series[0].values) == len(self.x_labels)
for serie in self.series:
assert len(self.series[0].values) == len(serie.values)
def draw(self):
vals = [val for serie in self.series for val in serie.values]
if not vals:
return
self.validate()
x_step = len(self.series[0].values)
x_pos = [x / float(x_step - 1) for x in range(x_step)
] if x_step != 1 else [.5] # Center if only one value
vals = [val for serie in self.series for val in serie.values]
margin = Margin(*(4 * [10]))
ymin, ymax = min(vals), max(vals)
if self.x_labels:

13
pygal/svg.py

@ -148,17 +148,24 @@ class Svg(object):
d='M%s L%s' % (origin, svg_values), class_='line')
def bar(self, serie, values, origin=None):
view_values = map(lambda x: (self.view(x[0]), self.view(x[1])), values)
"""Draw a bar graph for a serie"""
# value here is a list of tuple range of tuple coord
def view(rng):
"""Project range"""
return (self.view(rng[0]), self.view(rng[1]))
view_values = map(view, values)
for i, ((x, y), (X, Y)) in enumerate(view_values):
# x and y are left range coords and X, Y right ones
width = X - x
padding = .1 * width
width = width - 2 * padding
self.node(serie, 'rect',
width=width,
height=self.view.y(0) - y,
x=x + padding,
y=y,
width=width,
height=self.view.y(0) - y,
class_='rect')
def render(self):

2
pygal/test/test_bar.py

@ -4,7 +4,7 @@ from math import cos, sin
def test_simple_bar():
bar = Bar(800, 600, precision=2, format='f')
rng = [12, 3, 30, 4, 0]
rng = [12, 3, 30, 4, 40, 10, 9, 2]
bar.add('test1', rng)
bar.x_labels = map(str, rng)
bar.title = "Bar test"

11
pygal/test/test_line.py

@ -18,3 +18,14 @@ def test_one_dot():
line.add('one dot', [12])
line.x_labels = ['one']
line.render()
def test_no_dot():
line = Line(800, 600)
line.add('no dot', [])
line.render()
def test_no_dot_at_all():
line = Line(800, 600)
line.render()

Loading…
Cancel
Save