mirror of
https://github.com/umap-project/umap.git
synced 2025-04-29 11:52:38 +02:00
wip: add minimal legend for circles layer
This commit is contained in:
parent
cbb022f804
commit
930463032b
2 changed files with 54 additions and 10 deletions
|
@ -263,28 +263,33 @@ export const Circles = FeatureGroup.extend({
|
||||||
_getValue: function (feature) {
|
_getValue: function (feature) {
|
||||||
const key = this.datalayer.options.circles.property || 'value'
|
const key = this.datalayer.options.circles.property || 'value'
|
||||||
const value = +feature.properties[key]
|
const value = +feature.properties[key]
|
||||||
if (!Number.isNaN(value)) return Math.sqrt(value)
|
if (!Number.isNaN(value)) return value
|
||||||
},
|
},
|
||||||
|
|
||||||
compute: function () {
|
compute: function () {
|
||||||
const values = this.getValues()
|
const values = this.getValues()
|
||||||
this.options.minValue = Math.min(...values)
|
this.options.minValue = Math.sqrt(Math.min(...values))
|
||||||
this.options.maxValue = Math.max(...values)
|
this.options.maxValue = Math.sqrt(Math.max(...values))
|
||||||
|
this.options.minPX = this.datalayer.options.circles.radius?.min || 2
|
||||||
|
this.options.maxPX = this.datalayer.options.circles.radius?.max || 50
|
||||||
},
|
},
|
||||||
|
|
||||||
onEdit: function (field, builder) {
|
onEdit: function (field, builder) {
|
||||||
this.compute()
|
this.compute()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_computeRadius: function (value) {
|
||||||
|
const valuesRange = this.options.maxValue - this.options.minValue
|
||||||
|
const pxRange = this.options.maxPX - this.options.minPX
|
||||||
|
const radius =
|
||||||
|
this.options.minPX +
|
||||||
|
((Math.sqrt(value) - this.options.minValue) / valuesRange) * pxRange
|
||||||
|
return radius || this.options.minPX
|
||||||
|
},
|
||||||
|
|
||||||
_getOption: function (feature) {
|
_getOption: function (feature) {
|
||||||
if (!feature) return // FIXME should not happen
|
if (!feature) return // FIXME should not happen
|
||||||
const current = this._getValue(feature)
|
return this._computeRadius(this._getValue(feature))
|
||||||
const minPX = this.datalayer.options.circles.radius?.min || 2
|
|
||||||
const maxPX = this.datalayer.options.circles.radius?.max || 50
|
|
||||||
const valuesRange = this.options.maxValue - this.options.minValue
|
|
||||||
const pxRange = maxPX - minPX
|
|
||||||
const radius = minPX + ((current - this.options.minValue) / valuesRange) * pxRange
|
|
||||||
return radius || minPX
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getEditableOptions: function () {
|
getEditableOptions: function () {
|
||||||
|
@ -323,6 +328,32 @@ export const Circles = FeatureGroup.extend({
|
||||||
getStyleProperty: (feature) => {
|
getStyleProperty: (feature) => {
|
||||||
return 'radius'
|
return 'radius'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderLegend: function (container) {
|
||||||
|
const parent = DomUtil.create('ul', 'circles-layer-legend', container)
|
||||||
|
const color = this.datalayer.getOption('color')
|
||||||
|
const values = this.getValues()
|
||||||
|
if (!values.length) return
|
||||||
|
values.sort((a, b) => a - b)
|
||||||
|
const minValue = values[0]
|
||||||
|
const maxValue = values[values.length - 1]
|
||||||
|
const medianValue = values[Math.round(values.length / 2)]
|
||||||
|
const items = [
|
||||||
|
[this.options.minPX, minValue],
|
||||||
|
[this._computeRadius(medianValue), medianValue],
|
||||||
|
[this.options.maxPX, maxValue],
|
||||||
|
]
|
||||||
|
for (const [size, label] of items) {
|
||||||
|
const li = DomUtil.create('li', '', parent)
|
||||||
|
const circleEl = DomUtil.create('span', 'circle', li)
|
||||||
|
circleEl.style.backgroundColor = color
|
||||||
|
circleEl.style.height = `${size * 2}px`
|
||||||
|
circleEl.style.width = `${size * 2}px`
|
||||||
|
circleEl.style.opacity = this.datalayer.getOption('opacity')
|
||||||
|
const labelEl = DomUtil.create('span', 'label', li)
|
||||||
|
labelEl.textContent = label
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const Categorized = FeatureGroup.extend({
|
export const Categorized = FeatureGroup.extend({
|
||||||
|
|
|
@ -994,6 +994,19 @@ a.umap-control-caption,
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
.datalayer-legend .circles-layer-legend {
|
||||||
|
padding: var(--box-padding);
|
||||||
|
}
|
||||||
|
.circles-layer-legend li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.circles-layer-legend li .circle {
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
/* ********************************* */
|
/* ********************************* */
|
||||||
/* Popup */
|
/* Popup */
|
||||||
|
|
Loading…
Reference in a new issue