From 0d89ab4dd863eb0b3b6fec56fccb1be5e978d9a8 Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Thu, 2 Feb 2012 17:54:42 +0100 Subject: [PATCH] Add series title --- pygal/css/graph.css | 118 +++++++++++++++++++++++++++++++++++++--- pygal/line.py | 4 +- pygal/svg.py | 27 +++++++-- pygal/test/test_line.py | 3 +- 4 files changed, 137 insertions(+), 15 deletions(-) diff --git a/pygal/css/graph.css b/pygal/css/graph.css index d570348..74d6c09 100644 --- a/pygal/css/graph.css +++ b/pygal/css/graph.css @@ -6,8 +6,21 @@ fill: #111; } -.axis text { +.graph { fill: #777; +} + +.legend text { + font-size: 12px; + font-family: sans; + alignment-baseline: hanging; +} + +.legend rect { + stroke: #555; +} + +.axis text { font-size: 12px; font-family: sans; } @@ -31,6 +44,23 @@ stroke-dasharray: 5,5; } +.axis.x .guide.line { + stroke: none; +} + +.axis .guides:hover .guide.line { + stroke: #aaa; +} + +.axis .guides:hover text { + fill: #aaa; +} + +.series .dots .dot circle { + stroke-width: 9px; + stroke: transparent; +} + .series .dots .dot text { font-size: 10px; text-anchor: middle; @@ -45,20 +75,90 @@ .series .line { fill: none; - stroke-width: 1.5px; + stroke-width: 1px; } .series .line:hover { fill: none; - stroke-width: 3px; + stroke-width: 2px; +} + +.color-0 { + stroke: #ff5995; + fill: #ff5995; +} + +.color-1 { + stroke: #b6e354; + fill: #b6e354; +} + +.color-2 { + stroke: #feed6c; + fill: #feed6c; +} + +.color-3 { + stroke: #8cedff; + fill: #8cedff; +} + +.color-4 { + stroke: #9e6ffe; + fill: #9e6ffe; +} + +.color-5 { + stroke: #899ca1; + fill: #899ca1; +} + +.color-6 { + stroke: #f8f8f2; + fill: #f8f8f2; +} + +.color-7 { + stroke: #808384; + fill: #808384; +} + +.color-8 { + stroke: #bf4646; + fill: #bf4646; +} + +.color-9 { + stroke: #516083; + fill: #516083; +} + +.color-10 { + stroke: #f92672; + fill: #f92672; +} + +.color-11 { + stroke: #82b414; + fill: #82b414; +} + +.color-12 { + stroke: #fd971f; + fill: #fd971f; +} + +.color-13 { + stroke: #56c2d6; + fill: #56c2d6; } -.serie-0 { - stroke: blue; - fill: blue; +.color-14 { + stroke: #8c54fe; + fill: #8c54fe; } -.serie-1 { - stroke: red; - fill: red; +.color-15 { + stroke: #465457; + fill: #465457; } diff --git a/pygal/line.py b/pygal/line.py index d02ff39..6c8de18 100644 --- a/pygal/line.py +++ b/pygal/line.py @@ -47,16 +47,18 @@ class Line(BaseGraph): ymin, ymax = min(vals), max(vals) x_labels = self.x_labels y_labels = self.y_labels(ymin, ymax) + series_labels = [serie.title for serie in self.series] margin.left += 10 + max( map(len, [l.label for l in y_labels])) * 0.6 * self.label_font_size margin.bottom += 10 + self.label_font_size + margin.right += 40 + max(map(len, series_labels)) # Actual drawing - self.svg.set_view(margin, ymin, ymax) self.svg.graph(margin) self.svg.x_axis(x_labels) self.svg.y_axis(y_labels) + self.svg.legend(margin, series_labels) for serie_index, serie in enumerate(self.series): serie_node = self.svg.serie(serie_index) self.svg.line(serie_node, [ diff --git a/pygal/svg.py b/pygal/svg.py index 1611379..e49ace4 100644 --- a/pygal/svg.py +++ b/pygal/svg.py @@ -75,8 +75,14 @@ class Svg(object): d='M%f %f v%f' % (0, 0, self.view.height), class_='line') for label in labels: + guides = self.node(axis, class_='guides') x = self.view.x(label.pos) - text = self.node(axis, 'text', x=x, y=self.view.height + 5) + if x != 0: + self.node(guides, 'path', + d='M%f %f v%f' % (x, 0, self.view.height), + class_='guide line') + + text = self.node(guides, 'text', x=x, y=self.view.height + 5) text.text = label.label def y_axis(self, labels): @@ -86,16 +92,29 @@ class Svg(object): d='M%f %f h%f' % (0, self.view.height, self.view.width), class_='line') for label in labels: + guides = self.node(axis, class_='guides') y = self.view.y(label.pos) if y != self.view.height: - self.node(axis, 'path', + self.node(guides, 'path', d='M%f %f h%f' % (0, y, self.view.width), class_='guide line') - text = self.node(axis, 'text', x=-5, y=y) + text = self.node(guides, 'text', x=-5, y=y) text.text = label.label + def legend(self, margin, titles): + legend = self.node( + self.graph, class_='legend', + transform='translate(%d, %d)' % ( + margin.left + self.view.width + 10, margin.top + 10)) + for i, title in enumerate(titles): + self.node(legend, 'rect', x=0, y=i * 15, + width=8, height=8, class_="color-%d" % i, + ).text = title + self.node(legend, 'text', x=15, y=i * 15).text = title + def serie(self, serie): - return self.node(self.plot, class_='series serie-%d' % serie) + return self.node( + self.plot, class_='series serie-%d color-%d' % (serie, serie)) def line(self, serie, values, origin=None): view_values = map(self.view, values) diff --git a/pygal/test/test_line.py b/pygal/test/test_line.py index 1d791ba..e9bd624 100644 --- a/pygal/test/test_line.py +++ b/pygal/test/test_line.py @@ -4,7 +4,8 @@ from math import cos, sin def test_simple_line(): line = Line(800, 600) - line.add('test2', [cos(x / 10.) for x in range(-30, 30, 5)]) + line.add('test1', [cos(x / 10.) for x in range(-30, 30, 5)]) line.add('test2', [sin(x / 10.) for x in range(-30, 30, 5)]) + line.add('test3', [cos(x / 10.) - sin(x / 10.) for x in range(-30, 30, 5)]) line.set_labels(map(str, range(-30, 30, 5))) line._in_browser()