diff --git a/pygal/graph/__init__.py b/pygal/graph/__init__.py index 175a099..f9122fa 100644 --- a/pygal/graph/__init__.py +++ b/pygal/graph/__init__.py @@ -36,5 +36,4 @@ CHARTS_NAMES = [ 'VerticalPyramid', 'Dot', 'Gauge', - 'DoubleYLine', ] diff --git a/pygal/graph/line.py b/pygal/graph/line.py index 2ce920b..1534bf8 100644 --- a/pygal/graph/line.py +++ b/pygal/graph/line.py @@ -48,9 +48,13 @@ class Line(Graph): values + [(values[-1][0], zero)]) - def line(self, serie_node, serie): + def line(self, serie_node, serie, rescale=False): """Draw the line serie""" - view_values = map(self.view, serie.points) + if rescale and self.secondary_series: + points = list ((x, self._scale_diff+(y - self._scale_min_2nd) * self._scale) for x, y in serie.points) + else: + points = serie.points + view_values = map(self.view, points) if self.show_dots: for i, (x, y) in enumerate(view_values): if None in (x, y): @@ -87,12 +91,23 @@ class Line(Graph): class_='line reactive' + (' nofill' if not self.fill else '')) def _compute(self): + # X Labels x_pos = [ x / (self._len - 1) for x in range(self._len) ] if self._len != 1 else [.5] # Center if only one value + # XXX: we need to have rescaled serie.values to execute this self._points(x_pos) + x_labels = zip(self.x_labels, x_pos) + + if self.x_labels_num_limit and len(x_labels)>self.x_labels_num_limit: + step = (len(x_labels)-1)/(self.x_labels_num_limit-1) + x_labels = list(x_labels[int(i*step)] for i in range(self.x_labels_num_limit)) + + self._x_labels = self.x_labels and x_labels + # Y Label + if self.include_x_axis: self._box.ymin = min(self._min, 0) self._box.ymax = max(self._max, 0) @@ -104,15 +119,32 @@ class Line(Graph): self._box.ymin, self._box.ymax, self.logarithmic, self.order_min ) if not self.y_labels else map(float, self.y_labels) - x_labels = zip(self.x_labels, x_pos) + self._y_labels = zip(map(self._format, y_pos), y_pos) + # secondary y axis support + if self.secondary_series: + if self.include_x_axis: + ymin = min(self._secondary_min, 0) + ymax = max(self._secondary_max, 0) + else: + ymin = self._secondary_min + ymax = self._secondary_max + print("ymin: %f, ymax: %f" % (ymin, ymax)) + steps = len(y_pos) + left_range = abs(y_pos[-1] - y_pos[0]) + right_range = abs(ymax - ymin) + scale = right_range / (steps-1) + self._y_2nd_labels = list((self._format(ymin+i*scale), pos) for i, pos in enumerate(y_pos)) + + min_2nd = float(self._y_2nd_labels[0][0]) + self._scale = left_range / right_range + self._scale_diff = y_pos[0] + self._scale_min_2nd = min_2nd + - if self.x_labels_num_limit and len(x_labels)>self.x_labels_num_limit: - step = (len(x_labels)-1)/(self.x_labels_num_limit-1) - x_labels = list(x_labels[int(i*step)] for i in range(self.x_labels_num_limit)) - self._x_labels = self.x_labels and x_labels - self._y_labels = zip(map(self._format, y_pos), y_pos) def _plot(self): for index, serie in enumerate(self.series): self.line(self._serie(index), serie) + for index, serie in enumerate(self.secondary_series, len(self.series)): + self.line(self._serie(index), serie, True)