Skip to content

Commit

Permalink
Add ability to set font size in plot (#1879)
Browse files Browse the repository at this point in the history
* Added a function to process font sizes

* Add ability to set font size in plot and test it

* formatting with black

* correct import order

* move arg to be the last and added a docstring

* Update folium/folium.py

Co-authored-by: Frank Anema <33519926+Conengmo@users.noreply.github.com>

* Change to accept em and px

made px the default in line with _parse_size.

* correct test units

* formatting with black

* formatting with black

* Update tests/test_utilities.py

* Update tests/test_utilities.py

---------

Co-authored-by: Frank Anema <33519926+Conengmo@users.noreply.github.com>
  • Loading branch information
this-josh and Conengmo authored Feb 28, 2024
1 parent 36f2ff6 commit 6c85ddd
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
8 changes: 7 additions & 1 deletion folium/folium.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
TypeBounds,
TypeJsonValue,
_parse_size,
parse_font_size,
parse_options,
temp_html_filepath,
validate_location,
Expand Down Expand Up @@ -152,6 +153,9 @@ class Map(JSCSSMixin, MacroElement):
rare environments) even if they're supported.
zoom_control : bool, default True
Display zoom controls on the map.
font_size : int or float or string (default: '1rem')
The font size to use for Leaflet, can either be a number or a
string ending in 'rem', 'em', or 'px'.
**kwargs
Additional keyword arguments are passed to Leaflets Map class:
https://leafletjs.com/reference.html#map
Expand Down Expand Up @@ -186,7 +190,7 @@ class Map(JSCSSMixin, MacroElement):
left: {{this.left[0]}}{{this.left[1]}};
top: {{this.top[0]}}{{this.top[1]}};
}
.leaflet-container { font-size: 1rem; }
.leaflet-container { font-size: {{this.font_size}}; }
</style>
{% endmacro %}
Expand Down Expand Up @@ -253,6 +257,7 @@ def __init__(
disable_3d: bool = False,
png_enabled: bool = False,
zoom_control: bool = True,
font_size: str = "1rem",
**kwargs: TypeJsonValue,
):
super().__init__()
Expand All @@ -276,6 +281,7 @@ def __init__(
self.left = _parse_size(left)
self.top = _parse_size(top)
self.position = position
self.font_size = parse_font_size(font_size)

max_bounds_array = (
[[min_lat, min_lon], [max_lat, max_lon]] if max_bounds else None
Expand Down
10 changes: 10 additions & 0 deletions folium/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,3 +428,13 @@ def __init__(self, js_code: Union[str, "JsCode"]):
self.js_code: str = js_code.js_code
else:
self.js_code = js_code


def parse_font_size(value: Union[str, int, float]) -> str:
"""Parse a font size value, if number set as px"""
if isinstance(value, (int, float)):
return f"{value}px"

if (value[-3:] != "rem") and (value[-2:] not in ["em", "px"]):
raise ValueError("The font size must be expressed in rem, em, or px.")
return value
2 changes: 2 additions & 0 deletions tests/test_folium.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def setup_method(self):
max_zoom=20,
zoom_start=4,
max_bounds=True,
font_size="1.5rem",
attr=attr,
)
self.env = Environment(loader=PackageLoader("folium", "templates"))
Expand All @@ -94,6 +95,7 @@ def test_init(self):
assert self.m.top == (0, "%")
assert self.m.global_switches.no_touch is False
assert self.m.global_switches.disable_3d is False
assert self.m.font_size == "1.5rem"
assert self.m.to_dict() == {
"name": "Map",
"id": self.m._id,
Expand Down
24 changes: 24 additions & 0 deletions tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
get_obj_in_upper_tree,
if_pandas_df_convert_to_numpy,
javascript_identifier_path_to_array_notation,
parse_font_size,
parse_options,
validate_location,
validate_locations,
Expand Down Expand Up @@ -230,3 +231,26 @@ def test_js_code_init_js_code():
js_code_2 = JsCode(js_code)
assert isinstance(js_code_2, JsCode)
assert isinstance(js_code_2.js_code, str)


@pytest.mark.parametrize(
"value,expected",
[
(10, "10px"),
(12.5, "12.5px"),
("1rem", "1rem"),
("1em", "1em"),
],
)
def test_parse_font_size_valid(value, expected):
assert parse_font_size(value) == expected


invalid_values = ["1", "1unit"]
expected_errors = "The font size must be expressed in rem, em, or px."


@pytest.mark.parametrize("value,error_message", zip(invalid_values, expected_errors))
def test_parse_font_size_invalid(value, error_message):
with pytest.raises(ValueError, match=error_message):
parse_font_size(value)

0 comments on commit 6c85ddd

Please sign in to comment.