Skip to content

Commit beebf42

Browse files
committed
Added support for BorderRadius object and fixed missing SunburstOptions.border_radius property.
1 parent 830d244 commit beebf42

File tree

7 files changed

+219
-11
lines changed

7 files changed

+219
-11
lines changed

docs/api.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,8 @@ Core Components
622622
:class:`ASTNode <highcharts_core.utility_classes.ast.ASTNode>`
623623
:class:`TextPath <highcharts_core.utility_classes.ast.TextPath>`
624624
:class:`AttributeObject <highcharts_core.utility_classes.ast.AttributeObject>`
625+
* - :mod:`.utility_classes.border_radius <highcharts_core.utility_classes.border_radius>`
626+
- :class:`BorderRadius <highcharts_core.utility_classes.border_radius.BorderRadius>`
625627
* - :mod:`.utility_classes.breadcrumbs <highcharts_core.utility_classes.breadcrumbs>`
626628
- :class:`BreadcrumbOptions <highcharts_core.utility_classes.breadcrumbs.BreadcrumbOptions>`
627629
:class:`Separator <highcharts_core.utility_classes.breadcrumbs.Separator>`
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
##########################################################################################
2+
:mod:`.border_radius <highcharts_core.utility_classes.border_radius>`
3+
##########################################################################################
4+
5+
.. contents:: Module Contents
6+
:local:
7+
:depth: 3
8+
:backlinks: entry
9+
10+
--------------
11+
12+
.. module:: highcharts_core.utility_classes.border_radius
13+
14+
********************************************************************************************************************
15+
class: :class:`BorderRadius <highcharts_core.utility_classes.border_radius.BorderRadius>`
16+
********************************************************************************************************************
17+
18+
.. autoclass:: BorderRadius
19+
:members:
20+
:inherited-members:
21+
22+
.. collapse:: Class Inheritance
23+
24+
.. inheritance-diagram:: BorderRadius
25+
:top-classes: highcharts_core.metaclasses.HighchartsMeta
26+
:parts: -1
27+
28+
|
29+

docs/api/utility_classes/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ Sub-components
5353
:class:`ASTNode <highcharts_core.utility_classes.ast.ASTNode>`
5454
:class:`TextPath <highcharts_core.utility_classes.ast.TextPath>`
5555
:class:`AttributeObject <highcharts_core.utility_classes.ast.AttributeObject>`
56+
* - :mod:`.utility_classes.border_radius <highcharts_core.utility_classes.border_radius>`
57+
- :class:`BorderRadius <highcharts_core.utility_classes.border_radius.BorderRadius>`
5658
* - :mod:`.utility_classes.breadcrumbs <highcharts_core.utility_classes.breadcrumbs>`
5759
- :class:`BreadcrumbOptions <highcharts_core.utility_classes.breadcrumbs.BreadcrumbOptions>`
5860
:class:`Separator <highcharts_core.utility_classes.breadcrumbs.Separator>`

highcharts_core/options/plot_options/bar.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from highcharts_core.utility_classes.patterns import Pattern
1111
from highcharts_core.utility_classes.data_grouping import DataGroupingOptions
1212
from highcharts_core.utility_classes.partial_fill import PartialFillOptions
13+
from highcharts_core.utility_classes.border_radius import BorderRadius
1314

1415

1516
class BaseBarOptions(SeriesOptions):
@@ -61,7 +62,7 @@ def border_color(self, value):
6162
self._border_color = utility_functions.validate_color(value)
6263

