Skip to content

Commit 7abde84

Browse files
authored
Merge pull request #12 from highcharts-for-python/develop
PR for v.1.0.0-rc3
2 parents 128e9fd + 1f0ab92 commit 7abde84

File tree

9 files changed

+84
-51
lines changed

9 files changed

+84
-51
lines changed

CHANGES.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
Release 1.0.0-rc3
2+
=========================================
3+
4+
* Fixed unneeded ``python-dotenv`` dependency.
5+
* Fixed JSON deserialization in ``.from_array()``.
6+
* Added ``options.chart.ChartOptions.is_async`` property.
7+
* Updated ``utility_classes.fetch_configuration.FetchConfiguration``
8+
serialization to handle quote escaping.
9+
* Fixed JS literal synchronization when ``options.chart.map`` is asynchronous.
10+
11+
--------------
12+
113
Release 1.0.0-rc2
214
=========================================
315

highcharts_maps/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.0.0-rc2'
1+
__version__ = '1.0.0-rc3'

highcharts_maps/chart.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from highcharts_core.chart import Chart as ChartBase
66

7-
from highcharts_maps import constants, errors
7+
from highcharts_maps import constants, errors, utility_functions
88
from highcharts_maps.options import HighchartsOptions, HighchartsMapsOptions
99
from highcharts_maps.decorators import validate_types
1010
from highcharts_maps.js_literal_functions import serialize_to_js_literal
@@ -218,6 +218,14 @@ def to_js_literal(self,
218218
if self.is_async:
219219
urls = []
220220
topologies = []
221+
if self.options.chart and self.options.chart.map:
222+
url = self.options.chart.map.url
223+
urls.append(url)
224+
self.options.chart.map.fetch_counter = 1
225+
226+
map_data_as_str = self.options.chart.map.to_js_literal(encoding = encoding)
227+
topologies.append(map_data_as_str)
228+
221229
for index, series in enumerate(self.options.series):
222230
if series.is_async:
223231
url = series.map_data.url
@@ -229,10 +237,7 @@ def to_js_literal(self,
229237
map_data_as_str = series.map_data.to_js_literal(encoding = encoding)
230238
topologies.append(map_data_as_str)
231239

232-
fetch_as_str = ''
233-
for topology in topologies:
234-
fetch_request = topology.to_js_literal(encoding = encoding)
235-
fetch_as_str += f"""{fetch_request}\n"""
240+
fetch_as_str = '\n'.join(topologies)
236241

237242
custom_projection_as_str = ''
238243
if self.uses_custom_projection:
@@ -249,6 +254,11 @@ def to_js_literal(self,
249254
options_as_str = ''
250255
if self.options:
251256
options_as_str = self.options.to_js_literal(encoding = encoding)
257+
if self.options.chart and self.options.chart.map and self.options.chart.is_async:
258+
chart_map_str = self.options.chart.map.to_js_literal(encoding = encoding)
259+
chart_map_str = f"""'{chart_map_str}'"""
260+
fetch_counter = self.options.chart.map.fetch_counter
261+
options_as_str = options_as_str.replace(chart_map_str, f'topology{fetch_counter}')
252262
options_as_str = f"""{options_as_str}"""
253263
else:
254264
options_as_str = """{}"""
@@ -285,7 +295,7 @@ def to_js_literal(self,
285295
prefix = """document.addEventListener('DOMContentLoaded', function() {\n"""
286296
if custom_projection_as_str:
287297
prefix += custom_projection_as_str
288-
prefix += """(async () => """
298+
prefix += """(async () => { """
289299
suffix = """})()});"""
290300
as_str = fetch_as_str + '\n' + as_str
291301
else:
@@ -1043,6 +1053,9 @@ def is_async(self) -> bool:
10431053
if not self.options or not self.options.series:
10441054
return False
10451055

1056+
if self.options.chart and self.options.chart.is_async:
1057+
return True
1058+
10461059
for series in self.options.series:
10471060
if hasattr(series, 'is_async') and series.is_async:
10481061
return True

highcharts_maps/constants.py

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,10 @@
22
from highcharts_core.constants import *
33

44

5-
MAPS_INCLUDE_LIBS = [
6-
'https://code.highcharts.com/highcharts.js',
7-
'https://code.highcharts.com/highcharts-more.js',
8-
'https://code.highcharts.com/highcharts-3d.js',
9-
'https://code.highcharts.com/maps/modules/map.js',
10-
'https://code.highcharts.com/modules/accessibility.js',
11-
'https://code.highcharts.com/modules/annotations.js',
12-
'https://code.highcharts.com/modules/boost.js',
13-
'https://code.highcharts.com/modules/broken-axis.js',
14-
'https://code.highcharts.com/modules/data.js',
15-
'https://code.highcharts.com/modules/exporting.js',
16-
'https://code.highcharts.com/modules/drilldown.js',
17-
'https://code.highcharts.com/modules/funnel.js',
18-
'https://code.highcharts.com/modules/heatmap.js',
19-
'https://code.highcharts.com/modules/no-data-to-display.js',
20-
'https://code.highcharts.com/modules/offline-exporting.js',
21-
'https://code.highcharts.com/modules/solid-gauge.js',
22-
'https://code.highcharts.com/modules/series-label.js',
23-
'https://code.highcharts.com/modules/treemap.js'
5+
MAPS_INCLUDE_LIBS = INCLUDE_LIBS + [
6+
'https://code.highcharts.com/maps/modules/map.js'
247
]
258

26-
MAPS_INCLUDE_STR = """<script src="https://code.highcharts.com/highcharts.js"/>
27-
<script src="https://code.highcharts.com/highcharts-more.js"/>
28-
<script src="https://code.highcharts.com/highcharts-3d.js"/>
29-
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
30-
<script src="https://code.highcharts.com/modules/accessibility.js"/>
31-
<script src="https://code.highcharts.com/modules/annotations.js"/>
32-
<script src="https://code.highcharts.com/modules/boost.js"/>
33-
<script src="https://code.highcharts.com/modules/broken-axis.js"/>
34-
<script src="https://code.highcharts.com/modules/data.js"/>
35-
<script src="https://code.highcharts.com/modules/exporting.js"/>
36-
<script src="https://code.highcharts.com/modules/drilldown.js"/>
37-
<script src="https://code.highcharts.com/modules/funnel.js"/>
38-
<script src="https://code.highcharts.com/modules/heatmap.js"/>
39-
<script src="https://code.highcharts.com/modules/no-data-to-display.js"/>
40-
<script src="https://code.highcharts.com/modules/offline-exporting.js"/>
41-
<script src="https://code.highcharts.com/modules/solid-gauge.js"/>
42-
<script src="https://code.highcharts.com/modules/treemap.js"/>
43-
<script src="https://code.highcharts.com/modules/series-label.js"/>
44-
"""
9+
MAPS_INCLUDE_STR = INCLUDE_STR + """
10+
<script src="https://code.highcharts.com/maps/modules/map.js"/>
11+
"""

highcharts_maps/headless_export.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
from dotenv import load_dotenv
1+
try:
2+
from dotenv import load_dotenv
3+
load_dotenv()
4+
except ImportError:
5+
pass
6+
27
from typing import Optional
38

49
from validator_collection import checkers
@@ -9,8 +14,6 @@
914
from highcharts_maps.options import HighchartsOptions, HighchartsMapsOptions
1015
from highcharts_maps.global_options.shared_options import SharedOptions, SharedMapsOptions
1116

12-
load_dotenv()
13-
1417

1518
class ExportServer(ExportServerBase):
1619
"""Class that provides methods for interacting with the Highcharts

highcharts_maps/options/chart/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,26 @@ def _to_untrimmed_dict(self, in_cls = None) -> dict:
231231
untrimmed[key] = parent_as_dict[key]
232232

233233
return untrimmed
234+
235+
@property
236+
def is_async(self) -> bool:
237+
"""Read-only property which indicates whether the data visualization should be
238+
rendered using asynchronous logic.
239+
240+
.. note::
241+
242+
This property will only return ``True`` if one or more series rely on
243+
:class:`AsyncMapData <highcharts_maps.options.series.data.map_data.AsyncMapData>`
244+
245+
:rtype: :class:`bool <python:bool>`
246+
"""
247+
if checkers.is_iterable(self.map):
248+
for item in self.map:
249+
if isinstance(item, (AsyncMapData)):
250+
return True
251+
return False
252+
253+
if isinstance(self.map, AsyncMapData):
254+
return True
255+
256+
return False

highcharts_maps/options/series/data/geometric.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ def value(self, value_):
225225
def from_array(cls, value):
226226
if not value:
227227
return []
228+
elif checkers.is_string(value):
229+
try:
230+
value = validators.json(value)
231+
except (ValueError, TypeError):
232+
pass
228233
elif not checkers.is_iterable(value):
229234
value = [value]
230235

@@ -343,6 +348,11 @@ def z(self, value):
343348
def from_array(cls, value):
344349
if not value:
345350
return []
351+
elif checkers.is_string(value):
352+
try:
353+
value = validators.json(value)
354+
except (ValueError, TypeError):
355+
pass
346356
elif not checkers.is_iterable(value):
347357
value = [value]
348358

@@ -521,6 +531,11 @@ def y(self, value):
521531
def from_array(cls, value):
522532
if not value:
523533
return []
534+
elif checkers.is_string(value):
535+
try:
536+
value = validators.json(value)
537+
except (ValueError, TypeError):
538+
pass
524539
elif not checkers.is_iterable(value):
525540
value = [value]
526541

highcharts_maps/options/series/data/map_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ def to_js_literal(self,
678678
fetch_config = self.fetch_config
679679
else:
680680
fetch_config = FetchConfiguration(self.url)
681-
681+
682682
if self.selector:
683683
function = f"""const selector = {str(self.selector)};\n"""
684684
fetch = f"""const topology = await {str(fetch_config)}.then(response => selector(response.json()));"""

highcharts_maps/utility_classes/fetch_configuration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ def __str__(self):
5050
options_as_str = json.dumps(trimmed_options)
5151

5252
if not options_as_str:
53-
as_str = f"""fetch('{self.url}')"""
53+
as_str = f"""fetch("{self.url}")"""
5454
else:
55-
as_str = f"""fetch('{self.url}', options = {options_as_str})"""
55+
as_str = f"""fetch("{self.url}", options = {options_as_str})"""
5656

5757
return as_str
5858

0 commit comments

Comments
 (0)