diff --git a/demo/simple_test.py b/demo/simple_test.py index 3e6c29e..41ea34f 100755 --- a/demo/simple_test.py +++ b/demo/simple_test.py @@ -128,7 +128,7 @@ hstackedbar.render_to_file('out-horizontalstackedbar.svg') line = Line(Config(style=NeonStyle, zero=.0001, fill=True, - human_readable=not True, logarithmic=True)) + human_readable=not True, logarithmic=not True)) rng = range(-30, 31, 1) # line.add('test1', [1000 ** cos(x / 10.) for x in rng]) @@ -145,9 +145,13 @@ rng = range(-30, 31, 1) # line.add('_', [2 ** -3, 2.9 ** -8, 2]) # line.add('_', [.001, .0001, .00001]) # line.add('_', [1 + 10 ** 10, 3 + 10 ** 10, 2 + 10 ** 10]) -line.add('_', [1, lnk(4), None, 2, 8, lnk(-2), None, lnk(2)]) +# line.add('_', [1, lnk(4), None, 2, 8, lnk(-2), None, lnk(2)]) +line.add('_', [0, .5, 1]) line.x_labels = map(str, rng) +line.order_min = 0 line.title = "Line test" +# line.range = (40000, 70000) +# line.y_labels = [40000, 50000, 60000, 70000] # line.interpolate = "cubic" line.interpolation_precision = 200 line.render_to_file('out-line.svg') @@ -181,16 +185,16 @@ pie = Pie(Config(style=NeonStyle)) for i in range(10): pie.add('P' + str(i) + '!' * i, [i, 30 - i]) -# pie.js = [ - # 'http://localhost:9898/svg.jquery.js', - # 'http://localhost:9898/pygal-tooltips.js', -# ] +pie.js = [ + 'http://localhost:9898/svg.jquery.js', + 'http://localhost:9898/pygal-tooltips.js', +] # pie.add('test', {'value': 11, 'xlink': 'javascript:alert("lol 11")'}) # pie.add('test2', 1) # pie.add('test3', 5) # pie.title = "Pie test" pie.legend_at_bottom = True -pie.legend_box_size = 100 +pie.legend_box_size = 10 pie.render_to_file('out-pie.svg') config = Config() @@ -207,7 +211,7 @@ radar.title = "Radar test" radar.render_to_file('out-radar.svg') -call(['wsreload', '--url', "file:///*/*/kozea/pygal/*"]) +# call(['wsreload', '--url', "file:///*/*/kozea/pygal/*"]) print "Ok (%dms)" % (1000 * (time.time() - t_start)) diff --git a/pygal/__init__.py b/pygal/__init__.py index 541a3b9..d6c0e6a 100644 --- a/pygal/__init__.py +++ b/pygal/__init__.py @@ -21,7 +21,7 @@ Pygal - A python svg graph plotting library """ -__version__ = '0.10.1' +__version__ = '0.10.3' from pygal.config import Config from pygal.graph.bar import Bar diff --git a/pygal/config.py b/pygal/config.py index 6a67c0f..b8a1e19 100644 --- a/pygal/config.py +++ b/pygal/config.py @@ -39,6 +39,8 @@ class Config(object): human_readable = False #: Display values in logarithmic scale logarithmic = False + #: Minimum order of scale, defaults to None + order_min = None #: List of css file, can be an absolute file path or an external link css = ('style.css', 'graph.css') # Relative path to pygal css #: List of js file, can be a filepath or an external link diff --git a/pygal/graph/bar.py b/pygal/graph/bar.py index dae45b2..642bb35 100644 --- a/pygal/graph/bar.py +++ b/pygal/graph/bar.py @@ -120,7 +120,7 @@ class Bar(Graph): x_pos = [x / self._len for x in range(self._len + 1) ] if self._len > 1 else [0, 1] # Center if only one value y_pos = compute_scale( - self._box.ymin, self._box.ymax, self.logarithmic + self._box.ymin, self._box.ymax, self.logarithmic, self.order_min ) if not self.y_labels else map(float, self.y_labels) self._x_ranges = zip(x_pos, x_pos[1:]) diff --git a/pygal/graph/funnel.py b/pygal/graph/funnel.py index 3067864..fd037e8 100644 --- a/pygal/graph/funnel.py +++ b/pygal/graph/funnel.py @@ -84,7 +84,7 @@ class Funnel(Graph): self._box.ymax = val_max y_pos = compute_scale( - self._box.ymin, self._box.ymax, self.logarithmic + self._box.ymin, self._box.ymax, self.logarithmic, self.order_min ) if not self.y_labels else map(float, self.y_labels) self._x_labels = zip(cut(self.series, 'title'), diff --git a/pygal/graph/gauge.py b/pygal/graph/gauge.py index 04ae35e..5daa43a 100644 --- a/pygal/graph/gauge.py +++ b/pygal/graph/gauge.py @@ -114,7 +114,7 @@ class Gauge(Graph): self.max_ += 1 x_pos = compute_scale( - self.min_, self.max_, self.logarithmic + self.min_, self.max_, self.logarithmic, self.order_min ) self._x_labels = zip(map(self._format, x_pos), x_pos) diff --git a/pygal/graph/graph.py b/pygal/graph/graph.py index 28ec526..3c4f785 100644 --- a/pygal/graph/graph.py +++ b/pygal/graph/graph.py @@ -87,7 +87,8 @@ class Graph(BaseGraph): self.nodes['tooltip'] = self.svg.node( self.nodes['tooltip_overlay'], id="tooltip", - transform='translate(0 0)') + transform='translate(0 0)', + style="opacity: 0") a = self.svg.node(self.nodes['tooltip'], 'a') self.svg.node(a, 'rect', diff --git a/pygal/graph/line.py b/pygal/graph/line.py index 7f69766..e5bfb32 100644 --- a/pygal/graph/line.py +++ b/pygal/graph/line.py @@ -114,7 +114,7 @@ class Line(Graph): self._box.ymax = self._max y_pos = compute_scale( - self._box.ymin, self._box.ymax, self.logarithmic + self._box.ymin, self._box.ymax, self.logarithmic, self.order_min ) if not self.y_labels else map(float, self.y_labels) self._x_labels = self.x_labels and zip(self.x_labels, x_pos) diff --git a/pygal/graph/pyramid.py b/pygal/graph/pyramid.py index 58a5d48..bf63c4d 100644 --- a/pygal/graph/pyramid.py +++ b/pygal/graph/pyramid.py @@ -51,7 +51,7 @@ class VerticalPyramid(Bar): for x in range(self._len + 1) ] if self._len > 1 else [0, 1] # Center if only one value y_pos = compute_scale( - self._box.ymin, self._box.ymax, self.logarithmic + self._box.ymin, self._box.ymax, self.logarithmic, self.order_min ) if not self.y_labels else map(float, self.y_labels) self._x_ranges = zip(x_pos, x_pos[1:]) diff --git a/pygal/graph/radar.py b/pygal/graph/radar.py index cb3b1e8..6f16d59 100644 --- a/pygal/graph/radar.py +++ b/pygal/graph/radar.py @@ -128,7 +128,7 @@ class Radar(Line): self._box.xmax = self._box.ymax = self._rmax = self._max y_pos = compute_scale( - 0, self._box.ymax, self.logarithmic, max_scale=8 + 0, self._box.ymax, self.logarithmic, self.order_min, max_scale=8 ) if not self.y_labels else map(int, self.y_labels) self._x_labels = self.x_labels and zip(self.x_labels, x_pos) self._y_labels = zip(map(self._format, y_pos), y_pos) diff --git a/pygal/graph/stackedbar.py b/pygal/graph/stackedbar.py index 48092a5..8a5ceeb 100644 --- a/pygal/graph/stackedbar.py +++ b/pygal/graph/stackedbar.py @@ -45,7 +45,7 @@ class StackedBar(Bar): for x in range(self._len + 1) ] if self._len > 1 else [0, 1] # Center if only one value y_pos = compute_scale( - self._box.ymin, self._box.ymax, self.logarithmic + self._box.ymin, self._box.ymax, self.logarithmic, self.order_min ) if not self.y_labels else map(float, self.y_labels) self._x_ranges = zip(x_pos, x_pos[1:]) diff --git a/pygal/graph/xy.py b/pygal/graph/xy.py index a803e91..bebfc65 100644 --- a/pygal/graph/xy.py +++ b/pygal/graph/xy.py @@ -70,9 +70,9 @@ class XY(Line): self._box.xmin, self._box.xmax = min(xvals), max(xvals) self._box.ymin, self._box.ymax = min(yvals), max(yvals) x_pos = compute_scale( - self._box.xmin, self._box.xmax, self.logarithmic) + self._box.xmin, self._box.xmax, self.logarithmic, self.order_min) y_pos = compute_scale( - self._box.ymin, self._box.ymax, self.logarithmic) + self._box.ymin, self._box.ymax, self.logarithmic, self.order_min) self._x_labels = zip(map(self._format, x_pos), x_pos) self._y_labels = zip(map(self._format, y_pos), y_pos) diff --git a/pygal/util.py b/pygal/util.py index 2e1592f..2c6d200 100644 --- a/pygal/util.py +++ b/pygal/util.py @@ -146,7 +146,8 @@ def compute_logarithmic_scale(min_, max_): return positions -def compute_scale(min_, max_, logarithmic=False, min_scale=4, max_scale=20): +def compute_scale(min_, max_, logarithmic=False, order_min=None, + min_scale=4, max_scale=20): """Compute an optimal scale between min and max""" if min_ == 0 and max_ == 0: return [0] @@ -158,8 +159,12 @@ def compute_scale(min_, max_, logarithmic=False, min_scale=4, max_scale=20): return log_scale # else we fallback to normal scalling order = round(log10(max(abs(min_), abs(max_)))) - 1 - while (max_ - min_) / (10 ** order) < min_scale: - order -= 1 + if order < order_min: + order = order_min + else: + while ((max_ - min_) / (10 ** order) < min_scale and + (order_min == None or order > order_min)): + order -= 1 step = float(10 ** order) while (max_ - min_) / step > max_scale: step *= 2.