Skip to content

Commit

Permalink
Merge branch 'master' into solidgauge
Browse files Browse the repository at this point in the history
  • Loading branch information
paradoxxxzero committed Feb 24, 2016
2 parents 013d9c7 + e9ea167 commit f686ff7
Show file tree
Hide file tree
Showing 44 changed files with 661 additions and 257 deletions.
13 changes: 0 additions & 13 deletions demo/moulinrouge.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,6 @@
except:
pass


try:
import wsreload
except ImportError:
app.logger.debug('wsreload not found')
else:
url = "http://moulinrouge.l:21112/*"

def log(httpserver):
app.logger.debug('WSReloaded after server restart')
wsreload.monkey_patch_http_server({'url': url}, callback=log)
app.logger.debug('HTTPServer monkey patched for url %s' % url)

try:
from wdb.ext import WdbMiddleware, add_w_builtin
except ImportError:
Expand Down
27 changes: 14 additions & 13 deletions demo/moulinrouge/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ def _random(data, order):
random_value((-max, min)[random.randrange(0, 2)], max),
random_value((-max, min)[random.randrange(0, 2)], max)
) for i in range(data)]
series.append((random_label(), values))
series.append((random_label(), values, {}))
return series

def _random_series(type, data, order):
max = 10 ** order
min = 10 ** random.randrange(0, order)
with_2nd = bool(random.randint(0, 1))
with_secondary = bool(random.randint(0, 1))
series = []
for i in range(random.randrange(1, 10)):
if type == 'Pie':
Expand All @@ -89,10 +89,10 @@ def _random_series(type, data, order):
else:
values = [random_value((-max, min)[random.randrange(1, 2)],
max) for i in range(data)]
is_2nd = False
if with_2nd:
is_2nd = bool(random.randint(0, 1))
series.append((random_label(), values, is_2nd))
config = {
'secondary': with_secondary and bool(random.randint(0, 1))
}
series.append((random_label(), values, config))
return series

from .tests import get_test_routes
Expand All @@ -110,15 +110,17 @@ def index():
def svg(type, series, config):
graph = get(type)(
pickle.loads(b64decode(str(config))))
for title, values, is_2nd in pickle.loads(b64decode(str(series))):
graph.add(title, values, secondary=is_2nd)
for title, values, serie_config in pickle.loads(
b64decode(str(series))):
graph.add(title, values, **serie_config)
return graph.render_response()

@app.route("/table/<type>/<series>/<config>")
def table(type, series, config):
graph = get(type)(pickle.loads(b64decode(str(config))))
for title, values, is_2nd in pickle.loads(b64decode(str(series))):
graph.add(title, values, secondary=is_2nd)
for title, values, serie_config in pickle.loads(
b64decode(str(series))):
graph.add(title, values, **serie_config)
return graph.render_table()

@app.route("/sparkline/<style>")
Expand Down Expand Up @@ -196,16 +198,15 @@ def all(style='default', color=None, interpolate=None, base_style=None):

xy_series = _random(data, order)
other_series = []
for title, values in xy_series:
for title, values, config in xy_series:
other_series.append(
(title, cut(values, 1)))
(title, cut(values, 1), config))
xy_series = b64encode(pickle.dumps(xy_series))
other_series = b64encode(pickle.dumps(other_series))
config = Config()
config.width = width
config.height = height
config.fill = bool(random.randrange(0, 2))
config.human_readable = True
config.interpolate = interpolate
config.style = style
svgs = []
Expand Down
60 changes: 37 additions & 23 deletions demo/moulinrouge/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from flask import abort
from pygal.style import styles, Style, RotateStyle
from pygal.colors import rotate
from pygal import stats
from pygal import stats, formatters
from pygal.graph.horizontal import HorizontalGraph
from random import randint, choice
from datetime import datetime, date
Expand All @@ -38,7 +38,7 @@ def get_test_routes(app):

@app.route('/test/unsorted')
def test_unsorted():
bar = Bar(style=styles['neon'], human_readable=True)
bar = Bar(style=styles['neon'], value_formatter=formatters.human_readable)
bar.add('A', {'red': 10, 'green': 12, 'blue': 14})
bar.add('B', {'green': 11, 'blue': 7})
bar.add('C', {'blue': 7})
Expand Down Expand Up @@ -373,12 +373,24 @@ def test_bar():
bar.x_labels_major = [4]
return bar.render_response()

@app.route('/test/formatters/<chart>')
def test_formatters_for(chart):
chart = CHARTS_BY_NAME[chart](
print_values=True, formatter=lambda x, chart, serie: '%s%s$' % (
x, serie.title))
chart.add('_a', [1, 2, {'value': 3, 'formatter': lambda x: '%s¥' % x}])
chart.add('_b', [4, 5, 6], formatter=lambda x: '%s€' % x)
chart.x_labels = [2, 4, 6]
chart.x_labels_major = [4]
return chart.render_response()

