Skip to content

Commit 4516391

Browse files
TomTom4martinRenou
authored andcommitted
Add LegendControl
Signed-off-by: martinRenou <[email protected]>
1 parent 8248579 commit 4516391

File tree

7 files changed

+413
-0
lines changed

7 files changed

+413
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Legend Control
2+
==============
3+
4+
Example
5+
-------
6+
7+
.. jupyter-execute::
8+
9+
from ipyleaflet import Map, LegendControl
10+
mymap = Map(center=(-10,-45), zoom=4)
11+
a_legend = LegendControl({"low":"#FAA", "medium":"#A55", "High":"#500"}, name="Legend", position="bottomright")
12+
mymap.add_control(a_legend)
13+
mymap
14+
15+
.. jupyter-execute::
16+
17+
# manipulate the legend
18+
19+
# legend title
20+
a_legend.name = "Risk" ## set name
21+
a_legend.name # get name
22+
23+
# legend content
24+
a_legend.legends = {"el1":"#FAA", "el2":"#A55", "el3":"#500"} #set content
25+
a_legend.legends # get content
26+
a_legend.add_legend_element("el5","#000") # add a legend element
27+
a_legend.remove_legend_element("el5") # remove a legend element
28+
29+
30+
# legend position
31+
a_legend.positionning ="topright"
32+
a_legend.positionning # get current positionning
33+
34+
Attributes
35+
----------
36+
37+
================ ================ ===
38+
Attribute Default Value Doc
39+
================ ================ ===
40+
position 'topleft' Position of the control, can be 'bottomleft', 'bottomright', 'topleft', or 'topright'
41+
legend None a dictionnary that represents the legend
42+
title "Legend" LegendControl name
43+
================ ================ ===

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,4 @@ ipyleaflet: Interactive maps in the Jupyter notebook
5757
api_reference/split_map_control
5858
api_reference/draw_control
5959
api_reference/widget_control
60+
api_reference/legend_control