6364
@property
64-
def border_radius(self) -> Optional[int | float | Decimal]:
65+
def border_radius(self) -> Optional[int | float | Decimal | str | BorderRadius]:
6566
"""The corner radius of the border surrounding each column or bar. Defaults to
6667
``0``.
6768
@@ -71,9 +72,23 @@ def border_radius(self) -> Optional[int | float | Decimal]:
7172

7273
@border_radius.setter
7374
def border_radius(self, value):
74-
self._border_radius = validators.numeric(value,
75-
allow_empty = True,
76-
minimum = 0)
75+
if value is None:
76+
self._border_radius = None
77+
else:
78+
try:
79+
self._border_radius = validators.numeric(value,
80+
allow_empty = True,
81+
minimum = 0)
82+
except (ValueError, TypeError):
83+
try:
84+
self._border_radius = validate_types(value, BorderRadius)
85+
except (ValueError, TypeError):
86+
if not isinstance(value, str):
87+
raise errors.HighchartsValueError(f'border_radius must be a numeric value, '
88+
f'a string, or an instance of BorderRadius. '
89+
f'Received {value.__class__.__name__}.')
90+
91+
self._border_radius = value
7792

7893
@property
7994
def border_width(self) -> Optional[int | float | Decimal]:

highcharts_core/options/plot_options/pie.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from highcharts_core.utility_classes.gradients import Gradient
99
from highcharts_core.utility_classes.patterns import Pattern
1010
from highcharts_core.utility_classes.data_labels import PieDataLabel
11+
from highcharts_core.utility_classes.border_radius import BorderRadius
1112
from highcharts_core.decorators import validate_types
1213

1314

@@ -95,7 +96,7 @@ def border_color(self, value):
9596
self._border_color = utility_functions.validate_color(value)
9697

9798
@property
98-
def border_radius(self) -> Optional[str | int | float | Decimal]:
99+
def border_radius(self) -> Optional[str | int | float | Decimal | BorderRadius]:
99100
"""
100101
.. versionadded:: Highcharts Core for Python v.1.1.0 / Highcharts Core (JS) v.11.0.0
101102
@@ -106,7 +107,9 @@ def border_radius(self) -> Optional[str | int | float | Decimal]:
106107
A numerical value signifies the value is expressed in pixels. A percentage string like `50%`
107108
signifies a size relative to the radius and the inner radius.
108109
109-
:rtype: numeric, :class:`str <python:str>` or :obj:`None <python:None>`
110+
:rtype: numeric, :class:`str <python:str>`,
111+
:class:`BorderRadius <highcharts_core.utility_classes.border_radius.BorderRadius>` or
112+
:obj:`None <python:None>`
110113
"""
111114
return self._border_radius
112115

@@ -116,11 +119,14 @@ def border_radius(self, value):
116119
self._border_radius = None
117120
else:
118121
try:
119-
value = validators.string(value)
120-
if '%' not in value:
121-
raise ValueError
122-
except (TypeError, ValueError):
123-
value = validators.numeric(value, minimum = 0)
122+
value = validate_types(value, types = BorderRadius)
123+
except (ValueError, TypeError):
124+
try:
125+
value = validators.string(value)
126+
if '%' not in value:
127+
raise ValueError
128+
except (TypeError, ValueError):
129+
value = validators.numeric(value, minimum = 0)
124130

125131
self._border_radius = value
126132

highcharts_core/options/plot_options/sunburst.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from highcharts_core.utility_classes.breadcrumbs import BreadcrumbOptions
1313
from highcharts_core.utility_classes.shadows import ShadowOptions
1414
from highcharts_core.utility_classes.data_labels import SunburstDataLabel
15+
from highcharts_core.utility_classes.border_radius import BorderRadius
1516

1617

1718
class SunburstOptions(GenericTypeOptions):
@@ -28,6 +29,7 @@ class SunburstOptions(GenericTypeOptions):
2829
"""
2930

3031
def __init__(self, **kwargs):
32+
self._border_radius = None
3133
self._color_index = None
3234
self._crisp = None
3335
self._shadow = None
@@ -46,6 +48,7 @@ def __init__(self, **kwargs):
4648
self._sliced_offset = None
4749
self._start_angle = None
4850

51+
self.border_radius = kwargs.get('border_radius', None)
4952
self.color_index = kwargs.get('color_index', None)
5053
self.crisp = kwargs.get('crisp', None)
5154
self.shadow = kwargs.get('shadow', None)
@@ -117,6 +120,35 @@ def border_width(self, value):
117120
allow_empty = True,
118121
minimum = 0)
119122

