-
Notifications
You must be signed in to change notification settings - Fork 10
/
mixin.legend.js
90 lines (86 loc) · 3.69 KB
/
mixin.legend.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import math from 'mathjs'
import L from 'leaflet'
import 'leaflet-legend/leaflet-legend.js'
import 'leaflet-legend/leaflet-legend.css'
import store from '../store'
// Add knot unit not defined by default
math.createUnit('knot', { definition: '0.514444 m/s', aliases: ['knots', 'kt', 'kts'] })
let legendMixin = {
methods: {
getLabelsForUnit (colorMap, units) {
let labels = ['<span style="text-align:center; width: 30px; height: 18px; float: left; margin-right: 8px; opacity: 0.7; background: white">' + units.from + '</span> ']
for (var i = 0; i < colorMap.length; i++) {
labels.push('<span style="text-align:center; width: 30px; height: 18px; float: left; margin-right: 8px; opacity: 0.7; background:' +
colorMap[i].color + '">' + math.unit(colorMap[i].value, units.base).toNumber(units.from).toFixed(0) + '</span> ')
}
return labels
},
getHtmlForUnit (colorMap, units) {
let labelsForUnit = this.getLabelsForUnit(colorMap, units)
if (units.from !== units.to) return '<div title="Click to convert to ' + units.to + '" style="position:absolute; cursor:pointer;">' + labelsForUnit.join('<br>') + '</div>'
else return '<div style="position:absolute; cursor:pointer;">' + labelsForUnit.join('<br>') + '</div>'
},
setLegendColorMap (legend, forecastLayer, colorMap) {
const units = forecastLayer.options.units
if (!units || (units.length === 0)) return
// Offset to avoid stacking multiple legends
let offsetHtml = '<div style="transform: translateX(' + legend.offset + 'px)">'
// The first unit is the base one
const base = units[0]
// Build legend/labels for each unit
let html = []
units.forEach((from, index) => {
let to = units[(index + 1) % units.length]
html.push(offsetHtml + this.getHtmlForUnit(colorMap, { base, from, to }) + '</div>')
})
let currentUnitIndex = 0
legend._container.innerHTML = html[currentUnitIndex]
legend._container.addEventListener('click', _ => {
currentUnitIndex = (currentUnitIndex + 1) % html.length
legend._container.innerHTML = html[currentUnitIndex]
})
},
showLegend (forecastLayer) {
let legend = this.legends[forecastLayer._leaflet_id]
legend.addTo(this.map)
let colorMap = forecastLayer.getColorMap()
// Nothing to display ?
if (colorMap.length === 0) {
this.hideLegend(forecastLayer)
} else {
this.setLegendColorMap(legend, forecastLayer, colorMap)
}
forecastLayer.off('data', legend.callback)
},
hideLegend (forecastLayer) {
let legend = this.legends[forecastLayer._leaflet_id]
delete this.legends[forecastLayer._leaflet_id]
legend.remove()
}
},
mounted () {
this.legends = {}
this.map.on('layeradd', event => {
const forecastLayer = event.layer
// We only manage forecast layers
if (forecastLayer instanceof L.Weacast.ForecastLayer) {
const count = Object.keys(this.legends).length
let legend = new L.Control.Legend({ position: 'topleft', collapsed: false })
legend.offset = count * 40
legend.callback = () => this.showLegend(forecastLayer)
this.legends[forecastLayer._leaflet_id] = legend
// We need to wait until data is here because it is require to get color map
if (forecastLayer.hasData) this.showLegend(forecastLayer)
else forecastLayer.on('data', legend.callback)
}
})
this.map.on('layerremove', event => {
const forecastLayer = event.layer
if (this.legends[forecastLayer._leaflet_id]) {
this.hideLegend(forecastLayer)
}
})
}
}
store.set('legend', legendMixin)
export default legendMixin