140 lines
3.9 KiB
Python
140 lines
3.9 KiB
Python
from typing import List, Tuple
|
|
|
|
from branca.element import CssLink, Element, Figure, JavascriptLink, MacroElement
|
|
from jinja2 import Template
|
|
|
|
from folium.utilities import JsCode
|
|
|
|
|
|
class JSCSSMixin(Element):
|
|
"""Render links to external Javascript and CSS resources."""
|
|
|
|
default_js: List[Tuple[str, str]] = []
|
|
default_css: List[Tuple[str, str]] = []
|
|
|
|
def render(self, **kwargs) -> None:
|
|
figure = self.get_root()
|
|
assert isinstance(
|
|
figure, Figure
|
|
), "You cannot render this Element if it is not in a Figure."
|
|
|
|
for name, url in self.default_js:
|
|
figure.header.add_child(JavascriptLink(url), name=name)
|
|
|
|
for name, url in self.default_css:
|
|
figure.header.add_child(CssLink(url), name=name)
|
|
|
|
super().render(**kwargs)
|
|
|
|
def add_css_link(self, name: str, url: str):
|
|
"""Add or update css resource link."""
|
|
self._add_link(name, url, self.default_css)
|
|
|
|
def add_js_link(self, name: str, url: str):
|
|
"""Add or update JS resource link."""
|
|
self._add_link(name, url, self.default_js)
|
|
|
|
def _add_link(self, name: str, url: str, default_list: List[Tuple[str, str]]):
|
|
"""Modify a css or js link.
|
|
|
|
If `name` does not exist, the link will be appended
|
|
"""
|
|
|
|
for i, pair in enumerate(default_list):
|
|
if pair[0] == name:
|
|
default_list[i] = (name, url)
|
|
break
|
|
else:
|
|
default_list.append((name, url))
|
|
|
|
|
|
class EventHandler(MacroElement):
|
|
'''
|
|
Add javascript event handlers.
|
|
|
|
Examples
|
|
--------
|
|
>>> import folium
|
|
>>> from folium.utilities import JsCode
|
|
>>>
|
|
>>> m = folium.Map()
|
|
>>>
|
|
>>> geo_json_data = {
|
|
... "type": "FeatureCollection",
|
|
... "features": [
|
|
... {
|
|
... "type": "Feature",
|
|
... "geometry": {
|
|
... "type": "Polygon",
|
|
... "coordinates": [
|
|
... [
|
|
... [100.0, 0.0],
|
|
... [101.0, 0.0],
|
|
... [101.0, 1.0],
|
|
... [100.0, 1.0],
|
|
... [100.0, 0.0],
|
|
... ]
|
|
... ],
|
|
... },
|
|
... "properties": {"prop1": {"title": "Somewhere on Sumatra"}},
|
|
... }
|
|
... ],
|
|
... }
|
|
>>>
|
|
>>> g = folium.GeoJson(geo_json_data).add_to(m)
|
|
>>>
|
|
>>> highlight = JsCode(
|
|
... """
|
|
... function highlight(e) {
|
|
... e.target.original_color = e.layer.options.color;
|
|
... e.target.setStyle({ color: "green" });
|
|
... }
|
|
... """
|
|
... )
|
|
>>>
|
|
>>> reset = JsCode(
|
|
... """
|
|
... function reset(e) {
|
|
... e.target.setStyle({ color: e.target.original_color });
|
|
... }
|
|
... """
|
|
... )
|
|
>>>
|
|
>>> g.add_child(EventHandler("mouseover", highlight))
|
|
>>> g.add_child(EventHandler("mouseout", reset))
|
|
'''
|
|
|
|
_template = Template(
|
|
"""
|
|
{% macro script(this, kwargs) %}
|
|
{{ this._parent.get_name()}}.on(
|
|
{{ this.event|tojson}},
|
|
{{ this.handler.js_code }}
|
|
);
|
|
{% endmacro %}
|
|
"""
|
|
)
|
|
|
|
def __init__(self, event: str, handler: JsCode):
|
|
super().__init__()
|
|
self._name = "EventHandler"
|
|
self.event = event
|
|
self.handler = handler
|
|
|
|
|
|
class ElementAddToElement(MacroElement):
|
|
"""Abstract class to add an element to another element."""
|
|
|
|
_template = Template(
|
|
"""
|
|
{% macro script(this, kwargs) %}
|
|
{{ this.element_name }}.addTo({{ this.element_parent_name }});
|
|
{% endmacro %}
|
|
"""
|
|
)
|
|
|
|
def __init__(self, element_name: str, element_parent_name: str):
|
|
super().__init__()
|
|
self.element_name = element_name
|
|
self.element_parent_name = element_parent_name
|