Browse Source

Supranations

pull/63/head
Jean-Marc Martins 11 years ago
parent
commit
3422462511
  1. 19
      pygal/ghost.py
  2. 1
      pygal/graph/__init__.py
  3. 101
      pygal/graph/supranationalworldmap.py
  4. 11
      pygal/i18n.py
  5. 6
      pygal/test/test_config.py
  6. 4
      pygal/test/test_graph.py
  7. 10
      pygal/util.py

19
pygal/ghost.py

@ -29,6 +29,7 @@ import sys
from pygal.config import Config
from pygal._compat import u, is_list_like
from pygal.graph import CHARTS_NAMES
from pygal.i18n import SUPRANATIONAL
from pygal.util import prepare_values
from uuid import uuid4
@ -65,11 +66,29 @@ class Ghost(object):
"""Add a serie to this graph"""
if not is_list_like(values) and not isinstance(values, dict):
values = [values]
values = self.replace_supranationals(values)
if secondary:
self.raw_series2.append((title, values))
else:
self.raw_series.append((title, values))
def replace_supranationals(self, values):
"""Replaces the values if it contains a supranational code."""
from pygal import Worldmap
if not isinstance(self, Worldmap):
return values
for suprakey in SUPRANATIONAL.keys():
if suprakey in values:
if not isinstance(values, dict):
del values[values.index(suprakey)]
values.extend(SUPRANATIONAL[suprakey])
else:
values.update(
dict([(code, values[suprakey])
for code in SUPRANATIONAL[suprakey]]))
del values[suprakey]
return values
def make_series(self, series):
return prepare_values(series, self.config, self.cls)

1
pygal/graph/__init__.py

@ -38,6 +38,5 @@ CHARTS_NAMES = [
'Gauge',
'DateY',
'Worldmap',
'SupranationalWorldmap',
'Histogram'
]

101
pygal/graph/supranationalworldmap.py

@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
# This file is part of pygal
#
# A python svg graph plotting library
# Copyright © 2012-2013 Kozea
#
# This library is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
"""
Supranational Worldmap chart
"""
from __future__ import division
from pygal.graph.worldmap import Worldmap
from pygal.i18n import SUPRANATIONAL
from pygal.util import cut, decorate
from lxml import etree
import os
with open(os.path.join(
os.path.dirname(__file__),
'worldmap.svg')) as file:
MAP = file.read()
class SupranationalWorldmap(Worldmap):
"""SupranationalWorldmap graph"""
def _plot(self):
map = etree.fromstring(MAP)
map.set('width', str(self.view.width))
map.set('height', str(self.view.height))
for i, serie in enumerate(self.series):
safe_vals = list(filter(
lambda x: x is not None, cut(serie.values, 1)))
if not safe_vals:
continue
min_ = min(safe_vals)
max_ = max(safe_vals)
serie.values = self.replace_supranationals(serie.values)
for j, (country_code, value) in enumerate(serie.values):
if value is None:
continue
if max_ == min_:
ratio = 1
else:
ratio = .3 + .7 * (value - min_) / (max_ - min_)
country = map.find('.//*[@id="%s"]' % country_code)
if country is None:
continue
cls = country.get('class', '').split(' ')
cls.append('color-%d' % i)
country.set('class', ' '.join(cls))
country.set(
'style', 'fill-opacity: %f' % (
ratio))
metadata = serie.metadata.get(j)
if metadata:
parent = country.getparent()
node = decorate(self.svg, country, metadata)
if node != country:
country.remove(node)
index = parent.index(country)
parent.remove(country)
node.append(country)
parent.insert(index, node)
last_node = len(country) > 0 and country[-1]
if last_node is not None and last_node.tag == 'title':
title_node = last_node
text = title_node.text + '\n'
else:
title_node = self.svg.node(country, 'title')
text = ''
title_node.text = text + '[%s] %s: %d' % (
serie.title,
self.country_names[country_code], value)
self.nodes['plot'].append(map)
def replace_supranationals(self, values):
"""Replaces the values if it contains a supranational code."""
for i, (code, value) in enumerate(values[:]):
for suprakey in SUPRANATIONAL.keys():
if suprakey == code:
values.extend(
[(country, value) for country in SUPRANATIONAL[code]])
values.remove((code, value))
return values

11
pygal/i18n.py