examples/LegendControl.ipynb

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Legend: How to use"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"## step 1: create an ipyleaflet map"
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": 104,
20+
"metadata": {},
21+
"outputs": [],
22+
"source": [
23+
"from ipyleaflet import Map, LegendControl"
24+
]
25+
},
26+
{
27+
"cell_type": "code",
28+
"execution_count": 105,
29+
"metadata": {},
30+
"outputs": [],
31+
"source": [
32+
"mymap = Map(center=(-10,-45), zoom=4)"
33+
]
34+
},
35+
{
36+
"cell_type": "code",
37+
"execution_count": 106,
38+
"metadata": {},
39+
"outputs": [
40+
{
41+
"data": {
42+
"application/vnd.jupyter.widget-view+json": {
43+
"model_id": "e3697c421ece40cd9508549298ad457a",
44+
"version_major": 2,
45+
"version_minor": 0
46+
},
47+
"text/plain": [
48+
"Map(center=[-10, -45], controls=(ZoomControl(options=['position', 'zoom_in_text', 'zoom_in_title', 'zoom_out_t…"
49+
]
50+
},
51+
"metadata": {},
52+
"output_type": "display_data"
53+
}
54+
],
55+
"source": [
56+
"mymap"
57+
]
58+
},
59+
{
60+
"cell_type": "markdown",
61+
"metadata": {},
62+
"source": [
63+
"## step 2: create a legend"
64+
]
65+
},
66+
{
67+
"cell_type": "markdown",
68+
"metadata": {},
69+
"source": [
70+
"By default, you need to provide at least a dictionnary with pair key=> the label to display and value=> the desired color. By default, it is named 'Legend', but you can pass a name as argument as well. "
71+
]
72+
},
73+
{
74+
"cell_type": "code",
75+
"execution_count": 107,
76+
"metadata": {},
77+
"outputs": [],
78+
"source": [
79+
"a_legend = LegendControl({\"low\":\"#FAA\", \"medium\":\"#A55\", \"High\":\"#500\"}, name=\"Legend\", position=\"bottomright\")"
80+
]
81+
},
82+
{
83+
"cell_type": "code",
84+
"execution_count": 108,
85+
"metadata": {},
86+
"outputs": [],
87+
"source": [
88+
"mymap.add_control(a_legend)"
89+
]
90+
},
91+
{
92+
"cell_type": "markdown",
93+
"metadata": {},
94+
"source": [
95+
"## Step 3: manipulate Legend"
96+
]
97+
},
98+
{
99+
"cell_type": "markdown",
100+
"metadata": {},
101+
"source": [
102+
"### Name"
103+
]
104+
},
105+
{
106+
"cell_type": "code",
107+
"execution_count": 109,
108+
"metadata": {},
109+
"outputs": [
110+
{
111+
"data": {
112+
"text/plain": [
113+
"'Risk'"
114+
]
115+
},
116+
"execution_count": 109,
117+
"metadata": {},
118+
"output_type": "execute_result"
119+
}
120+
],
121+
"source": [
122+
"a_legend.name = \"Risk\" ## set name\n",
123+
"a_legend.name # get name"
124+
]
125+
},
126+
{
127+
"cell_type": "markdown",
128+
"metadata": {},
129+
"source": [
130+
"### Legend content"
131+
]
132+
},
133+
{
134+
"cell_type": "code",
135+
"execution_count": 110,
136+
"metadata": {},
137+
"outputs": [],
138+
"source": [
139+
"a_legend.legends = {\"el1\":\"#FAA\", \"el2\":\"#A55\", \"el3\":\"#500\"} #set content\n",
140+
"a_legend.legends # get content\n",
141+
"\n",
142+
"a_legend.add_legend_element(\"el5\",\"#000\") # add a legend element"
143+
]
144+
},
145+
{
146+
"cell_type": "code",
147+
"execution_count": 111,
148+
"metadata": {},
149+
"outputs": [],
150+
"source": [
151+
"a_legend.remove_legend_element(\"el5\") # remove a legend element"
152+
]
153+
},
154+
{
155+
"cell_type": "markdown",
156+
"metadata": {},
157+
"source": [
158+
"### Positionning"
159+
]
160+
},
161+
{
162+
"cell_type": "code",
163+
"execution_count": 112,
164+
"metadata": {},
165+
"outputs": [
166+
{
167+
"data": {
168+
"text/plain": [
169+
"'topright'"
170+
]
171+
},
172+
"execution_count": 112,
173+
"metadata": {},
174+
"output_type": "execute_result"
175+
}
176+
],
177+
"source": [
178+
"a_legend.positionning =\"topright\" # set positionning : possible values are topleft, topright, bottomleft, bottomright\n",
179+
"a_legend.positionning # get current positionning"
180+
]
181+
},
182+
{
183+
"cell_type": "code",
184+
"execution_count": null,
185+
"metadata": {},
186+
"outputs": [],
187+
"source": []
188+
}
189+
],
190+
"metadata": {
191+
"kernelspec": {
192+
"display_name": "Python 3",
193+
"language": "python",
194+
"name": "python3"
195+
},
196+
"language_info": {
197+
"codemirror_mode": {
198+
"name": "ipython",
199+
"version": 3
200+
},
201+
"file_extension": ".py",
202+
"mimetype": "text/x-python",
203+
"name": "python",
204+
"nbconvert_exporter": "python",
205+
"pygments_lexer": "ipython3",
206+
"version": "3.6.9"
207+
}
208+
},
209+
"nbformat": 4,
210+
"nbformat_minor": 4
211+
}

ipyleaflet/leaflet.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,53 @@ class AttributionControl(Control):
915915
prefix = Unicode('Leaflet').tag(sync=True, o=True)
916916

917917

