Skip to content

Commit 2fa6fdf

Browse files
authored
Merge pull request #26 from highcharts-for-python/develop
PR for v.1.0.0-rc5
2 parents a7f7a18 + 856080d commit 2fa6fdf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+405
-72
lines changed

CHANGES.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
Release 1.0.0-rc5
2+
=========================================
3+
4+
* Bug fixes to Jupyter Labs rendering.
5+
* Bug fix for timestamp serialization of timezone-naive ``datetime`` objects.
6+
* Bug fix: typo in Plot Bands serialization.
7+
* Added null support to color validation.
8+
* Bug fix in ``style`` deserialization.
9+
* Bug fix in ``CartesianData.from_array()``.
10+
* Fixed ``NaN`` handling in ``.load_from_pandas()``.
11+
* Fixed JSON deserialization in ``.from_array()``.
12+
* Added support for stylesheet links in Jupyter Labs context.
13+
* Several bug fixes in JS literal serialization.
14+
* Major improvements to JavaScript module inclusion.
15+
16+
---------------
17+
118
Release 1.0.0-rc4
219
=========================================
320

highcharts_core/__version__.py

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

highcharts_core/constants.py

Lines changed: 91 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,37 +31,108 @@ def __eq__(self, other):
3131
'https://code.highcharts.com/highcharts-3d.js',
3232
'https://code.highcharts.com/modules/accessibility.js',
3333
'https://code.highcharts.com/modules/annotations.js',
34+
'https://code.highcharts.com/modules/annotations-advanced.js',
35+
'https://code.highcharts.com/modules/sankey.js',
36+
'https://code.highcharts.com/modules/arc-diagram.js',
3437
'https://code.highcharts.com/modules/boost.js',
3538
'https://code.highcharts.com/modules/broken-axis.js',
39+
'https://code.highcharts.com/modules/bullet.js',
40+
'https://code.highcharts.com/modules/cylinder.js',
3641
'https://code.highcharts.com/modules/data.js',
37-
'https://code.highcharts.com/modules/exporting.js',
42+
'https://code.highcharts.com/modules/datagrouping.js',
43+
'https://code.highcharts.com/modules/debugger.js',
44+
'https://code.highcharts.com/modules/dependency-wheel.js',
45+
'https://code.highcharts.com/modules/drag-panes.js',
46+
'https://code.highcharts.com/modules/draggable-points.js',
3847
'https://code.highcharts.com/modules/drilldown.js',
48+
'https://code.highcharts.com/modules/dumbbell.js',
49+
'https://code.highcharts.com/modules/export-data.js',
50+
'https://code.highcharts.com/modules/exporting.js',
3951
'https://code.highcharts.com/modules/funnel.js',
52+
'https://code.highcharts.com/modules/funnel3d.js',
4053
'https://code.highcharts.com/modules/heatmap.js',
54+
'https://code.highcharts.com/modules/item-series.js',
55+
'https://code.highcharts.com/modules/lollipop.js',
56+
'https://code.highcharts.com/modules/networkgraph.js',
4157
'https://code.highcharts.com/modules/no-data-to-display.js',
4258
'https://code.highcharts.com/modules/offline-exporting.js',
43-
'https://code.highcharts.com/modules/solid-gauge.js',
59+
'https://code.highcharts.com/modules/oldie.js',
60+
'https://code.highcharts.com/modules/organization.js',
61+
'https://code.highcharts.com/modules/parallel-coordinates.js',
62+
'https://code.highcharts.com/modules/pareto.js',
63+
'https://code.highcharts.com/modules/pyramid3d.js',
4464
'https://code.highcharts.com/modules/series-label.js',
45-
'https://code.highcharts.com/modules/treemap.js'
65+
'https://code.highcharts.com/modules/series-on-point.js',
66+
'https://code.highcharts.com/modules/solid-gauge.js',
67+
'https://code.highcharts.com/modules/streamgraph.js',
68+
'https://code.highcharts.com/modules/sunburst.js',
69+
'https://code.highcharts.com/modules/tilemap.js',
70+
'https://code.highcharts.com/modules/timeline.js',
71+
'https://code.highcharts.com/modules/treegraph.js',
72+
'https://code.highcharts.com/modules/treemap.js',
73+
'https://code.highcharts.com/modules/variable-pie.js',
74+
'https://code.highcharts.com/modules/variwide.js',
75+
'https://code.highcharts.com/modules/vector.js',
76+
'https://code.highcharts.com/modules/venn.js',
77+
'https://code.highcharts.com/modules/windbarb.js',
78+
'https://code.highcharts.com/modules/wordcloud.js',
79+
'https://code.highcharts.com/modules/xrange.js',
4680
]
4781

