diff --git a/pygal/bar.py b/pygal/bar.py index 6f706c6..e74ae05 100644 --- a/pygal/bar.py +++ b/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)]) diff --git a/pygal/css/graph.css b/pygal/css/graph.css index d74622f..8083511 100644 --- a/pygal/css/graph.css +++ b/pygal/css/graph.css @@ -98,4 +98,13 @@ svg * { stroke-width: 2px; } +.series .rect { + opacity: .8; +} + +.series .rect:hover { + opacity: 1; +} + + {{ style.colors }} diff --git a/pygal/line.py b/pygal/line.py index 166f5a7..70842c5 100644 --- a/pygal/line.py +++ b/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: diff --git a/pygal/svg.py b/pygal/svg.py index 2b1d4d7..62ed4aa 100644 --- a/pygal/svg.py +++ b/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): diff --git a/pygal/test/test_bar.py b/pygal/test/test_bar.py index f9a30f7..19a1076 100644 --- a/pygal/test/test_bar.py +++ b/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" diff --git a/pygal/test/test_line.py b/pygal/test/test_line.py index b999321..c36290d 100644 --- a/pygal/test/test_line.py +++ b/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()