123+
@property
124+
def border_radius(self) -> Optional[int | float | Decimal | str | BorderRadius]:
125+
"""The corner radius of the border surrounding each column or bar. Defaults to
126+
``0``.
127+
128+
:rtype: numeric or :obj:`None <python:None>`
129+
"""
130+
return self._border_radius
131+
132+
@border_radius.setter
133+
def border_radius(self, value):
134+
if value is None:
135+
self._border_radius = None
136+
else:
137+
try:
138+
self._border_radius = validators.numeric(value,
139+
allow_empty = True,
140+
minimum = 0)
141+
except (ValueError, TypeError):
142+
try:
143+
self._border_radius = validate_types(value, BorderRadius)
144+
except (ValueError, TypeError):
145+
if not isinstance(value, str):
146+
raise errors.HighchartsValueError(f'border_radius must be a numeric value, '
147+
f'a string, or an instance of BorderRadius. '
148+
f'Received {value.__class__.__name__}.')
149+
150+
self._border_radius = value
151+
120152
@property
121153
def breadcrumbs(self) -> Optional[BreadcrumbOptions]:
122154
"""Options for the breadcrumbs, the navigation at the top leading the way up
@@ -468,6 +500,7 @@ def _get_kwargs_from_dict(cls, as_dict):
468500
'allow_traversing_tree': as_dict.get('allowTraversingTree', None),
469501
'border_color': as_dict.get('borderColor', None),
470502
'border_width': as_dict.get('borderWidth', None),
503+
'border_radius': as_dict.get('borderRadius', None),
471504
'breadcrumbs': as_dict.get('breadcrumbs', None),
472505
'center': as_dict.get('center', None),
473506
'color_by_point': as_dict.get('colorByPoint', None),
@@ -491,6 +524,7 @@ def _to_untrimmed_dict(self, in_cls = None) -> dict:
491524
'allowTraversingTree': self.allow_traversing_tree,
492525
'borderColor': self.border_color,
493526
'borderWidth': self.border_width,
527+
'borderRadius': self.border_radius,
494528
'breadcrumbs': self.breadcrumbs,
495529
'center': self.center,
496530
'colorByPoint': self.color_by_point,
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
from typing import Optional
2+
from decimal import Decimal
3+
4+
from validator_collection import validators
5+
6+
from highcharts_core import errors
7+
from highcharts_core.decorators import class_sensitive
8+
from highcharts_core.metaclasses import HighchartsMeta
9+
10+
11+
class BorderRadius(HighchartsMeta):
12+
"""Precise configuration of Border Radius behavior."""
13+
14+
def __init__(self, **kwargs):
15+
self._radius = None
16+
self._scope = None
17+
self._where = None
18+
19+
self.radius = kwargs.get('radius', None)
20+
self.scope = kwargs.get('scope', None)
21+
self.where = kwargs.get('where', None)
22+
23+
@property
24+
def radius(self) -> Optional[str | int | float | Decimal]:
25+
"""The border radius.
26+
27+
A number signifies pixels.
28+
29+
A percentage string, like for example 50%, signifies a relative size.
30+
31+
.. note::
32+
33+
For columns this is relative to the column width, for pies it is relative to the radius
34+
and the inner radius.
35+
36+
:rtype: numeric or :class:`str <python:str>` or :obj:`None <python:None>`
37+
"""
38+
return self._radius
39+
40+
@radius.setter
41+
def radius(self, value):
42+
if value is None:
43+
self._radius = None
44+
else:
45+
try:
46+
self._radius = validators.numeric(value, allow_empty = None)
47+
except (ValueError, TypeError):
48+
if not isinstance(value, str):
49+
raise errors.HighchartsValueError(f'radius expects a number or string. '
50+
f'Received: {value.__class__.__name__}')
51+
self._radius = value
52+
53+
@property
54+
def scope(self) -> Optional[str]:
55+
"""The scope of the rounding for column charts.
56+
57+
.. note::
58+
59+
In a stacked column chart:
60+
61+
* the value ``'point'`` means each single point will get rounded corners
62+
* the value ``'stack'`` means the rounding will apply to the full stack, so that
63+
only points close to the top or bottom will receive rounding.
64+
65+
:rtype: :class:`str <python:str>` or :obj:`None <python:None>`
66+
"""
67+
return self._scope
68+
69+
@scope.setter
70+
def scope(self, value):
71+
if not value:
72+
self._scope = None
73+
else:
74+
value = value.lower()
75+
if value not in ['point', 'stack']:
76+
raise errors.HighchartsValueError(f'scope expects either "point" or "stack". '
77+
f'Received: {value}')
78+
self._scope = value
79+
80+
@property
81+
def where(self) -> Optional[str]:
82+
"""For column charts, where in the point or stack to apply rounding.
83+
84+
* The value ``'end'`` means only those corners at the point value will be rounded,
85+
leaving the corners at the base or threshold unrounded. This is the most intuitive behaviour.
86+
* The value ``'all'`` means the base will be rounded, in addition to the corners at the point value.
87+
88+
:rtype: :class:`str <python:str>` or :obj:`None <python:None>`
89+
"""
90+
return self._where
91+
92+
@where.setter
93+
def where(self, value):
94+
if not value:
95+
self._where = None
96+
else:
97+
value = value.lower()
98+
if value not in ['end', 'all']:
99+
raise errors.HighchartsValueError(f'where expects either "end" or "all". '
100+
f'Received: {value}')
101+
self._where = value
102+
103+
@classmethod
104+
def _get_kwargs_from_dict(cls, as_dict):
105+
kwargs = {
106+
'radius': as_dict.get('radius', None),
107+
'scope': as_dict.get('scope', None),
108+
'where': as_dict.get('where', None)
109+
}
110+
111+
return kwargs
112+
113+
def _to_untrimmed_dict(self, in_cls = None) -> dict:
114+
untrimmed = {
115+
'radius': self.radius,
116+
'scope': self.scope,
117+
'where': self.where
118+
}
119+
120+
return untrimmed

0 commit comments

Comments
 (0)