48-
INCLUDE_STR = """<script src="https://code.highcharts.com/highcharts.js"/>
49-
<script src="https://code.highcharts.com/highcharts-more.js"/>
50-
<script src="https://code.highcharts.com/highcharts-3d.js"/>
51-
<script src="https://code.highcharts.com/modules/accessibility.js"/>
52-
<script src="https://code.highcharts.com/modules/annotations.js"/>
53-
<script src="https://code.highcharts.com/modules/boost.js"/>
54-
<script src="https://code.highcharts.com/modules/broken-axis.js"/>
55-
<script src="https://code.highcharts.com/modules/data.js"/>
56-
<script src="https://code.highcharts.com/modules/exporting.js"/>
57-
<script src="https://code.highcharts.com/modules/drilldown.js"/>
58-
<script src="https://code.highcharts.com/modules/funnel.js"/>
59-
<script src="https://code.highcharts.com/modules/heatmap.js"/>
60-
<script src="https://code.highcharts.com/modules/no-data-to-display.js"/>
61-
<script src="https://code.highcharts.com/modules/offline-exporting.js"/>
62-
<script src="https://code.highcharts.com/modules/solid-gauge.js"/>
63-
<script src="https://code.highcharts.com/modules/treemap.js"/>
64-
<script src="https://code.highcharts.com/modules/series-label.js"/>
82+
INCLUDE_STR = """
83+
<script src="https://code.highcharts.com/highcharts.js"/>
84+
<script src="https://code.highcharts.com/highcharts-more.js"/>
85+
<script src="https://code.highcharts.com/highcharts-3d.js"/>
86+
<script src="https://code.highcharts.com/modules/accessibility.js"/>
87+
<script src="https://code.highcharts.com/modules/annotations.js"/>
88+
<script src="https://code.highcharts.com/modules/annotations-advanced.js"/>
89+
<script src="https://code.highcharts.com/modules/arc-diagram.js"/>
90+
<script src="https://code.highcharts.com/modules/bellcurve.js"/>
91+
<script src="https://code.highcharts.com/modules/boost.js"/>
92+
<script src="https://code.highcharts.com/modules/broken-axis.js"/>
93+
<script src="https://code.highcharts.com/modules/bullet.js"/>
94+
<script src="https://code.highcharts.com/modules/cylinder.js"/>
95+
<script src="https://code.highcharts.com/modules/data.js"/>
96+
<script src="https://code.highcharts.com/modules/datagrouping.js"/>
97+
<script src="https://code.highcharts.com/modules/debugger.js"/>
98+
<script src="https://code.highcharts.com/modules/dependency-wheel.js"/>
99+
<script src="https://code.highcharts.com/modules/drag-panes'
100+
<script src="https://code.highcharts.com/modules/draggable-points.js"/>
101+
<script src="https://code.highcharts.com/modules/drilldown.js"/>
102+
<script src="https://code.highcharts.com/modules/dumbbell.js"/>
103+
<script src="https://code.highcharts.com/modules/export-data.js"/>
104+
<script src="https://code.highcharts.com/modules/exporting.js"/>
105+
<script src="https://code.highcharts.com/modules/full-screen.js"/>
106+
<script src="https://code.highcharts.com/modules/funnel.js"/>
107+
<script src="https://code.highcharts.com/modules/funnel3d.js"/>
108+
<script src="https://code.highcharts.com/modules/histogram.js"/>
109+
<script src="https://code.highcharts.com/modules/item-series.js"/>
110+
<script src="https://code.highcharts.com/modules/lollipop.js"/>
111+
<script src="https://code.highcharts.com/modules/networkgraph.js"/>
112+
<script src="https://code.highcharts.com/modules/no-data-to-display.js"/>
113+
<script src="https://code.highcharts.com/modules/offline-exporting.js"/>
114+
<script src="https://code.highcharts.com/modules/oldie.js"/>
115+
<script src="https://code.highcharts.com/modules/organization.js"/>
116+
<script src="https://code.highcharts.com/modules/parallel-coordinates.js"/>
117+
<script src="https://code.highcharts.com/modules/pareto.js"/>
118+
<script src="https://code.highcharts.com/modules/pyramid3d.js"/>
119+
<script src="https://code.highcharts.com/modules/sankey.js"/>
120+
<script src="https://code.highcharts.com/modules/series-label.js"/>
121+
<script src="https://code.highcharts.com/modules/series-on-point.js"/>
122+
<script src="https://code.highcharts.com/modules/solid-gauge.js"/>
123+
<script src="https://code.highcharts.com/modules/streamgraph.js"/>
124+
<script src="https://code.highcharts.com/modules/sunburst.js"/>
125+
<script src="https://code.highcharts.com/modules/tilemap.js"/>
126+
<script src="https://code.highcharts.com/modules/timeline.js"/>
127+
<script src="https://code.highcharts.com/modules/treegraph.js"/>
128+
<script src="https://code.highcharts.com/modules/treemap.js"/>
129+
<script src="https://code.highcharts.com/modules/variable-pie.js"/>
130+
<script src="https://code.highcharts.com/modules/variwide.js"/>
131+
<script src="https://code.highcharts.com/modules/vector.js"/>
132+
<script src="https://code.highcharts.com/modules/venn.js"/>
133+
<script src="https://code.highcharts.com/modules/windbarb.js"/>
134+
<script src="https://code.highcharts.com/modules/wordcloud.js"/>
135+
<script src="https://code.highcharts.com/modules/xrange.js"/>
65136
"""
66137

67138
AXIS_TYPES = [

highcharts_core/global_options/language/navigation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,7 @@ def style(self) -> Optional[str]:
12451245

12461246
@style.setter
12471247
def style(self, value):
1248-
self._style = validators.string(value, allow_empty = True)
1248+
self._style = validators.string(value, allow_empty = True, coerce_value = True)
12491249

12501250
@property
12511251
def time_cycles(self) -> Optional[str]:

highcharts_core/js_literal_functions.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ def serialize_to_js_literal(item, encoding = 'utf-8') -> Optional[str]:
3333
elif isinstance(item, bool):
3434
return item
3535
elif checkers.is_string(item):
36-
return item
36+
return_value = item.replace("'", "\\'")
37+
return return_value
3738
elif checkers.is_numeric(item) and not isinstance(item, Decimal):
3839
return item
3940
elif isinstance(item, Decimal):
@@ -46,6 +47,8 @@ def serialize_to_js_literal(item, encoding = 'utf-8') -> Optional[str]:
4647
as_dict[key] = serialize_to_js_literal(item[key], encoding = encoding)
4748
return str(as_dict)
4849
elif checkers.is_datetime(item):
50+
if not item.tzinfo:
51+
item = item.replace(tzinfo = datetime.timezone.utc)
4952
return item.timestamp()
5053
elif checkers.is_date(item):
5154
return f'Date.UTC({item.year}, {item.month - 1}, {item.day})'
@@ -57,6 +60,41 @@ def serialize_to_js_literal(item, encoding = 'utf-8') -> Optional[str]:
5760
return None
5861

5962

63+
def is_js_object(as_str):
64+
"""Determine whether ``as_str`` is a JavaScript object.
65+
66+
:param as_str: The string to evaluate.
67+
:type as_str: :class:`str <python:str>`
68+
69+
:returns: ``True`` if ``as_str`` is a JavaScript function. ``False`` if not.
70+
:rtype: :class:`bool <python:bool>`
71+
"""
72+
expression_item = f'const testName = {as_str}'
73+
try:
74+
parsed = esprima.parseScript(expression_item)
75+
except ParseError:
76+
try:
77+
parsed = esprima.parseModule(expression_item)
78+
except ParseError:
79+
return False
80+
81+
body = parsed.body
82+
if not body:
83+
return False
84+
85+
first_item = body[0]
86+
if first_item.type != 'VariableDeclaration':
87+
return False
88+
89+
init = first_item.declarations[0].init
90+
if not init:
91+
return False
92+
if init.type in ('ObjectExpression'):
93+
return True
94+
95+
return False
96+
97+
6098
def attempt_variable_declaration(as_str):
6199
"""Attempt to coerce ``as_str`` to a JavaScript variable declaration form.
62100
@@ -160,13 +198,21 @@ def get_js_literal(item) -> str:
160198
subitem_counter = 0
161199
for subitem in subitems:
162200
subitem_counter += 1
201+
if subitem == 'None':
202+
subitem = 'null'
163203
as_str += f"""{subitem}"""
164204
if subitem_counter < len(subitems):
165205
as_str += ',\n'
166206
as_str += ']'
167207
elif checkers.is_string(item):
168-
if item.startswith('{') or item.startswith('[') or item.startswith('Date'):
208+
if item.startswith('[') or item.startswith('Date'):
169209
as_str += f"""{item}"""
210+
elif item.startswith('{') and item.endswith('}'):
211+
if is_js_object(item):
212+
as_str += f"""{item}"""
213+
elif "'" in item:
214+
item = item.replace("'", "\\'")
215+
as_str += f'"{item}"'
170216
elif item in string.whitespace:
171217
as_str += f"""`{item}`"""
172218
elif item.startswith == 'HCP: REPLACE-WITH-':

