Browse Source

Fix negative bars

pull/8/head
Florian Mounier 13 years ago
parent
commit
2bb0e9e991
  1. 6
      demo/moulinrouge/__init__.py
  2. 2
      pygal/bar.py
  3. 9
      pygal/base.py
  4. 1
      pygal/config.py
  5. 6
      pygal/svg.py
  6. 3
      pygal/test/test_bar.py
  7. 2
      pygal/test/test_line.py

6
demo/moulinrouge/__init__.py

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from flask import Flask, Response, render_template, url_for
from log_colorizer import make_colored_stream_handler
from logging import getLogger, INFO, WARN, DEBUG
from logging import getLogger, INFO, DEBUG
from moulinrouge.data import labels, series
# from pygal.bar import VerticalBar, HorizontalBar
from pygal.line import Line
@ -9,7 +9,6 @@ from pygal.bar import Bar
from pygal.config import Config
from pygal.style import styles
# from pygal.pie import Pie
import math
import string
import random
@ -73,7 +72,8 @@ def create_app():
return
for i in range(random.randrange(1, 10)):
values = [random_value(min, max) for i in range(data)]
values = [random_value((-max, min)[random.randrange(0, 2)],
max) for i in range(data)]
g.add(random_label(), values)
return Response(g.render(), mimetype='image/svg+xml')

2
pygal/bar.py

@ -6,7 +6,7 @@ class Bar(BaseGraph):
def _draw(self):
vals = [val for serie in self.series for val in serie.values]
ymin, ymax = min(min(vals), 0), max(vals)
ymin, ymax = min(min(vals), 0), max(max(vals), 0)
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

9
pygal/base.py

@ -20,13 +20,16 @@ class BaseGraph(object):
return object.__getattribute__(self, attr)
def _y_pos(self, ymin, ymax):
order = round(math.log10(ymax)) - 1
order = round(math.log10(max(abs(ymin), abs(ymax)))) - 1
if (ymax - ymin) / float(10 ** order) < 4:
order -= 1
step = 10 ** order
positions = set()
position = round_to_scale(ymin, step)
while position < ymax:
if self.x_start_at_zero:
position = 0
else:
position = round_to_scale(ymin, step)
while position < (ymax + step):
rounded = round_to_scale(position, self.scale)
if ymin <= rounded <= ymax:
positions.add(rounded)

1
pygal/config.py

@ -12,6 +12,7 @@ class Config(object):
x_labels = None
y_labels = None
title = None
x_start_at_zero = False
def __init__(self, **kwargs):
self.__dict__.update(kwargs)

6
pygal/svg.py

@ -164,11 +164,15 @@ class Svg(object):
bar_padding = .1 * bar_width
bar_inner_width = bar_width - 2 * bar_padding
offset = serie.index * bar_width + bar_padding
height = self.view.y(0) - y
if height < 0:
y = y + height
height = -height
self.node(serie_node, 'rect',
x=x + padding + offset,
y=y,
width=bar_inner_width,
height=self.view.y(0) - y,
height=height,
class_='rect')
def render(self):

3
pygal/test/test_bar.py

@ -4,8 +4,9 @@ from math import cos, sin
def test_simple_bar():
bar = Bar()
rng = [12, 3, 30, -5, 40, 10, 9, 2]
rng = [-3, -32, -39]
bar.add('test1', rng)
bar.add('test2', map(abs, rng))
bar.x_labels = map(str, rng)
bar.title = "Bar test"
bar._in_browser()

2
pygal/test/test_line.py

@ -4,7 +4,7 @@ from math import cos, sin
def test_simple_line():
line = Line(Config(scale=.5))
line = Line(Config(scale=.0005))
rng = range(-30, 31, 5)
line.add('test1', [cos(x / 10.) for x in rng])
line.add('test2', [sin(x / 10.) for x in rng])

Loading…
Cancel
Save