@app.route('/test/bar/position')
def test_bar_print_values_position():
bar = StackedBar(print_values=True, print_values_position='top', zero=2,
style=styles['default'](
value_font_family='googlefont:Raleway',
value_font_size=46))
bar = StackedBar(
print_values=True, print_values_position='top', zero=2,
style=styles['default'](
value_font_family='googlefont:Raleway',
value_font_size=46))
bar.add('1', [1, -2, 3])
bar.add('2', [4, -5, 6])
bar.x_labels = [2, 4, 6]
Expand All @@ -387,7 +399,10 @@ def test_bar_print_values_position():

@app.route('/test/histogram')
def test_histogram():
hist = Histogram(print_values=True, print_values_position='top', style=styles['neon'])
hist = Histogram(
print_values=True,
print_values_position='top',
style=styles['neon'])
hist.add('1', [
(2, 0, 1),
(4, 1, 3),
Expand Down Expand Up @@ -443,7 +458,7 @@ def test_secondary_xy():
@app.route('/test/box')
def test_box():
chart = Box()
chart.js = ('http://l:2343/2.0.x/pygal-tooltips.js',)
# chart.js = ('http://l:2343/2.0.x/pygal-tooltips.js',)
chart.box_mode = '1.5IQR'
chart.add('One', [15, 8, 2, -12, 9, 23])
chart.add('Two', [5, 8, 2, -9, 23, 12])
Expand Down Expand Up @@ -597,21 +612,9 @@ def test_frenchmapdepartments():
if fr is None:
abort(404)
fmap = fr.Departments(style=choice(list(styles.values())))
fmap.add('', [(69, 2), (42, 7), (38, 3), (26, 0)])
# for i in range(10):
# fmap.add('s%d' % i, [
# (choice(list(fr.DEPARTMENTS.keys())), randint(0, 100))
# for _ in range(randint(1, 5))])

# fmap.add('links', [{
# 'value': (69, 10),
# 'label': '\o/',
# 'xlink': 'http://google.com?q=69'
# }, {
# 'value': ('42', 20),
# 'label': 'Y',
# }])
# fmap.add('6th', [3, 5, 34, 12])
fmap.add('', [(i, i) for i in range(1, 100)])
fmap.add('', [(970 + i, i) for i in range(1, 7)])
fmap.add('', [('2A', 1), ('2B', 2)])
fmap.title = 'French map'
return fmap.render_response()

Expand Down Expand Up @@ -1092,6 +1095,17 @@ def test_ci_for(chart):
chart.range = (30, 200)
return chart.render_response()

@app.route('/test/interruptions')
def test_interruptions():
chart = Line(allow_interruptions=True)
chart.add(
'interrupt', [22, 34, 43, 12, None, 12, 55, None, 56],
allow_interruptions=False)
chart.add('not interrupt', [
-a if a else None
for a in (22, 34, 43, 12, None, 12, 55, None, 56)])
return chart.render_response()

return list(sorted(filter(
lambda x: x.startswith('test') and not x.endswith('_for'), locals()))
) + list(sorted(filter(
Expand Down
7 changes: 7 additions & 0 deletions docs/api/pygal.graph.horizontalline.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pygal.graph.horizontalline module
=================================

.. automodule:: pygal.graph.horizontalline
:members:
:undoc-members:
:show-inheritance:
7 changes: 7 additions & 0 deletions docs/api/pygal.graph.horizontalstackedline.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pygal.graph.horizontalstackedline module
========================================

.. automodule:: pygal.graph.horizontalstackedline
:members:
:undoc-members:
:show-inheritance:
2 changes: 2 additions & 0 deletions docs/api/pygal.graph.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ Submodules
pygal.graph.histogram
pygal.graph.horizontal
pygal.graph.horizontalbar
pygal.graph.horizontalline
pygal.graph.horizontalstackedbar
pygal.graph.horizontalstackedline
pygal.graph.line
pygal.graph.map
pygal.graph.pie
Expand Down
9 changes: 9 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
Changelog
=========

2.2.0 UNRELEASED
=====

* Support interruptions in line charts (thanks @piotrmaslanka #300)
* Fix confidence interval reactiveness (thanks @chartique #296)
* Add horizontal line charts (thanks @chartique #301)
* There is now a `formatter` config option to format values as specified. The formatter callable may or may not take `chart`, `serie` and `index` as argument. The default value formatting is now chart dependent and is value_formatter for most graph but could be a combination of value_formatter and x_value_formatter for dual charts.
* The `human_readable` option has been removed. Now you have to use the pygal.formatters.human_readable formatter (value_formatter=human_readable instead of human_readable=True)

2.1.1
=====

Expand Down
30 changes: 30 additions & 0 deletions docs/documentation/configuration/serie.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,33 @@ inner_radius
chart = pygal.Pie()
for i in range(10):
chart.add(str(i), i, inner_radius=(10 - i) / 10)



allow_interruptions
~~~~~~~~~~~~~~~~~~~

You can set `allow_interruptions` to True in order to break lines on None values.

.. pygal-code::

interrupted_chart = pygal.Line()
interrupted_chart.add(
'Temperature', [22, 34, 43, 12, None, 12, 55, None, 56],
allow_interruptions=True)
interrupted_chart.add(
'Temperature', [11, 17, 21.5, 6, None, 6, 27.5, None, 28])


formatter
~~~~~~~~~

You can add a `formatter` function for this serie values.
It will be used for value printing and tooltip. (Not for axis.)


.. pygal-code::

chart = pygal.Bar(print_values=True, value_formatter=lambda x: '{}$'.format(x))
chart.add('bar', [.0002, .0005, .00035], formatter=lambda x: '<%s>' % x)
chart.add('bar', [.0004, .0009, .001])
13 changes: 13 additions & 0 deletions docs/documentation/configuration/value.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@ The color key set the fill and the stroke style. You can also set the css style
])


Value formatting
~~~~~~~~~~~~~~~~

You can add a `formatter` metadata for a specific value.


.. pygal-code::

chart = pygal.Bar(print_values=True, value_formatter=lambda x: '{}$'.format(x))
chart.add('bar', [.0002, .0005, .00035], formatter=lambda x: '<%s>' % x)
chart.add('bar', [.0004, {'value': .0009, 'formatter': lambda x: '«%s»' % x}, .001])


Node attributes
---------------

Expand Down
7 changes: 7 additions & 0 deletions docs/documentation/types/line.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Basic simple line graph:
line_chart.add('IE', [85.8, 84.6, 84.7, 74.5, 66, 58.6, 54.7, 44.8, 36.2, 26.6, 20.1])
line_chart.add('Others', [14.2, 15.4, 15.3, 8.9, 9, 10.4, 8.9, 5.8, 6.7, 6.8, 7.5])


Stacked
~~~~~~~

Expand Down Expand Up @@ -47,3 +48,9 @@ For time related plots, just format your labels or use `one variant of xy charts
datetime(2013, 2, 2),
datetime(2013, 2, 22)])
date_chart.add("Visits", [300, 412, 823, 672])


None values
~~~~~~~~~~~

None values will be skipped. It is also possible to `break lines <../configuration/serie.html#allow-interruptions>`_.
5 changes: 5 additions & 0 deletions docs/documentation/types/xy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,8 @@ TimeDelta
(timedelta(days=3, microseconds=30), 12),
(timedelta(weeks=1), 10),
])

None values
~~~~~~~~~~~

None values will be skipped. It is also possible to `break lines <../configuration/serie.html#allow-interruptions>`_.
2 changes: 2 additions & 0 deletions pygal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
from pygal.graph.horizontalbar import HorizontalBar
from pygal.graph.horizontalstackedbar import HorizontalStackedBar
from pygal.graph.line import Line
from pygal.graph.horizontalline import HorizontalLine
from pygal.graph.horizontalstackedline import HorizontalStackedLine
from pygal.graph.pie import Pie
from pygal.graph.pyramid import Pyramid, VerticalPyramid
from pygal.graph.radar import Radar
Expand Down
21 changes: 14 additions & 7 deletions pygal/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@

from pygal.interpolate import INTERPOLATIONS
from pygal.style import DefaultStyle, Style
from pygal import formatters


CONFIG_ITEMS = []
callable = type(lambda: 1)


class Key(object):
Expand Down Expand Up @@ -218,6 +220,15 @@ class CommonConfig(BaseConfig):
inner_radius = Key(
0, float, "Look", "Piechart inner radius (donut), must be <.9")

allow_interruptions = Key(
False, bool, "Look", "Break lines on None values")

formatter = Key(
None, callable, "Value",
"A function to convert raw value to strings for this chart or serie",
"Default to value_formatter in most charts, it depends on dual charts."
"(Can be overriden by value with the formatter metadata.)")


class Config(CommonConfig):

Expand Down Expand Up @@ -380,18 +391,14 @@ class Config(CommonConfig):
"'x' (default), 'y' or 'either'")

# Value #
human_readable = Key(
False, bool, "Value", "Display values in human readable format",
"(ie: 12.4M)")

x_value_formatter = Key(
None, type(lambda: 1), "Value",
formatters.default, callable, "Value",
"A function to convert abscissa numeric value to strings "
"(used in XY and Date charts)")

value_formatter = Key(
None, type(lambda: 1), "Value",
"A function to convert numeric value to strings")
formatters.default, callable, "Value",
"A function to convert ordinate numeric value to strings")

logarithmic = Key(
False, bool, "Value", "Display values in logarithmic scale")
Expand Down
4 changes: 4 additions & 0 deletions pygal/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@
stroke-width: 4;
}

{{ id }}.ci .reactive.active {
stroke-width: 1.5;
}

{{ id }}.series text {
fill: {{ style.foreground_strong }};
}
Expand Down
Loading

0 comments on commit f686ff7

Please sign in to comment.