diff --git a/pygal/__init__.py b/pygal/__init__.py index f07cf30..b23431e 100644 --- a/pygal/__init__.py +++ b/pygal/__init__.py @@ -27,7 +27,6 @@ from pygal.graph.bar import Bar from pygal.graph.box import Box from pygal.graph.dot import Dot from pygal.graph.frenchmap import FrenchMapDepartments, FrenchMapRegions -from pygal.graph.swissmap import SwissMapCantons from pygal.graph.funnel import Funnel from pygal.graph.gauge import Gauge from pygal.graph.histogram import Histogram @@ -39,11 +38,11 @@ from pygal.graph.pyramid import Pyramid from pygal.graph.radar import Radar from pygal.graph.stackedbar import StackedBar from pygal.graph.stackedline import StackedLine -from pygal.graph.supranationalworldmap import SupranationalWorldmap +from pygal.graph.swissmap import SwissMapCantons from pygal.graph.time import DateLine, DateTimeLine, TimeLine, TimeDeltaLine from pygal.graph.treemap import Treemap from pygal.graph.verticalpyramid import VerticalPyramid -from pygal.graph.worldmap import Worldmap +from pygal.graph.worldmap import Worldmap, SupranationalWorldmap from pygal.graph.xy import XY from pygal.graph.graph import Graph from pygal.config import Config diff --git a/pygal/graph/base.py b/pygal/graph/base.py index 5850c45..9d81439 100644 --- a/pygal/graph/base.py +++ b/pygal/graph/base.py @@ -86,11 +86,10 @@ class BaseGraph(object): def prepare_values(self, raw, offset=0): """Prepare the values to start with sane values""" - from pygal import ( - Worldmap, FrenchMapDepartments, Histogram, SwissMapCantons) - # TODO: Generalize these conditions - if self.zero == 0 and isinstance( - self, (Worldmap, FrenchMapDepartments, SwissMapCantons)): + from pygal.graph.map import BaseMap + from pygal import Histogram + + if self.zero == 0 and isinstance(self, BaseMap): self.zero = 1 for key in ('x_labels', 'y_labels'): @@ -126,8 +125,7 @@ class BaseGraph(object): metadata = {} values = [] if isinstance(raw_values, dict): - if isinstance(self, ( - Worldmap, FrenchMapDepartments, SwissMapCantons)): + if isinstance(self, BaseMap): raw_values = list(raw_values.items()) else: value_list = [None] * width @@ -161,10 +159,7 @@ class BaseGraph(object): value = (value, self.zero) if x_adapter: value = (x_adapter(value[0]), adapter(value[1])) - if isinstance( - self, ( - Worldmap, FrenchMapDepartments, - SwissMapCantons)): + if isinstance(self, BaseMap): value = (adapter(value[0]), value[1]) else: value = list(map(adapter, value)) diff --git a/pygal/graph/ch.cantons.svg b/pygal/graph/ch.cantons.svg deleted file mode 100644 index 62ab954..0000000 --- a/pygal/graph/ch.cantons.svg +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygal/graph/fr.departments.svg b/pygal/graph/fr.departments.svg deleted file mode 100644 index 8b386f4..0000000 --- a/pygal/graph/fr.departments.svg +++ /dev/null @@ -1,328 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygal/graph/fr.regions.svg b/pygal/graph/fr.regions.svg deleted file mode 100644 index 1465de0..0000000 --- a/pygal/graph/fr.regions.svg +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygal/graph/frenchmap.py b/pygal/graph/frenchmap.py index f70a2d1..698857b 100644 --- a/pygal/graph/frenchmap.py +++ b/pygal/graph/frenchmap.py @@ -23,11 +23,8 @@ Worldmap chart from __future__ import division from collections import defaultdict -from pygal.util import cut, cached_property, decorate -from pygal.graph.graph import Graph +from pygal.graph.map import BaseMap from pygal._compat import u -from pygal.etree import etree -from numbers import Number import os @@ -177,102 +174,22 @@ with open(os.path.join( DPT_MAP = file.read() -with open(os.path.join( - os.path.dirname(__file__), - 'fr.regions.svg')) as file: - REG_MAP = file.read() - - -class FrenchMapDepartments(Graph): +class FrenchMapDepartments(BaseMap): """French department map""" - _dual = True x_labels = list(DEPARTMENTS.keys()) area_names = DEPARTMENTS area_prefix = 'z' kind = 'departement' svg_map = DPT_MAP - @cached_property - def _values(self): - """Getter for series values (flattened)""" - return [val[1] - for serie in self.series - for val in serie.values - if val[1] is not None] - - def _plot(self): - map = etree.fromstring(self.svg_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) - for j, (area_code, value) in enumerate(serie.values): - if isinstance(area_code, Number): - area_code = '%2d' % area_code - if value is None: - continue - if max_ == min_: - ratio = 1 - else: - ratio = .3 + .7 * (value - min_) / (max_ - min_) - try: - areae = map.findall( - ".//*[@class='%s%s %s map-element']" % ( - self.area_prefix, area_code, - self.kind)) - except SyntaxError: - # Python 2.6 (you'd better install lxml) - areae = [] - for g in map: - for e in g: - if '%s%s' % ( - self.area_prefix, area_code - ) in e.attrib.get('class', ''): - areae.append(e) - if not areae: - continue - - for area in areae: - cls = area.get('class', '').split(' ') - cls.append('color-%d' % i) - area.set('class', ' '.join(cls)) - area.set('style', 'fill-opacity: %f' % (ratio)) - - metadata = serie.metadata.get(j) - if metadata: - node = decorate(self.svg, area, metadata) - if node != area: - area.remove(node) - for g in map: - if area not in g: - continue - index = list(g).index(area) - g.remove(area) - node.append(area) - g.insert(index, node) - - last_node = len(area) > 0 and area[-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(area, 'title') - text = '' - title_node.text = text + '[%s] %s: %s' % ( - serie.title, - self.area_names[area_code], self._format(value)) - - self.nodes['plot'].append(map) +with open(os.path.join( + os.path.dirname(__file__), + 'fr.regions.svg')) as file: + REG_MAP = file.read() -class FrenchMapRegions(FrenchMapDepartments): +class FrenchMapRegions(BaseMap): """French regions map""" x_labels = list(REGIONS.keys()) area_names = REGIONS diff --git a/pygal/graph/map.py b/pygal/graph/map.py new file mode 100644 index 0000000..e8a41c7 --- /dev/null +++ b/pygal/graph/map.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +# This file is part of pygal +# +# A python svg graph plotting library +# Copyright © 2012-2014 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 . + +from __future__ import division +from pygal.graph.graph import Graph +from pygal.util import cut, cached_property, decorate +from pygal.etree import etree +from numbers import Number + + +class BaseMap(Graph): + """Base map.""" + _dual = True + + @cached_property + def _values(self): + """Getter for series values (flattened)""" + return [val[1] + for serie in self.series + for val in serie.values + if val[1] is not None] + + def get_values(self, serie): + return serie.values + + def _plot(self): + map = etree.fromstring(self.svg_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) + for j, (area_code, value) in enumerate(self.get_values(serie)): + # TODO: Generalize + if isinstance(area_code, Number): + area_code = '%2d' % area_code + + if value is None: + continue + if max_ == min_: + ratio = 1 + else: + ratio = .3 + .7 * (value - min_) / (max_ - min_) + try: + areae = map.findall( + ".//*[@class='%s%s %s map-element']" % ( + self.area_prefix, area_code, + self.kind)) + except SyntaxError: + # Python 2.6 (you'd better install lxml) + areae = [] + for g in map: + for e in g: + if '%s%s' % ( + self.area_prefix, area_code + ) in e.attrib.get('class', ''): + areae.append(e) + + if not areae: + continue + + for area in areae: + cls = area.get('class', '').split(' ') + cls.append('color-%d' % i) + area.set('class', ' '.join(cls)) + area.set('style', 'fill-opacity: %f' % (ratio)) + + metadata = serie.metadata.get(j) + if metadata: + node = decorate(self.svg, area, metadata) + if node != area: + area.remove(node) + for g in map: + if area not in g: + continue + index = list(g).index(area) + g.remove(area) + node.append(area) + g.insert(index, node) + + last_node = len(area) > 0 and area[-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(area, 'title') + text = '' + title_node.text = text + '[%s] %s: %s' % ( + serie.title, + self.area_names[area_code], self._format(value)) + + self.nodes['plot'].append(map) diff --git a/pygal/graph/supranationalworldmap.py b/pygal/graph/supranationalworldmap.py deleted file mode 100644 index bf45097..0000000 --- a/pygal/graph/supranationalworldmap.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -# This file is part of pygal -# -# A python svg graph plotting library -# Copyright © 2012-2014 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 pygal.etree 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_) - - try: - country = map.find('.//*[@id="%s"]' % country_code) - except SyntaxError: - # Python 2.6 (you'd better install lxml) - country = None - for e in map: - if e.attrib.get('id', '') == country_code: - country = e - - 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: - node = decorate(self.svg, country, metadata) - if node != country: - country.remove(node) - index = list(map).index(country) - map.remove(country) - node.append(country) - map.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/graph/swissmap.py b/pygal/graph/swissmap.py index 189a83b..1fe7efa 100644 --- a/pygal/graph/swissmap.py +++ b/pygal/graph/swissmap.py @@ -22,11 +22,8 @@ Worldmap chart """ from __future__ import division -from pygal.util import cut, cached_property, decorate -from pygal.graph.graph import Graph +from pygal.graph.map import BaseMap from pygal._compat import u -from pygal.etree import etree -from numbers import Number import os @@ -66,97 +63,10 @@ with open(os.path.join( CNT_MAP = file.read() -class SwissMapCantons(Graph): +class SwissMapCantons(BaseMap): """Swiss Cantons map""" - _dual = True x_labels = list(CANTONS.keys()) area_names = CANTONS area_prefix = 'z' kind = 'canton' svg_map = CNT_MAP - - @cached_property - def _values(self): - """Getter for series values (flattened)""" - return [val[1] - for serie in self.series - for val in serie.values - if val[1] is not None] - - def _plot(self): - map = etree.fromstring(self.svg_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) - for j, (area_code, value) in enumerate(serie.values): - if isinstance(area_code, Number): - area_code = '%2d' % area_code - if value is None: - continue - if max_ == min_: - ratio = 1 - else: - ratio = .3 + .7 * (value - min_) / (max_ - min_) - try: - areae = map.findall( - ".//*[@class='%s%s %s map-element']" % ( - self.area_prefix, area_code, - self.kind)) - except SyntaxError: - # Python 2.6 (you'd better install lxml) - areae = [] - for g in map: - for e in g: - if '%s%s' % ( - self.area_prefix, area_code - ) in e.attrib.get('class', ''): - areae.append(e) - - if not areae: - continue - for area in areae: - cls = area.get('class', '').split(' ') - cls.append('color-%d' % i) - area.set('class', ' '.join(cls)) - area.set('style', 'fill-opacity: %f' % (ratio)) - metadata = serie.metadata.get(j) - if metadata: - node = decorate(self.svg, area, metadata) - if node != area: - area.remove(node) - for g in map: - if area not in g: - continue - index = list(g).index(area) - g.remove(area) - node.append(area) - g.insert(index, node) - - last_node = len(area) > 0 and area[-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(area, 'title') - text = '' - title_node.text = text + '[%s] %s: %s' % ( - serie.title, - self.area_names[area_code], self._format(value)) - - self.nodes['plot'].append(map) - - -class SwissMapCantons(SwissMapCantons): - """French regions map""" - x_labels = list(CANTONS.keys()) - area_names = CANTONS - area_prefix = 'z' - svg_map = CNT_MAP - kind = 'canton' diff --git a/pygal/graph/worldmap.py b/pygal/graph/worldmap.py index 4fc5f77..fd4134f 100644 --- a/pygal/graph/worldmap.py +++ b/pygal/graph/worldmap.py @@ -23,22 +23,24 @@ Worldmap chart from __future__ import division from pygal.util import cut, cached_property, decorate -from pygal.graph.graph import Graph -from pygal.i18n import COUNTRIES +from pygal.graph.map import BaseMap +from pygal.i18n import COUNTRIES, SUPRANATIONAL from pygal.etree import etree import os with open(os.path.join( os.path.dirname(__file__), 'worldmap.svg')) as file: - MAP = file.read() + WORLD_MAP = file.read() -class Worldmap(Graph): +class Worldmap(BaseMap): """Worldmap graph""" - _dual = True x_labels = list(COUNTRIES.keys()) - country_names = COUNTRIES + area_names = COUNTRIES + area_prefix = '' + svg_map = WORLD_MAP + kind = 'country' @cached_property def countries(self): @@ -55,63 +57,19 @@ class Worldmap(Graph): for val in serie.values if val[1] is not None] - 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) - 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_) +class SupranationalWorldmap(Worldmap): + """SupranationalWorldmap graph""" - try: - country = map.find('.//*[@id="%s"]' % country_code) - except SyntaxError: - # Python 2.6 (you'd better install lxml) - country = None - for e in map: - if e.attrib.get('id', '') == country_code: - country = e + def get_values(self, serie): + return self.replace_supranationals(serie.values) - 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: - node = decorate(self.svg, country, metadata) - if node != country: - country.remove(node) - index = list(map).index(country) - map.remove(country) - node.append(country) - map.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: %s' % ( - serie.title, - self.country_names[country_code], self._format(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/graph/worldmap.svg b/pygal/graph/worldmap.svg deleted file mode 100644 index 0adfc9b..0000000 --- a/pygal/graph/worldmap.svg +++ /dev/null @@ -1,2408 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygal/test/__init__.py b/pygal/test/__init__.py index d4de7ac..8a576d4 100644 --- a/pygal/test/__init__.py +++ b/pygal/test/__init__.py @@ -20,9 +20,10 @@ import pygal from pygal.util import cut from pygal.i18n import COUNTRIES -from pygal.graph.frenchmap import DEPARTMENTS, REGIONS +from pygal.graph.map import BaseMap from decimal import Decimal + def get_data(i): return [ [(-1, 1), (2, 0), (0, 4)], @@ -38,29 +39,16 @@ def adapt(chart, data): # return list(map( # lambda t: # (datetime.fromtimestamp(1360000000 + t[0] * 987654) - # if t[0] is not None else None, t[1]), data)) + # if t[0] is not None else None, t[1]), data)) if isinstance(chart, pygal.XY): return data data = cut(data) - if isinstance(chart, pygal.Worldmap): - return list( - map(lambda x: list( - COUNTRIES.keys())[ - int(x) % len(COUNTRIES)] - if x is not None else None, data)) - elif isinstance(chart, pygal.FrenchMapRegions): - return list( - map(lambda x: list( - REGIONS.keys())[ - int(x) % len(REGIONS)] - if x is not None else None, data)) - elif isinstance(chart, pygal.FrenchMapDepartments): + if isinstance(chart, BaseMap): return list( - map(lambda x: list( - DEPARTMENTS.keys())[ - int(x) % len(DEPARTMENTS)] + map(lambda x: chart.__class__.x_labels[ + int(x) % len(chart.__class__.x_labels)] if x is not None else None, data)) return data diff --git a/pygal/test/test_graph.py b/pygal/test/test_graph.py index 268b187..713c00e 100644 --- a/pygal/test/test_graph.py +++ b/pygal/test/test_graph.py @@ -23,8 +23,7 @@ import uuid import sys import pytest from pygal import i18n -from pygal.graph.frenchmap import DEPARTMENTS, REGIONS -from pygal.graph.swissmap import CANTONS +from pygal.graph.map import BaseMap from pygal.util import cut from pygal._compat import u from pygal.test import make_data @@ -81,14 +80,8 @@ def test_metadata(Chart): return # summary charts cannot display per-value metadata elif Chart == pygal.XY: v = list(map(lambda x: (x, x + 1), v)) - elif Chart == pygal.Worldmap or Chart == pygal.SupranationalWorldmap: - v = [(i, k) for k, i in enumerate(i18n.COUNTRIES.keys())] - elif Chart == pygal.FrenchMapRegions: - v = [(i, k) for k, i in enumerate(REGIONS.keys())] - elif Chart == pygal.FrenchMapDepartments: - v = [(i, k) for k, i in enumerate(DEPARTMENTS.keys())] - elif Chart == pygal.SwissMapCantons: - v = [(i, k) for k, i in enumerate(CANTONS.keys())] + elif issubclass(Chart, BaseMap): + v = [(i, k) for k, i in enumerate(Chart.x_labels)] chart.add('Serie with metadata', [ v[0], @@ -111,10 +104,7 @@ def test_metadata(Chart): if Chart in (pygal.Pie, pygal.Treemap): # Slices with value 0 are not rendered assert len(v) - 1 == len(q('.tooltip-trigger').siblings('.value')) - elif Chart not in ( - pygal.Worldmap, pygal.SupranationalWorldmap, - pygal.FrenchMapRegions, pygal.FrenchMapDepartments, - pygal.SwissMapCantons): + elif not issubclass(Chart, BaseMap): # Tooltip are not working on maps assert len(v) == len(q('.tooltip-trigger').siblings('.value')) @@ -195,12 +185,7 @@ def test_values_by_dict(Chart): chart1 = Chart(no_prefix=True) chart2 = Chart(no_prefix=True) - if not issubclass(Chart, ( - pygal.Worldmap, - pygal.FrenchMapDepartments, - pygal.FrenchMapRegions, - pygal.SwissMapCantons)): - + if not issubclass(Chart, BaseMap): chart1.add('A', {'red': 10, 'green': 12, 'blue': 14}) chart1.add('B', {'green': 11, 'red': 7}) chart1.add('C', {'blue': 7}) @@ -383,10 +368,7 @@ def test_labels_with_links(Chart): q = chart.render_pyquery() links = q('a') - if isinstance(chart, - (pygal.graph.worldmap.Worldmap, - pygal.graph.frenchmap.FrenchMapDepartments, - pygal.graph.swissmap.SwissMapCantons)): + if isinstance(chart, BaseMap): # No country is found in this case so: assert len(links) == 4 # 3 links and 1 tooltip else: diff --git a/pygal/test/test_map.py b/pygal/test/test_map.py index 62feee1..6aae667 100644 --- a/pygal/test/test_map.py +++ b/pygal/test/test_map.py @@ -41,7 +41,7 @@ def test_worldmap(): assert len( q('.country.color-0') ) == len(COUNTRIES) - assert 'France' in q('#fr').text() + assert 'France' in q('.country.fr').text() def test_worldmap_i18n(): @@ -57,7 +57,7 @@ def test_worldmap_i18n(): assert len( q('.country.color-0') ) == len(COUNTRIES) - assert 'Francia' in q('#fr').text() + assert 'Francia' in q('.country.fr').text() def test_worldmap_i18n_clear(): @@ -69,7 +69,7 @@ def test_worldmap_i18n_clear(): assert len( q('.country.color-0') ) == 1 - assert 'Frankreich' in q('#fr').text() + assert 'Frankreich' in q('.country.fr').text() def test_supranationalworldmap(): diff --git a/setup.py b/setup.py index 76b7ca9..6aab2bd 100644 --- a/setup.py +++ b/setup.py @@ -64,7 +64,7 @@ setup( "svg", "chart", "graph", "diagram", "plot", "histogram", "kiviat"], tests_require=["pytest", "pyquery", "flask", "cairosvg"], cmdclass={'test': PyTest}, - package_data={'pygal': ['css/*', 'graph/*.svg']}, + package_data={'pygal': ['css/*', 'graph/maps/*.svg']}, extras_require={ 'lxml': ['lxml'], 'png': ['cairosvg']