918+
class LegendControl(Control):
919+
_view_name = Unicode('LeafletLegendControlView').tag(sync=True)
920+
_model_name = Unicode('LeafletLegendControlModel').tag(sync=True)
921+
title = Unicode('Legend').tag(sync=True)
922+
legend = Dict(default_value={
923+
"value 1": "#AAF",
924+
"value 2": "#55A",
925+
"value 3": "#005"}).tag(sync=True)
926+
927+
def __init__(self, legend, *args, name="Legend", **kwargs):
928+
super().__init__(*args, **kwargs)
929+
self.title = name
930+
self.legend = legend
931+
932+
@property
933+
def name(self):
934+
return self.title
935+
936+
@name.setter
937+
def name(self, title):
938+
self.title = title
939+
940+
@property
941+
def legends(self):
942+
return self.legend
943+
944+
@legends.setter
945+
def legends(self, legends):
946+
self.legend = legends
947+
948+
@property
949+
def positionning(self):
950+
return self.position
951+
952+
@positionning.setter
953+
def positionning(self, position):
954+
self.position = position
955+
956+
def add_legend_element(self, key, value):
957+
self.legend[key] = value
958+
self.send_state()
959+
960+
def remove_legend_element(self, key):
961+
del self.legend[key]
962+
self.send_state()
963+
964+
918965
class MapStyle(Style, Widget):
919966
""" Map Style Widget """
920967
_model_name = Unicode('LeafletMapStyleModel').tag(sync=True)

js/src/controls/LegendControl.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
const L = require('../leaflet.js');
2+
const control = require('./Control.js')
3+
4+
5+
export class LeafletLegendControlModel extends control.LeafletControlModel {
6+
defaults(){
7+
return{
8+
...super.defaults(),
9+
_view_name : 'LeafletLegendControlView',
10+
_model_name : 'LeafletLegendControlModel',
11+
title: "Legend",
12+
legend{
13+
"value 1": "#AAF",
14+
"value 2": "#55A",
15+
"value 3": "#005"
16+
},
17+
position: 'bottomright'
18+
}
19+
}
20+
}
21+
22+
23+
export class LeafletLegendControlView extends control.LeafletControlView{
24+
25+
initialize(parameters){
26+
super.initialize(parameters);
27+
this.map_view = this.options.map_view;
28+
}
29+
30+
render(){
31+
this.create_obj()
32+
this.model.on('change:title', this.titleChanged, this);
33+
this.model.on('change:position', this.positionChanged, this);
34+
this.model.on('change:legend', this.legendChanged, this);
35+
}
36+
37+
create_obj(title, positionning, legend){
38+
let jsLegend = L.control({position: this.model.get('position')})
39+
40+
jsLegend.onAdd = (map) => {
41+
let jsLegendName="leaflet-control-legend"
42+
let container = L.DomUtil.create('div', jsLegendName)
43+
this.addContent(container)
44+
return container
45+
}
46+
47+
this.obj = jsLegend
48+
}
49+
50+
legendChanged(){
51+
let container = this.obj.getContainer()
52+
L.DomUtil.empty(container)
53+
this.addContent(container)
54+
55+
}
56+
57+
positionChanged(){
58+
this.obj.setPosition(this.model.get('position'))
59+
}
60+
61+
titleChanged(){
62+
let container = this.obj.getContainer()
63+
let titleContainer = container.getElementsByTagName('h4')[0]
64+
titleContainer.textContent = this.model.get('title')
65+
}
66+
67+
addContent(container){
68+
let titleContainer = document.createElement('h4')
69+
titleContainer.textContent = this.model.get('title')
70+
container.appendChild(titleContainer)
71+
let legend = this.model.get('legend')
72+
for ( let legendElement in legend ){
73+
let icon = document.createElement("i")
74+
icon.style = `background-color: ${legend[legendElement]}`
75+
container.appendChild(icon)
76+
container.innerHTML += `<p>${legendElement} </p></br>`
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)