Skip to content

Commit 58a9bff

Browse files
authored
Merge pull request #28 from highcharts-for-python/develop
PR for v.1.3.0
2 parents 533cd78 + c6694d0 commit 58a9bff

Some content is hidden

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

45 files changed

+277
-161
lines changed

CHANGES.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
Release 1.3.0
2+
=========================================
3+
4+
* **ENHANCEMENT:** Modified the way that data points are serialized to JavaScript literal objects. Now, they are serialized to a JavaScript array if their configured properties are those that Highcharts (JS) supports in JavaScript array notation. Otherwise, the code falls back to serialize the data point as a JavaScript object literal. This change is intended to improve performance and reduce the size of the serialized data. (#27)
5+
* **ENHANCEMENT:** Added ``__repr__()`` method for Highcharts Core for Python classes.
6+
* **ENHANCEMENT:** Added ``__str__()`` method with special handling for difficult-to-read classes.
7+
* **ENHANCEMENT:** Added ``Chart.get_script_tags()`` to retrieve Javascript ``<script>`` tags.
8+
* **ENHANCEMENT:** Added ``utility_functions.to_snake_case()`` function.
9+
* **BUGFIX:** Fixed incorrect serialization of datetime and Pandas ``Timestamp`` objects in ``.to_dict()`` and ``.to_json()``.
10+
* **BUGFIX:** Fixed incorrect serialization of ``EnforcedNull`` in ``.to_dict()`` and ``.to_json()``.
11+
12+
-------------------
13+
114
Release 1.2.1
215
=========================================
316

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Before you install, please be aware of the following "hard" dependencies:
8080
* Python 3.10 or higher
8181
* Highcharts Stock (JS) v.10.2 or higher (not technically a Python dependency, but
8282
it won't work with earlier versions of Highcharts Stock)
83-
* `Highcharts Core for Python <https://core-docs.highchartspython.com/en/latest/>`__ v.1.0 or higher
83+
* `Highcharts Core for Python <https://core-docs.highchartspython.com/en/latest/>`__ v.1.3 or higher
8484
* `esprima-python <https://github.com/Kronuz/esprima-python>`__ v.4.0 or higher
8585
* `requests <https://requests.readthedocs.io/en/latest/>`__ v.2.31 or higher
8686
* `validator-collection <https://validator-collection.readthedocs.io/en/latest/>`__

docs/_dependencies.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
Not technically a Python dependency, but obviously **Highcharts Stock for Python**
3333
will not work properly if your rendering layer does not leverage Highcharts Stock.
3434

35-
* `highcharts-core <https://core-docs.highchartspython.com>`_ v.1.0.0 or higher
35+
* `highcharts-core <https://core-docs.highchartspython.com>`_ v.1.3.0 or higher
3636
* `esprima-python <https://github.com/Kronuz/esprima-python>`_ v.4.0 or higher
3737
* `requests <https://requests.readthedocs.io/en/latest/>`_ v.2.31 or higher
3838
* `validator-collection <https://validator-collection.readthedocs.io/en/latest/>`_

highcharts_stock/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.2.1'
1+
__version__ = '1.3.0'

highcharts_stock/options/series/data/hlc.py

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Optional
1+
from typing import Optional, List, Dict
22
from decimal import Decimal
33

44
from validator_collection import validators, checkers
@@ -237,10 +237,71 @@ def from_array(cls, value):
237237
f'be a DataBase Data Point or be '
238238
f'coercable to one. Could not coerce: '
239239
f'{item}')
240+
if checkers.is_string(as_obj.x) and not as_obj.name:
241+
as_obj.name = as_obj.x
242+
as_obj.x = None
243+
240244
collection.append(as_obj)
241245

242246
return collection
243247

248+
def _get_props_from_array(self) -> List[str]:
249+
"""Returns a list of the property names that can be set using the
250+
:meth:`.from_array() <highcharts_core.options.series.data.base.DataBase.from_array>`
251+
method.
252+
253+
:rtype: :class:`list <python:list>` of :class:`str <python:str>`
254+
"""
255+
return ['x', 'high', 'low', 'close', 'name']
256+
257+
def to_array(self, force_object = False) -> List | Dict:
258+
"""Generate the array representation of the data point (the inversion
259+
of
260+
:meth:`.from_array() <highcharts_core.options.series.data.base.DataBase.from_array>`).
261+
262+
.. warning::
263+
264+
If the data point *cannot* be serialized to a JavaScript array,
265+
this method will instead return the untrimmed :class:`dict <python:dict>`
266+
representation of the data point as a fallback.
267+
268+
:param force_object: if ``True``, forces the return of the instance's
269+
untrimmed :class:`dict <python:dict>` representation. Defaults to ``False``.
270+
:type force_object: :class:`bool <python:bool>`
271+
272+
:returns: The array representation of the data point.
273+
:rtype: :class:`list <python:list>` of values or :class:`dict <python:dict>`
274+
"""
275+
if self.requires_js_object or force_object:
276+
return self._to_untrimmed_dict()
277+
278+
if self.x is not None:
279+
x = self.x
280+
elif self.name is not None:
281+
x = self.name
282+
else:
283+
x = constants.EnforcedNull
284+
285+
if self.high is not None:
286+
high = self.high
287+
else:
288+
high = constants.EnforcedNull
289+
290+
if self.low is not None:
291+
low = self.low
292+
else:
293+
low = constants.EnforcedNull
294+
295+
if self.close is not None:
296+
close = self.close
297+
else:
298+
close = constants.EnforcedNull
299+
300+
if self.x is None and self.name is None:
301+
return [high, low, close]
302+
303+
return [x, high, low, close]
304+
244305

245306
class OHLCData(HLCData):
246307
"""Data point that can be visualized in a
@@ -371,6 +432,72 @@ def from_array(cls, value):
371432
f'be a DataBase Data Point or be '
372433
f'coercable to one. Could not coerce: '
373434
f'{item}')
435+
if checkers.is_string(as_obj.x) and not as_obj.name:
436+
as_obj.name = as_obj.x
437+
as_obj.x = None
438+
374439
collection.append(as_obj)
375440

376441
return collection
442+
443+
def _get_props_from_array(self) -> List[str]:
444+
"""Returns a list of the property names that can be set using the
445+
:meth:`.from_array() <highcharts_core.options.series.data.base.DataBase.from_array>`
446+
method.
447+
448+
:rtype: :class:`list <python:list>` of :class:`str <python:str>`
449+
"""
450+
return ['x', 'open', 'high', 'low', 'close', 'name']
451+
452+
def to_array(self, force_object = False) -> List | Dict:
453+
"""Generate the array representation of the data point (the inversion
454+
of
455+
:meth:`.from_array() <highcharts_core.options.series.data.base.DataBase.from_array>`).
456+
457+
.. warning::
458+
459+
If the data point *cannot* be serialized to a JavaScript array,
460+
this method will instead return the untrimmed :class:`dict <python:dict>`
461+
representation of the data point as a fallback.
462+
463+
:param force_object: if ``True``, forces the return of the instance's
464+
untrimmed :class:`dict <python:dict>` representation. Defaults to ``False``.
465+
:type force_object: :class:`bool <python:bool>`
466+
467+
:returns: The array representation of the data point.
468+
:rtype: :class:`list <python:list>` of values or :class:`dict <python:dict>`
469+
"""
470+
if self.requires_js_object or force_object:
471+
return self._to_untrimmed_dict()
472+
473+
if self.x is not None:
474+
x = self.x
475+
elif self.name is not None:
476+
x = self.name
477+
else:
478+
x = constants.EnforcedNull
479+
480+
if self.open is not None:
481+
open_ = self.open
482+
else:
483+
open_ = constants.EnforcedNull
484+
485+
if self.high is not None:
486+
high = self.high
487+
else:
488+
high = constants.EnforcedNull
489+
490+
if self.low is not None:
491+
low = self.low
492+
else:
493+
low = constants.EnforcedNull
494+
495+
if self.close is not None:
496+
close = self.close
497+
else:
498+
close = constants.EnforcedNull
499+
500+
if self.x is None and self.name is None:
501+
return [open, high, low, close]
502+
503+
return [x, open, high, low, close]

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ classifiers = [
5959

6060
requires-python = ">= 3.10"
6161
dependencies = [
62-
"highcharts-core>=1.0.0-rc1",
62+
"highcharts-core>=1.3.0",
6363
"esprima>=4.0.1",
6464
"validator-collection>=1.5.0",
6565
"requests>=2.31.0"

requirements.dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ tox==4.4.6
1212
requests==2.31.0
1313
urllib3==1.26.9
1414
validator-collection==1.5.0
15-
highcharts-core>=1.0.0-rc1
15+
highcharts-core>=1.3.0

requirements.travis.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ tox==4.4.6
1414
requests==2.31.0
1515
urllib3==1.26.9
1616
validator-collection==1.5.0
17-
highcharts-core>=1.0.0-rc1
17+
highcharts-core>=1.3.0

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
esprima==4.0.1
22
requests==2.31.0
33
validator-collection==1.5.0
4-
highcharts-core>=1.0.0-rc1
4+
highcharts-core>=1.3.0
24 Bytes
Loading

0 commit comments

Comments
 (0)