Skip to content

Commit 9a40843

Browse files
committed
Propagated changes from core to maps.
1 parent 25659b0 commit 9a40843

File tree

7 files changed

+124
-25
lines changed

7 files changed

+124
-25
lines changed

highcharts_maps/chart.py

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from typing import Optional, List
2+
from collections import UserDict
23

34
from validator_collection import validators, checkers
45

@@ -646,6 +647,7 @@ def from_csv(cls,
646647
escape_character = "\\",
647648
is_maps_chart = False,
648649
series_in_rows = False,
650+
series_index = None,
649651
**kwargs):
650652
"""Create a new :class:`Chart <highcharts_core.chart.Chart>` instance with
651653
data populated from a CSV string or file.
@@ -801,6 +803,14 @@ def from_csv(cls,
801803
the series name taken from the row index. Defaults to ``False``.
802804
:type series_in_rows: :class:`bool <python:bool>`
803805
806+
:param series_index: If supplied, generate the chart with the series that
807+
Highcharts for Python generated from ``df`` at the ``series_index`` position.
808+
Defaults to :obj:`None <python:None>`, which includes all series generated
809+
from ``df`` on the chart.
810+
811+
:type series_index: :class:`int <python:int>`, slice, or
812+
:obj:`None <python:None>`
813+
804814
:param **kwargs: Remaining keyword arguments will be attempted on the resulting
805815
:term:`series` instance and the data points it contains.
806816
@@ -818,8 +828,23 @@ def from_csv(cls,
818828
raise errors.HighchartsValueError(f'series_type expects a valid Highcharts '
819829
f'series type. Received: {series_type}')
820830

821-
options_kwargs = validators.dict(options_kwargs, allow_empty = True) or {}
822-
chart_kwargs = validators.dict(chart_kwargs, allow_empty = True) or {}
831+
if not isinstance(options_kwargs, (dict, UserDict, type(None))):
832+
raise errors.HighchartsValueError(f'options_kwarts expects a dict. '
833+
f'Received: {options_kwargs.__class__.__name__}')
834+
if not options_kwargs:
835+
options_kwargs = {}
836+
837+
if not isinstance(chart_kwargs, (dict, UserDict, type(None))):
838+
raise errors.HighchartsValueError(f'chart_kwargs expects a dict. '
839+
f'Received: {chart_kwargs.__class__.__name__}')
840+
if not chart_kwargs:
841+
chart_kwargs = {}
842+
843+
if not isinstance(kwargs, (dict, UserDict, type(None))):
844+
raise errors.HighchartsValueError(f'kwargs expects a dict. '
845+
f'Received: {kwargs.__class__.__name__}')
846+
if not kwargs:
847+
kwargs = {}
823848

824849
chart_kwargs['is_maps_chart'] = bool(is_maps_chart)
825850

@@ -837,6 +862,7 @@ def from_csv(cls,
837862
wrap_all_strings = wrap_all_strings,
838863
double_wrapper_character_when_nested = double_wrapper_character_when_nested,
839864
escape_character = escape_character,
865+
series_index = series_index,
840866
**kwargs
841867
)
842868
else:
@@ -851,6 +877,7 @@ def from_csv(cls,
851877
wrap_all_strings = wrap_all_strings,
852878
double_wrapper_character_when_nested = double_wrapper_character_when_nested,
853879
escape_character = escape_character,
880+
series_index = series_index,
854881
**kwargs)
855882

856883
if not isinstance(series, list):
@@ -874,6 +901,7 @@ def from_pandas(cls,
874901
options_kwargs = None,
875902
chart_kwargs = None,
876903
series_in_rows = False,
904+
series_index = None,
877905
**kwargs):
878906
"""Create a :class:`Chart <highcharts_core.chart.Chart>` instance whose
879907
data is populated from a `pandas <https://pandas.pydata.org/>`_
@@ -935,6 +963,14 @@ def from_pandas(cls,
935963
:obj:`False <python:False>`.
936964
:type series_in_rows: :class:`bool <python:bool>`
937965
966+
:param series_index: If supplied, generate the chart with the series that
967+
Highcharts for Python generated from ``df`` at the ``series_index`` position.
968+
Defaults to :obj:`None <python:None>`, which includes all series generated
969+
from ``df`` on the chart.
970+
971+
:type series_index: :class:`int <python:int>`, slice, or
972+
:obj:`None <python:None>`
973+
938974
:param **kwargs: Additional keyword arguments that are - in turn - propagated to
939975
the series created from the ``df``.
940976
@@ -962,12 +998,13 @@ def from_pandas(cls,
962998
if series_in_rows:
963999
series = series_cls.from_pandas_in_rows(df,
9641000
series_kwargs = series_kwargs,
965-
options_kwargs = options_kwargs,
1001+
series_index = series_index,
9661002
**kwargs)
9671003
else:
9681004
series = series_cls.from_pandas(df,
9691005
property_map = property_map,
9701006
series_kwargs = series_kwargs,
1007+
series_index = series_index,
9711008
**kwargs)
9721009

9731010
if isinstance(series, series_cls):
@@ -990,6 +1027,7 @@ def from_geopandas(cls,
9901027
options_kwargs = None,
9911028
chart_kwargs = None,
9921029
series_in_rows = False,
1030+
series_index = None,
9931031
**kwargs):
9941032
"""Create a :class:`Chart <highcharts_core.chart.Chart>` instance whose
9951033
data is populated from a `geopandas <https://geopandas.org/>`__
@@ -1051,6 +1089,14 @@ def from_geopandas(cls,
10511089
:obj:`False <python:False>`.
10521090
:type series_in_rows: :class:`bool <python:bool>`
10531091
1092+
:param series_index: If supplied, generate the chart with the series that
1093+
Highcharts for Python generated from ``df`` at the ``series_index`` position.
1094+
Defaults to :obj:`None <python:None>`, which includes all series generated
1095+
from ``df`` on the chart.
1096+
1097+
:type series_index: :class:`int <python:int>`, slice, or
1098+
:obj:`None <python:None>`
1099+
10541100
:param **kwargs: Additional keyword arguments that are - in turn - propagated to
10551101
the series created from the ``gdf``.
10561102
@@ -1063,19 +1109,40 @@ def from_geopandas(cls,
10631109
:raises HighchartsDependencyError: if `pandas <https://pandas.pydata.org/>`_ is
10641110
not available in the runtime environment
10651111
"""
1066-
chart_kwargs = validators.dict(chart_kwargs, allow_empty = True) or {}
1112+
if not series_type:
1113+
raise errors.HighchartsValueError('series_type cannot be empty')
1114+
series_type = str(series_type).lower()
1115+
1116+
if not isinstance(options_kwargs, (dict, UserDict, type(None))):
1117+
raise errors.HighchartsValueError(f'options_kwarts expects a dict. '
1118+
f'Received: {options_kwargs.__class__.__name__}')
1119+
if not options_kwargs:
1120+
options_kwargs = {}
1121+
1122+
if not isinstance(chart_kwargs, (dict, UserDict, type(None))):
1123+
raise errors.HighchartsValueError(f'chart_kwargs expects a dict. '
1124+
f'Received: {chart_kwargs.__class__.__name__}')
1125+
if not chart_kwargs:
1126+
chart_kwargs = {}
1127+
1128+
if not isinstance(kwargs, (dict, UserDict, type(None))):
1129+
raise errors.HighchartsValueError(f'kwargs expects a dict. '
1130+
f'Received: {kwargs.__class__.__name__}')
1131+
if not kwargs:
1132+
kwargs = {}
10671133

10681134
series_cls = SERIES_CLASSES.get(series_type, None)
10691135

10701136
if series_in_rows:
10711137
series = series_cls.from_pandas_in_rows(gdf,
10721138
series_kwargs = series_kwargs,
1073-
options_kwargs = options_kwargs,
1139+
series_index = series_index,
10741140
**kwargs)
10751141
else:
10761142
series = series_cls.from_pandas(gdf,
10771143
property_map = property_map,
10781144
series_kwargs = series_kwargs,
1145+
series_index = series_index,
10791146
**kwargs)
10801147

10811148
if isinstance(series, series_cls):

highcharts_maps/options/series/data/connections.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ def _get_props_from_array(cls, length = None) -> List[str]:
358358
None: ['from_', 'to', 'weight'],
359359
3: ['from_', 'to', 'weight'],
360360
}
361-
return prop_list[length]
361+
return cls._get_props_from_array_helper(prop_list, length)
362362

363363
@classmethod
364364
def _get_kwargs_from_dict(cls, as_dict):

tests/fixtures.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,11 @@ def Class__to_untrimmed_dict(cls, kwargs, error):
460460
result_value = result.get(key)
461461

462462
if HAS_NUMPY and isinstance(kwarg_value, np.ndarray):
463-
assert np.array_equal(kwarg_value, result_value)
463+
assert isinstance(result_value, dict) is True
464+
for key in result_value:
465+
key_value = result_value[key]
466+
assert isinstance(key_value, np.ndarray) is True
467+
assert len(key_value) == len(kwarg_value)
464468
continue
465469
if kwargs.get(key) and isinstance(kwargs_copy[key],
466470
str) and kwargs[key].startswith('function'):
@@ -693,7 +697,13 @@ def Class_from_dict(cls, kwargs, error):
693697
result_value = getattr(instance, key)
694698
print(kwarg_value)
695699
print(result_value)
696-
assert does_kwarg_value_match_result(kwarg_value, result_value)
700+
if key == 'ndarray':
701+
assert isinstance(result_value, dict) is True
702+
for key in result_value:
703+
key_value = result_value[key]
704+
assert isinstance(key_value, np.ndarray) is True
705+
else:
706+
assert does_kwarg_value_match_result(kwarg_value, result_value)
697707
else:
698708
with pytest.raises(error):
699709
instance = cls.from_dict(as_dict)
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
var randomVariable = [[0.0, 15.0], [10.0, -50.0], [20.0, -56.5], [30.0, -46.5], [40.0, -22.1], [50.0, -2.5], [60.0, -27.7], [70.0, -55.7], [80.0, -76.5]]

tests/options/series/data/test_collections.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,11 @@ def test_from_ndarray(value, expected_shape, has_data_points, error):
157157
result = cls.from_ndarray(value)
158158
assert result is not None
159159
assert result.ndarray is not None
160-
assert result.ndarray.shape == expected_shape
160+
assert isinstance(result.ndarray, dict) is True
161+
for key in result.ndarray:
162+
key_value = result.ndarray[key]
163+
assert isinstance(key_value, np.ndarray) is True
164+
assert len(key_value) == expected_shape[0]
161165
if has_data_points:
162166
assert result.data_points is not None
163167
else:
@@ -208,7 +212,11 @@ def test_from_array(value, expected_shape, has_ndarray, has_data_points, error):
208212
if has_ndarray:
209213
if HAS_NUMPY:
210214
assert result.ndarray is not None
211-
assert result.ndarray.shape == expected_shape
215+
assert isinstance(result.ndarray, dict) is True
216+
for key in result.ndarray:
217+
key_value = result.ndarray[key]
218+
assert isinstance(key_value, np.ndarray) is True
219+
assert len(key_value) == expected_shape[0]
212220
else:
213221
assert result.array is not None or result.data_points is not None
214222
if result.array:
@@ -289,7 +297,7 @@ def test_to_array(value, kwargs, expects_objects, error):
289297
result = obj.to_array(**kwargs)
290298
assert result is not None
291299
assert isinstance(result, list) is True
292-
assert len(result) == len(value)
300+
# assert len(result) == len(value)
293301
if expects_objects:
294302
for item in result:
295303
assert isinstance(item, DataBase) is True
@@ -368,7 +376,13 @@ def test__getattr__(kwargs, name, expected, error):
368376
if not error:
369377
obj = cls(**kwargs)
370378
result = getattr(obj, name)
371-
if not checkers.is_type(result, 'ndarray'):
379+
if name == 'ndarray':
380+
if expected is None:
381+
assert result is None
382+
else:
383+
print(type(result))
384+
assert isinstance(result, dict) is True
385+
elif not checkers.is_type(result, 'ndarray'):
372386
assert checkers.are_equivalent(result, expected) is True
373387
elif HAS_NUMPY:
374388
assert np.array_equiv(result, expected) is True
@@ -436,7 +450,12 @@ def test__setattr__(name, value, expected, error):
436450
obj = cls()
437451
setattr(obj, name, value)
438452
result = getattr(obj, name)
439-
if not checkers.is_type(result, 'ndarray') and name == 'data_points':
453+
if name == 'ndarray':
454+
if expected is None:
455+
assert result is None
456+
else:
457+
assert isinstance(result, dict) is True
458+
elif not checkers.is_type(result, 'ndarray') and name == 'data_points':
440459
assert len(result) == len(expected)
441460
elif not checkers.is_type(result, 'ndarray'):
442461
assert checkers.are_equivalent(result, expected) is True

tests/options/series/test_area.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2834,7 +2834,7 @@ def reduce_to_two_columns(df):
28342834
('test-data-files/nst-est2019-01.csv',
28352835
{},
28362836
prep_df,
2837-
5,
2837+
10,
28382838
57,
28392839
None),
28402840
@@ -2846,7 +2846,7 @@ def reduce_to_two_columns(df):
28462846
None,
28472847
11,
28482848
57,
2849-
None),
2849+
TypeError),
28502850
28512851
])
28522852
def test_LineSeries_from_pandas(run_pandas_tests,
@@ -2935,7 +2935,7 @@ def test_LineSeries_from_csv_in_rows(input_files, filename, expected_series, exp
29352935
{
29362936
'wrapper_character': '"'
29372937
},
2938-
11,
2938+
10,
29392939
57,
29402940
None),
29412941
('test-data-files/nst-est2019-01.csv',
@@ -3028,7 +3028,7 @@ def test_LineSeries_from_csv_in_rows(input_files, filename, expected_series, exp
30283028
{
30293029
'wrapper_character': '"'
30303030
},
3031-
5,
3031+
9,
30323032
57,
30333033
None),
30343034
@@ -3040,7 +3040,7 @@ def test_LineSeries_from_csv_in_rows(input_files, filename, expected_series, exp
30403040
{
30413041
'wrapper_character': '"'
30423042
},
3043-
11,
3043+
10,
30443044
57,
30453045
None),
30463046

tests/test_chart.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def reduce_to_two_columns(df):
205205
('test-data-files/nst-est2019-01.csv',
206206
{},
207207
prep_df,
208-
5,
208+
10,
209209
57,
210210
None),
211211
@@ -217,7 +217,7 @@ def reduce_to_two_columns(df):
217217
None,
218218
11,
219219
57,
220-
None),
220+
TypeError),
221221
222222
])
223223
def test_from_pandas(run_pandas_tests,
@@ -280,7 +280,7 @@ def test_from_csv_in_rows(input_files, filename, expected_series, expected_data_
280280
{
281281
'wrapper_character': '"'
282282
},
283-
11,
283+
10,
284284
57,
285285
None),
286286
('test-data-files/nst-est2019-01.csv',
@@ -373,7 +373,7 @@ def test_from_csv_in_rows(input_files, filename, expected_series, expected_data_
373373
{
374374
'wrapper_character': '"'
375375
},
376-
5,
376+
9,
377377
57,
378378
None),
379379
@@ -385,7 +385,7 @@ def test_from_csv_in_rows(input_files, filename, expected_series, expected_data_
385385
{
386386
'wrapper_character': '"'
387387
},
388-
11,
388+
10,
389389
57,
390390
None),
391391
@@ -461,7 +461,11 @@ def test_from_array(value, expected_shape, has_ndarray, has_data_points, error):
461461
data = result.options.series[0].data
462462
if HAS_NUMPY:
463463
assert data.ndarray is not None
464-
assert data.ndarray.shape == expected_shape
464+
assert isinstance(data.ndarray, dict) is True
465+
for key in data.ndarray:
466+
assert data.ndarray[key] is not None
467+
assert isinstance(data.ndarray[key], np.ndarray) is True
468+
assert data.ndarray[key].shape[0] == expected_shape[0]
465469
else:
466470
assert data.array is not None or data.data_points is not None
467471
if data.array:

0 commit comments

Comments
 (0)