highcharts_core/options/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@ def __init__(self, **kwargs):
8484
self.navigation = kwargs.get('navigation', None)
8585
self.plot_options = kwargs.get('plot_options', None)
8686
self.responsive = kwargs.get('responsive', None)
87-
self.series = kwargs.get('series', None)
8887
self.subtitle = kwargs.get('subtitle', None)
8988
self.time = kwargs.get('time', None)
9089
self.title = kwargs.get('title', None)
9190
self.tooltip = kwargs.get('tooltip', None)
9291
self.x_axis = kwargs.get('x_axis', None)
9392
self.y_axis = kwargs.get('y_axis', None)
9493

94+
self.series = kwargs.get('series', None)
9595
@property
9696
def accessibility(self) -> Optional[Accessibility]:
9797
"""Options for configuring accessibility for the chart.

highcharts_core/options/annotations/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ def draggable(self, value):
128128
if value is None:
129129
self._draggable = None
130130
else:
131-
value = validators.string(value, allow_empty = True)
131+
value = validators.string(value, allow_empty = True) or ''
132132
value = value.lower()
133-
if value not in ['x', 'xy', 'y']:
133+
if value not in ['x', 'xy', 'y', '']:
134134
raise errors.HighchartsValueError(f'draggable must be "x", "xy", "y", '
135135
f'or "". Was: {value}')
136136
self._draggable = value

highcharts_core/options/annotations/label_options.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ def style(self) -> Optional[str]:
449449

450450
@style.setter
451451
def style(self, value):
452-
self._style = validators.string(value, allow_empty = True)
452+
self._style = validators.string(value, allow_empty = True, coerce_value = True)
453453

454454
@property
455455
def text(self) -> Optional[str]:

highcharts_core/options/axes/labels.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,9 @@ def style(self) -> Optional[str]:
441441

442442
@style.setter
443443
def style(self, value):
444-
self._style = validators.string(value, allow_empty = True)
444+
self._style = validators.string(value,
445+
allow_empty = True,
446+
coerce_value = True)
445447

446448
@property
447449
def use_html(self) -> Optional[bool]:
@@ -632,7 +634,9 @@ def style(self) -> Optional[str]:
632634

633635
@style.setter
634636
def style(self, value):
635-
self._style = validators.string(value, allow_empty = True)
637+
self._style = validators.string(value,
638+
allow_empty = True,
639+
coerce_value = True)
636640

637641
@property
638642
def text(self) -> Optional[str]:

highcharts_core/options/axes/numeric.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def categories(self, value):
171171
if not value:
172172
self._categories = None
173173
else:
174-
self._categories = [validators.string(x) for x in validators.iterable(value)]
174+
self._categories = [validators.string(x, allow_empty = True) or '' for x in validators.iterable(value)]
175175

176176
@property
177177
def date_time_label_formats(self) -> Optional[DateTimeLabelFormats]:
@@ -541,7 +541,7 @@ def _to_untrimmed_dict(self, in_cls = None) -> dict:
541541
'opposite': self.opposite,
542542
'pane': self.pane,
543543
'panningEnabled': self.panning_enabled,
544-
'plotPands': self.plot_bands,
544+
'plotBands': self.plot_bands,
545545
'plotLines': self.plot_lines,
546546
'reversed': self.reversed,
547547
'reversedStacks': self.reversed_stacks,

0 commit comments

Comments
 (0)