From ff4e45790c37fcb6b1fd7f51924de869ea236bb4 Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Fri, 28 Oct 2011 17:52:43 +0200 Subject: [PATCH] Fix line plot --- pygal/css/bar.css | 17 --- pygal/css/graph.css | 99 +++++++++++++++--- pygal/css/plot.css | 193 ----------------------------------- pygal/line.py | 18 ++-- test/moulinrouge/__init__.py | 5 +- 5 files changed, 103 insertions(+), 229 deletions(-) diff --git a/pygal/css/bar.css b/pygal/css/bar.css index 47884b0..28fe842 100644 --- a/pygal/css/bar.css +++ b/pygal/css/bar.css @@ -1,19 +1,2 @@ /* Base styles for pygal bar */ -.bar .dataPointLabel { - fill-opacity: 0; - -webkit-transition: 250ms; -} - -.bar:hover .dataPointLabel { - fill-opacity: 0.9; - fill: #000000; -} - -.upGradientLight { - stop-opacity: 0.6; -} - -.downGradientLight { - stop-opacity: 0.9; -} diff --git a/pygal/css/graph.css b/pygal/css/graph.css index 3930cf1..0034264 100644 --- a/pygal/css/graph.css +++ b/pygal/css/graph.css @@ -86,6 +86,23 @@ } +.bar .dataPointLabel, .lines .dataPointLabel { + fill-opacity: 0; + -webkit-transition: 250ms; +} + +.bar:hover .dataPointLabel, .lines:hover .dataPointLabel { + fill-opacity: 0.9; + fill: #000000; +} + +.upGradientLight { + stop-opacity: 0.6; +} + +.downGradientLight { + stop-opacity: 0.9; +} .key, .fill { fill-opacity: 0.9; @@ -99,54 +116,112 @@ fill-opacity: 0.7; } -.key1, .fill1 { +.key1, .fill1, .dot1 { fill: url(#light1); } -.key2, .fill2 { +.key2, .fill2, .dot2 { fill: url(#light2); } -.key3, .fill3 { +.key3, .fill3, .dot3 { fill: url(#light3); } -.key4, .fill4 { +.key4, .fill4, .dot4 { fill: url(#light4); } -.key5, .fill5 { +.key5, .fill5, .dot5 { fill: url(#light5); } -.key6, .fill6 { +.key6, .fill6, .dot6 { fill: url(#light6); } -.key7, .fill7 { +.key7, .fill7, .dot7 { fill: url(#light7); } -.key8, .fill8 { +.key8, .fill8, .dot8 { fill: url(#light8); } -.key9, .fill9 { +.key9, .fill9, .dot9 { fill: url(#light9); } -.key10, .fill10 { +.key10, .fill10, .dot10 { fill: url(#light10); } -.key11, .fill11 { +.key11, .fill11, .dot11 { fill: url(#light11); } -.key12, .fill12 { +.key12, .fill12, .dot12 { fill: url(#light12); } +.line { + fill: none; + stroke-width: 1.5px; + -webkit-transition: 250ms; +} + +.line:hover { + stroke-width: 3px; +} + +.key1, .line1 { + stroke: url(#light1); +} + +.key2, .line2 { + stroke: url(#light2); +} + +.key3, .line3 { + stroke: url(#light3); +} + +.key4, .line4 { + stroke: url(#light4); +} + +.key5, .line5 { + stroke: url(#light5); +} + +.key6, .line6 { + stroke: url(#light6); +} + +.key7, .line7 { + stroke: url(#light7); +} + +.key8, .line8 { + stroke: url(#light8); +} + +.key9, .line9 { + stroke: url(#light9); +} + +.key10, .line10 { + stroke: url(#light10); +} + +.key11, .line11 { + stroke: url(#light11); +} + +.key12, .line12 { + stroke: url(#light12); +} + .light1 { stop-color: #2a4269; diff --git a/pygal/css/plot.css b/pygal/css/plot.css index f849203..e69de29 100644 --- a/pygal/css/plot.css +++ b/pygal/css/plot.css @@ -1,193 +0,0 @@ -/* -$Id$ - -default line styles -*/ -.line1{ - fill: none; - stroke: #ff0000; - stroke-width: 1px; -} -.line2{ - fill: none; - stroke: #0000ff; - stroke-width: 1px; -} -.line3{ - fill: none; - stroke: #00ff00; - stroke-width: 1px; -} -.line4{ - fill: none; - stroke: #ffcc00; - stroke-width: 1px; -} -.line5{ - fill: none; - stroke: #00ccff; - stroke-width: 1px; -} -.line6{ - fill: none; - stroke: #ff00ff; - stroke-width: 1px; -} -.line7{ - fill: none; - stroke: #00ffff; - stroke-width: 1px; -} -.line8{ - fill: none; - stroke: #ffff00; - stroke-width: 1px; -} -.line9{ - fill: none; - stroke: #cc6666; - stroke-width: 1px; -} -.line10{ - fill: none; - stroke: #663399; - stroke-width: 1px; -} -.line11{ - fill: none; - stroke: #339900; - stroke-width: 1px; -} -.line12{ - fill: none; - stroke: #9966FF; - stroke-width: 1px; -} -/* default fill styles */ -.fill1{ - fill: #cc0000; - fill-opacity: 0.2; - stroke: none; -} -.fill2{ - fill: #0000cc; - fill-opacity: 0.2; - stroke: none; -} -.fill3{ - fill: #00cc00; - fill-opacity: 0.2; - stroke: none; -} -.fill4{ - fill: #ffcc00; - fill-opacity: 0.2; - stroke: none; -} -.fill5{ - fill: #00ccff; - fill-opacity: 0.2; - stroke: none; -} -.fill6{ - fill: #ff00ff; - fill-opacity: 0.2; - stroke: none; -} -.fill7{ - fill: #00ffff; - fill-opacity: 0.2; - stroke: none; -} -.fill8{ - fill: #ffff00; - fill-opacity: 0.2; - stroke: none; -} -.fill9{ - fill: #cc6666; - fill-opacity: 0.2; - stroke: none; -} -.fill10{ - fill: #663399; - fill-opacity: 0.2; - stroke: none; -} -.fill11{ - fill: #339900; - fill-opacity: 0.2; - stroke: none; -} -.fill12{ - fill: #9966FF; - fill-opacity: 0.2; - stroke: none; -} -/* default line styles */ -.key1,.dataPoint1{ - fill: #ff0000; - stroke: none; - stroke-width: 1px; -} -.key2,.dataPoint2{ - fill: #0000ff; - stroke: none; - stroke-width: 1px; -} -.key3,.dataPoint3{ - fill: #00ff00; - stroke: none; - stroke-width: 1px; -} -.key4,.dataPoint4{ - fill: #ffcc00; - stroke: none; - stroke-width: 1px; -} -.key5,.dataPoint5{ - fill: #00ccff; - stroke: none; - stroke-width: 1px; -} -.key6,.dataPoint6{ - fill: #ff00ff; - stroke: none; - stroke-width: 1px; -} -.key7,.dataPoint7{ - fill: #00ffff; - stroke: none; - stroke-width: 1px; -} -.key8,.dataPoint8{ - fill: #ffff00; - stroke: none; - stroke-width: 1px; -} -.key9,.dataPoint9{ - fill: #cc6666; - stroke: none; - stroke-width: 1px; -} -.key10,.dataPoint10{ - fill: #663399; - stroke: none; - stroke-width: 1px; -} -.key11,.dataPoint11{ - fill: #339900; - stroke: none; - stroke-width: 1px; -} -.key12,.dataPoint12{ - fill: #9966FF; - stroke: none; - stroke-width: 1px; -} -.constantLine{ - color: navy; - stroke: navy; - stroke-width: 1px; - stroke-dasharray: 9,1,1; -} diff --git a/pygal/line.py b/pygal/line.py index c8ba8c1..512e295 100644 --- a/pygal/line.py +++ b/pygal/line.py @@ -70,11 +70,13 @@ class Line(Graph): scale_division = self.scale_divisions or (scale_range / 10.0) if self.scale_integers: - scale_division = min(1, round(scale_division)) + scale_division = round(scale_division) or 1 if max_value % scale_division == 0: max_value += scale_division labels = tuple(float_range(min_value, max_value, scale_division)) + if self.scale_integers: + labels = map(int, labels) return labels def get_y_labels(self): @@ -97,7 +99,8 @@ class Line(Graph): y_label_values = self.get_y_label_values() y_label_span = max(y_label_values) - min(y_label_values) - field_height /= float(y_label_span) + if y_label_span != 0: + field_height /= float(y_label_span) field_width = self.field_width() #line = len(self.data) @@ -144,28 +147,31 @@ class Line(Graph): 'Z' )) node(self.graph, 'path', { - 'class': 'fill%s' % line_n, + 'class': 'fill fill%s' % line_n, 'd': d, }) # now draw the line itself node(self.graph, 'path', { 'd': 'M0 %s L%s' % (self.graph_height, line_path), - 'class': 'line%s' % line_n, + 'class': 'line line%s' % line_n, }) if self.show_data_points or self.show_data_values: for i, value in enumerate(cum_sum): + group = node(self.graph, "g", + {'class': 'lines'}) if self.show_data_points: node( - self.graph, + group, 'circle', - {'class': 'dataPoint%s' % line_n}, + {'class': 'dot dot%s' % line_n}, cx=str(field_width * i), cy=str(self.graph_height - value * field_height), r='2.5', ) self.make_datapoint_text( + group, field_width * i, self.graph_height - value * field_height - 6, value + min_value diff --git a/test/moulinrouge/__init__.py b/test/moulinrouge/__init__.py index 60c87cf..df44dad 100644 --- a/test/moulinrouge/__init__.py +++ b/test/moulinrouge/__init__.py @@ -4,6 +4,7 @@ from log_colorizer import make_colored_stream_handler from logging import getLogger, INFO, WARN, DEBUG from moulinrouge.data import labels, series from pygal.bar import VerticalBar, HorizontalBar +from pygal.line import Line from pygal.pie import Pie import string import random @@ -57,6 +58,8 @@ def create_app(): elif type == 'pie': series = 1 g = Pie({'fields': labels}) + elif type == 'line': + g = Line({'fields': labels}) for i in range(series): values = [random_value() for i in range(data)] @@ -68,7 +71,7 @@ def create_app(): def all(): width, height = 800, 600 svgs = [url_for('all_svg', type=type) for type in - ('vbar', 'hbar', 'pie')] + ('vbar', 'hbar', 'line', 'pie')] return render_template('svgs.jinja2', svgs=svgs, width=width,