Skip to content

Instantly share code, notes, and snippets.

@manuelep
Last active August 30, 2021 16:08
Show Gist options
  • Save manuelep/91b17facbc277f2593162b3f3c32aa81 to your computer and use it in GitHub Desktop.
Save manuelep/91b17facbc277f2593162b3f3c32aa81 to your computer and use it in GitHub Desktop.
Leaflet.colorLegend
.legend-item {
/* padding: 6px 8px; */
font: 18px/20px Arial, Helvetica, sans-serif;
/* background: white; */
/* background: rgba(255,255,255,0.5); */
/* box-shadow: 0 0 15px rgba(0,0,0,0.2); */
border-radius: 10px;
margin: .5em .5em .5em .5em;
}
.legend-item h4 {
/* margin: 0 0 .5em; */
color: #777;
/* display: block; */
font-weight: bold;
padding-left: .75em;
padding-right: .75em;
}
.flex {
display: flex;
align-items: center;
}
.flex.vertical {
flex-direction: column;
}
.label-icon {
display: flex;
justify-content: center;
}
.ring {
width: 1.5em;
height: 1.5em;
}
.legend-item > .start-label {
margin-right: .3em;
}
.legend-item.vertical > .start-label {
margin-bottom: .3em;
margin-right: 0;
}
.legend-item > .end-label {
margin-left: .3em;
}
.legend-item.vertical > .end-label {
margin-top: .3em;
margin-left: 0;
}
.legend-item > .ring-wrapper span + i {
margin-top: .3em;
}
.legend-item.vertical > .ring-wrapper span + i {
margin-left: .3em;
}
/** Courtesy of: https://leafletjs.com/examples/choropleth/ */
var DEFAULTGRADES = [0, 1/4, 1/2, 3/4, 1]
var DEFAULTINFO = [
{label: document.createTextNode('E')},
{label: document.createTextNode('D')},
{label: document.createTextNode('C')},
{label: document.createTextNode('B')},
{label: document.createTextNode('A')}
]
var DEFAULTINFO2 = [
{label: document.createTextNode('-')},
{label: document.createTextNode('+')}
]
L.Control.ColorLegend = L.Control.extend({
onAdd: function (map) {
var self = this;
this.colorize = ()=>{};
let main = document.createElement('div');
L.DomEvent.disableClickPropagation(main);
main.classList.add('leaflet-control-layers');
main.classList.add('leaflet-control');
main.classList.add('leaflet-control-layers-expanded');
main.setAttribute('legend', "");
if ( this.customClass ) main.classList.add(this.customClass);
main.setAttribute('aria-haspopup', 'true');
main.classList.add('flex');
let label = document.createElement('div');
label.setAttribute('legend-item', '');
label.classList.add('flex');
label.classList.add('legend-item');
if ( this.vertical ) label.classList.add('vertical');
let legend = document.createElement('div');
legend.setAttribute('legend-item', '');
legend.classList.add('flex');
legend.classList.add('legend-item');
if ( this.vertical ) legend.classList.add('vertical');
main.appendChild(label);
main.appendChild(legend);
let icon = document.createElement('div');
icon.setAttribute('icon', '');
icon.classList.add('label-icon');
let title = document.createElement('h4');
title.setAttribute('title', '');
label.appendChild(icon);
label.appendChild(title);
this.updateIcon = function () {
if ( self.icon ) {
icon.innerHTML=self.icon.outerHTML;
};
};
this.updateTitle = function () {
if ( self.title ) {
let wrap = document.createElement('span');
wrap.appendChild(self.title)
title.innerHTML=wrap.innerHTML;
};
};
let gradeKeys = [...Array(self.grades.length).keys()];
let infos = [...self.info];
if ( this.reverse ) {
gradeKeys.reverse();
infos.reverse();
};
if (infos.length==2) {
const rs = document.createElement('span');
rs.classList.add('flex');
rs.classList.add('start-label');
if ( infos[0].icon ) {
const rls = document.createElement('span');
rls.appendChild(infos[0].icon);
if ( !this.vertical ) rls.setAttribute('style', 'order: 1;')
rs.appendChild(rls);
};
if ( infos[0].label ) {
const ris = document.createElement('span');
ris.appendChild(infos[0].label);
rs.appendChild(ris);
};
legend.appendChild(rs)
};
gradeKeys.forEach(function (i) {
let ringContainer = document.createElement('span');
ringContainer.setAttribute('ringContainer', '');
ringContainer.classList.add('flex');
ringContainer.classList.add('ring-wrapper');
if ( !self.vertical ) ringContainer.classList.add('vertical');
let ring = document.createElement('span');
ring.classList.add('ring');
ringContainer.appendChild(ring);
if (self.info.length==gradeKeys.length) {
if ( self.info[i].icon ) {
ringContainer.appendChild(self.info[i].icon);
};
if ( self.info[i].label ) {
ringContainer.appendChild(self.info[i].label);
};
};
legend.appendChild(ringContainer);
});
if (infos.length==2) {
const re = document.createElement('span');
re.classList.add('flex');
re.classList.add('end-label');
if ( infos[1].icon ) {
const rle = document.createElement('span');
rle.appendChild(infos[1].icon);
re.appendChild(rle);
};
if ( infos[1].label ) {
const rie = document.createElement('span');
if ( !this.vertical ) rie.setAttribute('style', 'order: 1;')
rie.appendChild(infos[1].label);
re.appendChild(rie);
};
legend.appendChild(re)
};
self.colorize = function () {
let i = 0
divs = [...legend.getElementsByClassName("ring")]
if ( self.reverse ) { divs.reverse() };
for (let el of divs) {
el.setAttribute('style', `background: ${self.getColor(self.grades[i])}`);
i+=1;
};
};
self.colorize();
this.updateTitle();
this.updateIcon();
return main;
},
onRemove: function(map) {
// Nothing to do here
},
vfill: function (scale, gradeKeys, infos) {
var self = this;
},
hfill: function (scale, gradeKeys, infos) {
var self = this;
}
});
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
Array(6).forEach()
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
L.control.colorlegend = function(colorfunc, gradeopts, opts, reverse=true, vertical=true) {
/**
* colorfunc (function) : Color function;
* gradeopts (object) : Grades options; an object with theese keys:
* - grades (array(int)) : List of values to pass to the color function (default: [0, 1/4, .5, 3/4, 1]);
* - infos (array(object)) : An object with theese keys:
* - icon (DOM element) :
* - label (text) :
* opts (object) : Control options.
* reverse (boolean) : If grades must be considered in reverse order.
* horizontal (booolean) : If grades must be bisplaced horizontally.
*/
let ctrl = new L.Control.ColorLegend(opts);
ctrl.reverse = reverse;
ctrl.vertical = vertical;
ctrl.setColorFunc = (func)=>{ctrl.getColor=func};
ctrl.setTitle = (stuff)=>{ctrl.title=stuff};
ctrl.setTitle(gradeopts&&gradeopts.title);
ctrl.setIcon = (stuff)=>{ctrl.icon=stuff};
ctrl.setIcon(gradeopts&&gradeopts.icon);
ctrl.customClass = gradeopts&&gradeopts.customClass;
ctrl.setColorFunc(colorfunc ? colorfunc : (u) => '#'+Math.random().toString(16).substr(2,6));
ctrl.grades = gradeopts ? gradeopts.grades : DEFAULTGRADES;
ctrl.info = gradeopts ? gradeopts.info : DEFAULTINFO;
return ctrl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment