Skip to content

Commit b87d663

Browse files
authored
Merge pull request #643 from njwilson23/vegalite
Vega-Lite features
2 parents 5caecd4 + f6d61d6 commit b87d663

5 files changed

Lines changed: 255 additions & 26 deletions

File tree

examples/Features.ipynb

Lines changed: 155 additions & 23 deletions
Large diffs are not rendered by default.

examples/WMS_and_WMTS.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
" url='http://demo.opengeo.org/geoserver/ows',\n",
5555
" layers='nasa:bluemarble',\n",
5656
" name='bluemarble',\n",
57-
" format=\"image/png\",\n",
57+
" fmt=\"image/png\",\n",
5858
").add_to(m)\n",
5959
"\n",
6060
"\n",

folium/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from .features import (
1212
CircleMarker, ClickForMarker, CustomIcon, DivIcon, GeoJson, LatLngPopup,
13-
MarkerCluster, PolyLine, RegularPolygonMarker, TopoJson, Vega, WmsTileLayer,
13+
MarkerCluster, PolyLine, RegularPolygonMarker, TopoJson, Vega, VegaLite, WmsTileLayer,
1414
)
1515

1616
from .folium import Map
@@ -55,6 +55,7 @@
5555
'MarkerCluster',
5656
'PolyLine',
5757
'Vega',
58+
'VegaLite',
5859
'RegularPolygonMarker',
5960
'TopoJson',
6061
'WmsTileLayer'

folium/features.py

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class WmsTileLayer(Layer):
3535
The names of the layers to be displayed.
3636
styles : str, default None
3737
Comma-separated list of WMS styles.
38-
format : str, default None
38+
fmt : str, default None
3939
The format of the service output.
4040
Ex: 'image/png'
4141
transparent: bool, default True
@@ -259,6 +259,101 @@ def render(self, **kwargs):
259259
name='vega_parse')
260260

261261

262+
class VegaLite(Element):
263+
"""
264+
Creates a Vega-Lite chart element.
265+
266+
Parameters
267+
----------
268+
data: JSON-like str or object
269+
The Vega-Lite description of the chart.
270+
It can also be any object that has a method `to_json`,
271+
so that you can (for instance) provide an `Altair` chart.
272+
width: int or str, default None
273+
The width of the output element.
274+
If None, either data['width'] (if available) or '100%' will be used.
275+
Ex: 120, '120px', '80%'
276+
height: int or str, default None
277+
The height of the output element.
278+
If None, either data['width'] (if available) or '100%' will be used.
279+
Ex: 120, '120px', '80%'
280+
left: int or str, default '0%'
281+
The horizontal distance of the output with respect to the parent
282+
HTML object. Ex: 120, '120px', '80%'
283+
top: int or str, default '0%'
284+
The vertical distance of the output with respect to the parent
285+
HTML object. Ex: 120, '120px', '80%'
286+
position: str, default 'relative'
287+
The `position` argument that the CSS shall contain.
288+
Ex: 'relative', 'absolute'
289+
290+
"""
291+
def __init__(self, data, width=None, height=None,
292+
left='0%', top='0%', position='relative'):
293+
super(VegaLite, self).__init__()
294+
self._name = 'VegaLite'
295+
self.data = data.to_json() if hasattr(data, 'to_json') else data
296+
# FIXME:
297+
if isinstance(self.data, text_type) or isinstance(data, binary_type):
298+
self.data = json.loads(self.data)
299+
300+
# Size Parameters.
301+
self.width = _parse_size(self.data.get('width', '100%') if
302+
width is None else width)
303+
self.height = _parse_size(self.data.get('height', '100%') if
304+
height is None else height)
305+
self.left = _parse_size(left)
306+
self.top = _parse_size(top)
307+
self.position = position
308+
self._template = Template(u'')
309+
310+
def render(self, **kwargs):
311+
"""Renders the HTML representation of the element."""
312+
self.json = json.dumps(self.data)
313+
314+
self._parent.html.add_child(Element(Template("""
315+
<div id="{{this.get_name()}}"></div>
316+
""").render(this=self, kwargs=kwargs)), name=self.get_name())
317+
318+
self._parent.script.add_child(Element(Template("""
319+
var embedSpec = {
320+
mode: "vega-lite",
321+
spec: {{this.json}}
322+
};
323+
vg.embed({{this.get_name()}}, embedSpec, function(error, result) {});
324+
""").render(this=self)), name=self.get_name())
325+
326+
figure = self.get_root()
327+
assert isinstance(figure, Figure), ('You cannot render this Element '
328+
'if it is not in a Figure.')
329+
330+
figure.header.add_child(Element(Template("""
331+
<style> #{{this.get_name()}} {
332+
position : {{this.position}};
333+
width : {{this.width[0]}}{{this.width[1]}};
334+
height: {{this.height[0]}}{{this.height[1]}};
335+
left: {{this.left[0]}}{{this.left[1]}};
336+
top: {{this.top[0]}}{{this.top[1]}};
337+
</style>
338+
""").render(this=self, **kwargs)), name=self.get_name())
339+
340+
figure.header.add_child(
341+
JavascriptLink('https://d3js.org/d3.v3.min.js'),
342+
name='d3')
343+
344+
figure.header.add_child(
345+
JavascriptLink('https://cdnjs.cloudflare.com/ajax/libs/vega/2.6.5/vega.min.js'),
346+
name='vega')
347+
348+
figure.header.add_child(
349+
JavascriptLink('https://cdnjs.cloudflare.com/ajax/libs/vega-lite/1.3.1/vega-lite.min.js'),
350+
name='vega-lite')
351+
352+
figure.header.add_child(
353+
JavascriptLink('https://cdnjs.cloudflare.com/ajax/libs/vega-embed/2.2.0/vega-embed.min.js'),
354+
name='vega-embed')
355+
356+
262357
class GeoJson(Layer):
263358
"""
264359
Creates a GeoJson object for plotting into a Map.

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
altair
12
cartopy
23
geographiclib
34
geopandas

0 commit comments

Comments
 (0)