diff --git a/pygal/ghost.py b/pygal/ghost.py
index 44f81ce..a991867 100644
--- a/pygal/ghost.py
+++ b/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)
diff --git a/pygal/graph/__init__.py b/pygal/graph/__init__.py
index d464591..d6418ce 100644
--- a/pygal/graph/__init__.py
+++ b/pygal/graph/__init__.py
@@ -38,6 +38,5 @@ CHARTS_NAMES = [
'Gauge',
'DateY',
'Worldmap',
- 'SupranationalWorldmap',
'Histogram'
]
diff --git a/pygal/graph/supranationalworldmap.py b/pygal/graph/supranationalworldmap.py
new file mode 100644
index 0000000..dd24c1d
--- /dev/null
+++ b/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 .
+"""
+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
diff --git a/pygal/i18n.py b/pygal/i18n.py
index 3b0b714..d97651f 100644
--- a/pygal/i18n.py
+++ b/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):
diff --git a/pygal/test/test_config.py b/pygal/test/test_config.py
index 1f688bf..a8b83df 100644
--- a/pygal/test/test_config.py
+++ b/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 .
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
diff --git a/pygal/test/test_graph.py b/pygal/test/test_graph.py
index aa2931f..77df284 100644
--- a/pygal/test/test_graph.py
+++ b/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'))
diff --git a/pygal/util.py b/pygal/util.py
index 0111cd2..8ab6958 100644
--- a/pygal/util.py
+++ b/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: