Browse Source

Process major labels as labels. (Fix #263)

pull/290/head
Florian Mounier 9 years ago
parent
commit
57dae84431
  1. 32
      demo/moulinrouge/tests.py
  2. 1
      docs/changelog.rst
  3. 6
      pygal/graph/dual.py
  4. 102
      pygal/graph/graph.py
  5. 2
      pygal/graph/horizontal.py
  6. 2
      pygal/graph/line.py
  7. 4
      pygal/graph/radar.py
  8. 4
      pygal/test/test_config.py

32
demo/moulinrouge/tests.py

@ -344,10 +344,11 @@ def get_test_routes(app):
@app.route('/test/bar')
def test_bar():
bar = Bar(dynamic_print_values=True)
bar = Bar(dynamic_print_values=True, show_minor_x_labels=False)
bar.add('1', [1, 2, 3])
bar.add('2', [4, 5, 6])
bar.x_labels = ['a']
bar.x_labels = [2, 4, 6]
bar.x_labels_major = [4]
return bar.render_response()
@app.route('/test/histogram')
@ -453,7 +454,7 @@ def get_test_routes(app):
@app.route('/test/dateline')
def test_dateline():
dateline = DateLine(show_dots=False)
dateline = DateLine(x_label_rotation=25, show_minor_x_labels=False)
dateline.x_labels = [
date(2013, 1, 1),
date(2013, 7, 1),
@ -462,13 +463,16 @@ def get_test_routes(app):
date(2015, 1, 1),
date(2015, 7, 1)
]
dateline.add('1', [
(date(2013, 1, 2), 300),
(date(2014, 1, 12), 412),
(date(2015, 2, 2), 823),
(date(2013, 2, 22), 672)
dateline.x_labels_major = [
date(2013, 1, 1),
date(2015, 7, 1)
]
dateline.add("Serie", [
(date(2013, 1, 2), 213),
(date(2013, 8, 2), 281),
(date(2014, 12, 7), 198),
(date(2015, 3, 21), 120)
])
dateline.x_label_rotation = 25
return dateline.render_response()
@app.route('/test/timeline')
@ -645,18 +649,20 @@ def get_test_routes(app):
@app.route('/test/x_major_labels/<chart>')
def test_x_major_labels_for(chart):
chart = CHARTS_BY_NAME[chart]()
chart = CHARTS_BY_NAME[chart](show_minor_y_labels=False)
for i in range(12):
chart.add('test', range(12))
chart.x_labels = map(str, range(10))
chart.x_labels = map(str, range(12))
# chart.x_labels_major_count = 4
# chart.x_labels_major = ['1', '5', '11', '1.0', '5.0', '11.0']
# chart.x_labels_major = ['1', '5', '11', 6]
# chart.y_labels_major = [60, 120]
return chart.render_response()
@app.route('/test/y_major_labels/<chart>')
def test_y_major_labels_for(chart):
chart = CHARTS_BY_NAME[chart]()
chart.add('test', zip(*[range(12), range(12)]))
chart.add('test', range(12))
# chart.add('test', zip(*[range(12), range(12)]))
chart.y_labels = range(12)
# chart.y_labels_major_count = 4
chart.y_labels_major = [1.0, 5.0, 11.0]

1
docs/changelog.rst

@ -7,6 +7,7 @@ Changelog
* Add `dynamic_print_values` to show print_values on legend hover. (Fix #279)
* Fix unparse_color for python 3.5+ compatibility (thanks felixonmars, sjourdois)
* Process major labels as labels. (Fix #263)
2.0.8

6
pygal/graph/dual.py

@ -52,6 +52,12 @@ class Dual(Graph):
else:
self._x_labels = list(zip(map(self._x_format, x_pos), x_pos))
def _compute_x_labels_major(self):
# In case of dual, x labels must adapters and so majors too
self.x_labels_major = self.x_labels_major and list(
map(self._x_adapt, self.x_labels_major))
super()._compute_x_labels_major()
def _get_x_label(self, i):
"""Convenience function to get the x_label of a value index"""
return

102
pygal/graph/graph.py

@ -146,7 +146,10 @@ class Graph(PublicApi):
lastlabel = self._x_labels[-1][0]
for label, position in self._x_labels:
major = label in self._x_major_labels
if self.horizontal:
major = position in self._x_labels_major
else:
major = label in self._x_labels_major
if not (self.show_minor_x_labels or major):
continue
guides = self.svg.node(axis, class_='guides')
@ -188,7 +191,7 @@ class Graph(PublicApi):
' always_show' if self.show_x_guides else ''
))
for label, position in self._x_2nd_labels:
major = label in self._x_major_labels
major = label in self._x_labels_major
if not (self.show_minor_x_labels or major):
continue
# it is needed, to have the same structure as primary axis
@ -224,7 +227,11 @@ class Graph(PublicApi):
)
for label, position in self._y_labels:
major = position in self._y_major_labels
if self.horizontal:
major = label in self._y_labels_major
else:
major = position in self._y_labels_major
if not (self.show_minor_y_labels or major):
continue
guides = self.svg.node(axis, class_='%sguides' % (
@ -263,7 +270,7 @@ class Graph(PublicApi):
secondary_ax = self.svg.node(
self.nodes['plot'], class_="axis y2")
for label, position in self._y_2nd_labels:
major = position in self._y_major_labels
major = position in self._y_labels_major
if not (self.show_minor_y_labels or major):
continue
# it is needed, to have the same structure as primary axis
@ -705,57 +712,34 @@ class Graph(PublicApi):
"""Getter for the number of series"""
return len(self.all_series)
@cached_property
def _x_major_labels(self):
"""Getter for the x major label"""
if self.x_labels_major:
return self.x_labels_major
def _x_label_format_if_value(self, label):
if not is_str(label):
return self._x_format(label)
return label
def _compute_x_labels(self):
self._x_labels = self.x_labels and list(
zip(map(self._x_label_format_if_value, self.x_labels),
self._x_pos))
def _compute_x_labels_major(self):
if self.x_labels_major_every:
return [self._x_labels[i][0] for i in range(
self._x_labels_major = [self._x_labels[i][0] for i in range(
0, len(self._x_labels), self.x_labels_major_every)]
if self.x_labels_major_count:
elif self.x_labels_major_count:
label_count = len(self._x_labels)
major_count = self.x_labels_major_count
if (major_count >= label_count):
return [label[0] for label in self._x_labels]
self._x_labels_major = [label[0] for label in self._x_labels]
return [self._x_labels[
else:
self._x_labels_major = [self._x_labels[
int(i * (label_count - 1) / (major_count - 1))][0]
for i in range(major_count)]
return []
@cached_property
def _y_major_labels(self):
"""Getter for the y major label"""
if self.y_labels_major:
return self.y_labels_major
if self.y_labels_major_every:
return [self._y_labels[i][1] for i in range(
0, len(self._y_labels), self.y_labels_major_every)]
if self.y_labels_major_count:
label_count = len(self._y_labels)
major_count = self.y_labels_major_count
if (major_count >= label_count):
return [label[1] for label in self._y_labels]
return [self._y_labels[
int(i * (label_count - 1) / (major_count - 1))][1]
for i in range(major_count)]
return majorize(
cut(self._y_labels, 1)
)
def _compute_x_labels(self):
def format_if_value(label):
if not is_str(label):
return self._x_format(label)
return label
self._x_labels = self.x_labels and list(
zip(map(format_if_value, self.x_labels), self._x_pos))
else:
self._x_labels_major = self.x_labels_major and list(
map(self._x_label_format_if_value, self.x_labels_major)) or []
def _compute_y_labels(self):
y_pos = compute_scale(
@ -780,11 +764,35 @@ class Graph(PublicApi):
else:
self._y_labels = list(zip(map(self._format, y_pos), y_pos))
def _compute_y_labels_major(self):
if self.y_labels_major_every:
self._y_labels_major = [self._y_labels[i][1] for i in range(
0, len(self._y_labels), self.y_labels_major_every)]
elif self.y_labels_major_count:
label_count = len(self._y_labels)
major_count = self.y_labels_major_count
if (major_count >= label_count):
self._y_labels_major = [label[1] for label in self._y_labels]
else:
self._y_labels_major = [self._y_labels[
int(i * (label_count - 1) / (major_count - 1))][1]
for i in range(major_count)]
elif self.y_labels_major:
self._y_labels_major = list(map(self._adapt, self.y_labels_major))
elif self._y_labels:
self._y_labels_major = majorize(cut(self._y_labels, 1))
else:
self._y_labels_major = []
def _draw(self):
"""Draw all the things"""
self._compute()
self._compute_x_labels()
self._compute_x_labels_major()
self._compute_y_labels()
self._compute_y_labels_major()
self._compute_secondary()
self._post_compute()
self._compute_margin()

2
pygal/graph/horizontal.py

@ -34,6 +34,8 @@ class HorizontalGraph(Graph):
def _post_compute(self):
"""After computations transpose labels"""
self._x_labels, self._y_labels = self._y_labels, self._x_labels
self._x_labels_major, self._y_labels_major = (
self._y_labels_major, self._x_labels_major)
self._x_2nd_labels, self._y_2nd_labels = (
self._y_2nd_labels, self._x_2nd_labels)

2
pygal/graph/line.py

@ -101,7 +101,7 @@ class Line(Graph):
continue
if (serie.show_only_major_dots and
self.x_labels and i < len(self.x_labels) and
self.x_labels[i] not in self._x_major_labels):
self.x_labels[i] not in self._x_labels_major):
continue
metadata = serie.metadata.get(i)

4
pygal/graph/radar.py

@ -90,7 +90,7 @@ class Radar(Line):
truncation = self.truncate_label or 25
for label, theta in self._x_labels:
major = label in self._x_major_labels
major = label in self._x_labels_major
if not (self.show_minor_x_labels or major):
continue
guides = self.svg.node(axis, class_='guides')
@ -132,7 +132,7 @@ class Radar(Line):
axis = self.svg.node(self.nodes['plot'], class_="axis y web")
for label, r in reversed(self._y_labels):
major = r in self._y_major_labels
major = r in self._y_labels_major
if not (self.show_minor_y_labels or major):
continue
guides = self.svg.node(axis, class_='%sguides' % (

4
pygal/test/test_config.py

@ -25,6 +25,8 @@ from pygal import (
Pyramid, HorizontalBar, HorizontalStackedBar,
DateTimeLine, TimeLine, DateLine, TimeDeltaLine)
from pygal.graph.map import BaseMap
from pygal.graph.horizontal import HorizontalGraph
from pygal.graph.dual import Dual
from pygal._compat import u
from pygal.test.utils import texts
from tempfile import NamedTemporaryFile
@ -388,7 +390,7 @@ def test_x_label_major(Chart):
Pie, Treemap, Funnel, Dot, Gauge, Histogram, Box,
Pyramid, DateTimeLine, TimeLine, DateLine,
TimeDeltaLine
) or issubclass(Chart, BaseMap) or Chart._dual:
) or issubclass(Chart, (BaseMap, Dual, HorizontalGraph)):
return
chart = Chart()
chart.add('test', range(12))

Loading…
Cancel
Save