@ -185,12 +185,9 @@ COUNTRIES = {
'zw': 'Zimbabwe'
}
EUROPE = ['at', 'be', 'bg', 'hr', 'cy', 'cz', 'dk', 'ee', 'fi', 'fr', 'de',
'gr', 'hu', 'ie', 'it', 'lv', 'lt', 'lu', 'mt', 'nl', 'pl', 'pt',
'ro', 'sk', 'si', 'es', 'se', 'gb']
EUR = ['be', 'de', 'ie', 'gr', 'es', 'fr', 'it', 'cy', 'lu', 'mt', 'nl', 'at',
'pt', 'si', 'sk', 'fi', 'ee']
EUROPE = ['bg', 'cs', 'da', 'de', 'et', 'el', 'en', 'es', 'fr', 'ga', 'hr',
'it', 'lt', 'lv', 'hu', 'mt', 'nl', 'pl', 'pt', 'ro', 'sk', 'sl',
'fi', 'sv']
OECD = ['au', 'at', 'be', 'ca', 'cl', 'cz', 'dk', 'ee', 'fi', 'fr', 'de', 'gr',
'hu', 'is', 'ie', 'il', 'it', 'jp', 'kr', 'lu', 'mx', 'nl', 'nz', 'no',
@ -199,7 +196,7 @@ OECD = ['au', 'at', 'be', 'ca', 'cl', 'cz', 'dk', 'ee', 'fi', 'fr', 'de', 'gr',
NAFTA = ['ca', 'mx', 'us']
SUPRANATIONAL = {'europe': EUROPE, 'oecd': OECD, 'nafta': NAFTA, 'eur': EUR}
SUPRANATIONAL = {'europe': EUROPE, 'oecd': OECD, 'nafta': NAFTA}
def set_countries(countries):

6
pygal/test/test_config.py

@ -17,8 +17,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from pygal import (
Line, Dot, Pie, Radar, Config, Bar, Funnel, Worldmap,
SupranationalWorldmap, Histogram, Gauge)
Line, Dot, Pie, Radar, Config, Bar, Funnel, Worldmap, Histogram, Gauge)
from pygal._compat import u
from pygal.test.utils import texts
from pygal.test import pytest_generate_tests, make_data
@ -260,8 +259,7 @@ def test_no_data():
def test_include_x_axis(Chart):
chart = Chart()
if Chart in (Pie, Radar, Funnel, Dot, Gauge, Worldmap,
SupranationalWorldmap, Histogram):
if Chart in (Pie, Radar, Funnel, Dot, Gauge, Worldmap, Histogram):
return
if not chart.cls._dual:
data = 100, 200, 150

4
pygal/test/test_graph.py

@ -70,7 +70,7 @@ def test_metadata(Chart):
v = range(7)
if Chart == pygal.XY:
v = list(map(lambda x: (x, x + 1), v))
elif Chart == pygal.Worldmap or Chart == pygal.SupranationalWorldmap:
elif Chart == pygal.Worldmap:
v = list(map(lambda x: x, i18n.COUNTRIES))
chart.add('Serie with metadata', [
@ -94,7 +94,7 @@ def test_metadata(Chart):
if Chart == pygal.Pie:
# Slices with value 0 are not rendered
assert len(v) - 1 == len(q('.tooltip-trigger').siblings('.value'))
elif Chart != pygal.Worldmap and Chart != pygal.SupranationalWorldmap:
elif Chart != pygal.Worldmap:
# Tooltip are not working on worldmap
assert len(v) == len(q('.tooltip-trigger').siblings('.value'))

10
pygal/util.py

@ -300,10 +300,9 @@ def prepare_values(raw, config, cls):
from pygal.graph.datey import DateY
from pygal.graph.histogram import Histogram
from pygal.graph.worldmap import Worldmap
from pygal.graph.supranationalworldmap import SupranationalWorldmap
if config.x_labels is None and hasattr(cls, 'x_labels'):
config.x_labels = cls.x_labels
if config.zero == 0 and issubclass(cls, (Worldmap, SupranationalWorldmap)):
if config.zero == 0 and issubclass(cls, Worldmap):
config.zero = 1
for key in ('x_labels', 'y_labels'):
@ -333,7 +332,7 @@ def prepare_values(raw, config, cls):
metadata = {}
values = []
if isinstance(raw_values, dict):
if issubclass(cls, (Worldmap, SupranationalWorldmap)):
if issubclass(cls, Worldmap):
raw_values = list(raw_values.items())
else:
value_list = [None] * width
@ -365,9 +364,8 @@ def prepare_values(raw, config, cls):
value = (None, None)
elif not is_list_like(value):
value = (value, config.zero)
if issubclass(cls, DateY) or issubclass(
cls, (Worldmap, SupranationalWorldmap)):
value = (adapter(value[0]), value[1])
if issubclass(cls, DateY) or issubclass(cls, Worldmap):
value = (adapter(value[0]), value[1])
else:
value = list(map(adapter, value))
else:

Loading…
Cancel
Save