Choropleth: replace chromajs by colorbrewer + simple-statistics
simple-statistics has a few advantages: - faster - more accurate kmeans algo - Jenks-Fisher algo Also, I suspect will use it again for next step, which is Bubble mode layer.
This commit is contained in:
parent
e97e566c42
commit
739626351c
8 changed files with 86 additions and 62 deletions
|
@ -35,6 +35,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tmcw/togeojson": "^5.8.0",
|
"@tmcw/togeojson": "^5.8.0",
|
||||||
"chroma-js": "^2.4.2",
|
"chroma-js": "^2.4.2",
|
||||||
|
"colorbrewer": "^1.5.6",
|
||||||
"csv2geojson": "5.1.1",
|
"csv2geojson": "5.1.1",
|
||||||
"dompurify": "^3.0.3",
|
"dompurify": "^3.0.3",
|
||||||
"georsstogeojson": "^0.1.0",
|
"georsstogeojson": "^0.1.0",
|
||||||
|
@ -56,6 +57,7 @@
|
||||||
"leaflet.path.drag": "0.0.6",
|
"leaflet.path.drag": "0.0.6",
|
||||||
"leaflet.photon": "0.8.0",
|
"leaflet.photon": "0.8.0",
|
||||||
"osmtogeojson": "^3.0.0-beta.3",
|
"osmtogeojson": "^3.0.0-beta.3",
|
||||||
|
"simple-statistics": "^7.8.3",
|
||||||
"togpx": "^0.5.4",
|
"togpx": "^0.5.4",
|
||||||
"tokml": "0.4.0"
|
"tokml": "0.4.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ mkdir -p umap/static/umap/vendors/tokml && cp -r node_modules/tokml/tokml.js uma
|
||||||
mkdir -p umap/static/umap/vendors/locatecontrol/ && cp -r node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css umap/static/umap/vendors/locatecontrol/
|
mkdir -p umap/static/umap/vendors/locatecontrol/ && cp -r node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css umap/static/umap/vendors/locatecontrol/
|
||||||
mkdir -p umap/static/umap/vendors/locatecontrol/ && cp -r node_modules/leaflet.locatecontrol/src/L.Control.Locate.js umap/static/umap/vendors/locatecontrol/
|
mkdir -p umap/static/umap/vendors/locatecontrol/ && cp -r node_modules/leaflet.locatecontrol/src/L.Control.Locate.js umap/static/umap/vendors/locatecontrol/
|
||||||
mkdir -p umap/static/umap/vendors/dompurify/ && cp -r node_modules/dompurify/dist/purify.js umap/static/umap/vendors/dompurify/
|
mkdir -p umap/static/umap/vendors/dompurify/ && cp -r node_modules/dompurify/dist/purify.js umap/static/umap/vendors/dompurify/
|
||||||
mkdir -p umap/static/umap/vendors/chroma/ && cp -r node_modules/chroma-js/chroma.min.js umap/static/umap/vendors/chroma/
|
mkdir -p umap/static/umap/vendors/colorbrewer/ && cp node_modules/colorbrewer/index.js umap/static/umap/vendors/colorbrewer/colorbrewer.js
|
||||||
|
mkdir -p umap/static/umap/vendors/simple-statistics/ && cp node_modules/simple-statistics/dist/simple-statistics.min.js umap/static/umap/vendors/simple-statistics/
|
||||||
|
|
||||||
echo 'Done!'
|
echo 'Done!'
|
||||||
|
|
|
@ -117,6 +117,12 @@ L.U.Layer.Choropleth = L.FeatureGroup.extend({
|
||||||
fillOpacity: 0.7,
|
fillOpacity: 0.7,
|
||||||
weight: 2,
|
weight: 2,
|
||||||
},
|
},
|
||||||
|
MODES: {
|
||||||
|
kmeans: L._('K-means'),
|
||||||
|
equidistant: L._('Equidistant'),
|
||||||
|
jenks: L._('Jenks-Fisher'),
|
||||||
|
quantiles: L._('Quantiles'),
|
||||||
|
},
|
||||||
|
|
||||||
initialize: function (datalayer) {
|
initialize: function (datalayer) {
|
||||||
this.datalayer = datalayer
|
this.datalayer = datalayer
|
||||||
|
@ -132,7 +138,7 @@ L.U.Layer.Choropleth = L.FeatureGroup.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
redraw: function () {
|
redraw: function () {
|
||||||
this.computeLimits()
|
this.computeBreaks()
|
||||||
if (this._map) this.eachLayer(this._map.addLayer, this._map)
|
if (this._map) this.eachLayer(this._map.addLayer, this._map)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -141,26 +147,44 @@ L.U.Layer.Choropleth = L.FeatureGroup.extend({
|
||||||
return +feature.properties[key] // TODO: should we catch values non castable to int ?
|
return +feature.properties[key] // TODO: should we catch values non castable to int ?
|
||||||
},
|
},
|
||||||
|
|
||||||
computeLimits: function () {
|
computeBreaks: function () {
|
||||||
const values = []
|
const values = []
|
||||||
this.datalayer.eachLayer((layer) => values.push(this._getValue(layer)))
|
this.datalayer.eachLayer((layer) => {
|
||||||
this.options.limits = chroma.limits(
|
let value = this._getValue(layer)
|
||||||
values,
|
if (!isNaN(value)) values.push(value)
|
||||||
this.datalayer.options.choropleth.mode || 'q',
|
})
|
||||||
this.datalayer.options.choropleth.steps || 5
|
if (!values.length) {
|
||||||
)
|
this.options.breaks = []
|
||||||
|
this.options.colors = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let mode = this.datalayer.options.choropleth.mode,
|
||||||
|
steps = +this.datalayer.options.choropleth.steps || 5,
|
||||||
|
breaks
|
||||||
|
if (mode === 'equidistant') {
|
||||||
|
breaks = ss.equalIntervalBreaks(values, steps)
|
||||||
|
} else if (mode === 'jenks') {
|
||||||
|
breaks = ss.jenks(values, steps)
|
||||||
|
} else if (mode === 'quantiles') {
|
||||||
|
const quantiles = [...Array(steps)].map((e, i) => i/steps).concat(1)
|
||||||
|
breaks = ss.quantile(values, quantiles)
|
||||||
|
} else {
|
||||||
|
breaks = ss.ckmeans(values, steps).map((cluster) => cluster[0])
|
||||||
|
breaks.push(ss.max(values)) // Needed for computing the legend
|
||||||
|
}
|
||||||
|
this.options.breaks = breaks
|
||||||
const fillColor = this.datalayer.getOption('fillColor') || this.defaults.fillColor
|
const fillColor = this.datalayer.getOption('fillColor') || this.defaults.fillColor
|
||||||
this.options.colors = chroma
|
let colorScheme = this.datalayer.options.choropleth.brewer
|
||||||
.scale(this.datalayer.options.choropleth.brewer || ['#f7f7f7', fillColor])
|
if (!colorbrewer[colorScheme]) colorScheme = 'Blues'
|
||||||
.colors(this.options.limits.length - 1)
|
this.options.colors = colorbrewer[colorScheme][breaks.length - 1] || []
|
||||||
},
|
},
|
||||||
|
|
||||||
getColor: function (feature) {
|
getColor: function (feature) {
|
||||||
if (!feature) return // FIXME shold not happen
|
if (!feature) return // FIXME shold not happen
|
||||||
const featureValue = this._getValue(feature)
|
const featureValue = this._getValue(feature)
|
||||||
// Find the bucket/step/limit that this value is less than and give it that color
|
// Find the bucket/step/limit that this value is less than and give it that color
|
||||||
for (let i = 1; i < this.options.limits.length; i++) {
|
for (let i = 1; i < this.options.breaks.length; i++) {
|
||||||
if (featureValue <= this.options.limits[i]) {
|
if (featureValue <= this.options.breaks[i]) {
|
||||||
return this.options.colors[i - 1]
|
return this.options.colors[i - 1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,24 +196,22 @@ L.U.Layer.Choropleth = L.FeatureGroup.extend({
|
||||||
|
|
||||||
addLayer: function (layer) {
|
addLayer: function (layer) {
|
||||||
// Do not add yet the layer to the map
|
// Do not add yet the layer to the map
|
||||||
// wait for datachanged event, so we want compute limits once
|
// wait for datachanged event, so we want compute breaks once
|
||||||
var id = this.getLayerId(layer);
|
var id = this.getLayerId(layer)
|
||||||
this._layers[id] = layer;
|
this._layers[id] = layer
|
||||||
return this;
|
return this
|
||||||
},
|
},
|
||||||
|
|
||||||
onAdd: function (map) {
|
onAdd: function (map) {
|
||||||
this.computeLimits()
|
this.computeBreaks()
|
||||||
L.FeatureGroup.prototype.onAdd.call(this, map)
|
L.FeatureGroup.prototype.onAdd.call(this, map)
|
||||||
},
|
},
|
||||||
|
|
||||||
getEditableOptions: function () {
|
getEditableOptions: function () {
|
||||||
// chroma expose each palette both in title mode and in lowercase
|
const brewerSchemes = Object.keys(colorbrewer)
|
||||||
// TODO: PR to chroma to get a accessor to the palettes names list
|
.filter((k) => k !== 'schemeGroups')
|
||||||
const brewerPalettes = Object.keys(chroma.brewer)
|
|
||||||
.filter((s) => s[0] == s[0].toUpperCase())
|
|
||||||
.sort()
|
.sort()
|
||||||
.map((k) => [k, k])
|
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
'options.choropleth.property',
|
'options.choropleth.property',
|
||||||
|
@ -205,7 +227,7 @@ L.U.Layer.Choropleth = L.FeatureGroup.extend({
|
||||||
{
|
{
|
||||||
handler: 'Select',
|
handler: 'Select',
|
||||||
label: L._('Choropleth color palette'),
|
label: L._('Choropleth color palette'),
|
||||||
selectOptions: brewerPalettes,
|
selectOptions: brewerSchemes,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
@ -223,13 +245,8 @@ L.U.Layer.Choropleth = L.FeatureGroup.extend({
|
||||||
'options.choropleth.mode',
|
'options.choropleth.mode',
|
||||||
{
|
{
|
||||||
handler: 'MultiChoice',
|
handler: 'MultiChoice',
|
||||||
default: 'q',
|
default: 'kmeans',
|
||||||
choices: [
|
choices: Object.entries(this.MODES),
|
||||||
['q', L._('quantile')],
|
|
||||||
['e', L._('equidistant')],
|
|
||||||
['l', L._('logarithmic')],
|
|
||||||
['k', L._('k-mean')],
|
|
||||||
],
|
|
||||||
label: L._('Choropleth mode'),
|
label: L._('Choropleth mode'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -240,14 +257,14 @@ L.U.Layer.Choropleth = L.FeatureGroup.extend({
|
||||||
const parent = L.DomUtil.create('ul', '', container)
|
const parent = L.DomUtil.create('ul', '', container)
|
||||||
let li, color, label
|
let li, color, label
|
||||||
|
|
||||||
this.options.limits.slice(0, -1).forEach((limit, index) => {
|
this.options.breaks.slice(0, -1).forEach((limit, index) => {
|
||||||
li = L.DomUtil.create('li', '', parent)
|
li = L.DomUtil.create('li', '', parent)
|
||||||
color = L.DomUtil.create('span', 'datalayer-color', li)
|
color = L.DomUtil.create('span', 'datalayer-color', li)
|
||||||
color.style.backgroundColor = this.options.colors[index]
|
color.style.backgroundColor = this.options.colors[index]
|
||||||
label = L.DomUtil.create('span', '', li)
|
label = L.DomUtil.create('span', '', li)
|
||||||
label.textContent = `${+this.options.limits[index].toFixed(
|
label.textContent = `${+this.options.breaks[index].toFixed(
|
||||||
1
|
1
|
||||||
)} - ${+this.options.limits[index + 1].toFixed(1)}`
|
)} - ${+this.options.breaks[index + 1].toFixed(1)}`
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -216,26 +216,28 @@ describe('L.U.Choropleth', function () {
|
||||||
describe('#compute()', function () {
|
describe('#compute()', function () {
|
||||||
it('choropleth should compute default colors', function () {
|
it('choropleth should compute default colors', function () {
|
||||||
this.datalayer.resetLayer(true)
|
this.datalayer.resetLayer(true)
|
||||||
// Does not pass because chroma-js seems to have rounding issues
|
assert.deepEqual(
|
||||||
//assert.deepEqual(this.datalayer.layer.options.limits, [45, 438.6, 707.0, 3231.0, 4935.2, 9898])
|
this.datalayer.layer.options.breaks,
|
||||||
assert.equal(poly1._path.attributes.fill.value, '#ffffff')
|
[45, 673, 3829, 4900, 9898, 9898]
|
||||||
assert.equal(poly4._path.attributes.fill.value, '#ffbfbf')
|
)
|
||||||
assert.equal(poly9._path.attributes.fill.value, '#ff0000')
|
assert.equal(poly1._path.attributes.fill.value, '#eff3ff')
|
||||||
|
assert.equal(poly4._path.attributes.fill.value, '#bdd7e7')
|
||||||
|
assert.equal(poly9._path.attributes.fill.value, '#3182bd')
|
||||||
})
|
})
|
||||||
it('choropleth should compute brewer colors', function () {
|
it('can change brewer scheme', function () {
|
||||||
this.datalayer.options.choropleth.brewer = 'Blues'
|
this.datalayer.options.choropleth.brewer = 'Reds'
|
||||||
this.datalayer.resetLayer(true)
|
this.datalayer.resetLayer(true)
|
||||||
assert.equal(poly1._path.attributes.fill.value, '#f7fbff')
|
assert.equal(poly1._path.attributes.fill.value, '#fee5d9')
|
||||||
assert.equal(poly4._path.attributes.fill.value, '#c6dbef')
|
assert.equal(poly4._path.attributes.fill.value, '#fcae91')
|
||||||
assert.equal(poly9._path.attributes.fill.value, '#08306b')
|
assert.equal(poly9._path.attributes.fill.value, '#de2d26')
|
||||||
})
|
})
|
||||||
it('choropleth should allow to change steps', function () {
|
it('choropleth should allow to change steps', function () {
|
||||||
this.datalayer.options.choropleth.brewer = 'Blues'
|
this.datalayer.options.choropleth.brewer = 'Blues'
|
||||||
this.datalayer.options.choropleth.steps = 6
|
this.datalayer.options.choropleth.steps = 6
|
||||||
this.datalayer.resetLayer(true)
|
this.datalayer.resetLayer(true)
|
||||||
assert.equal(poly1._path.attributes.fill.value, '#f7fbff')
|
assert.equal(poly1._path.attributes.fill.value, '#eff3ff')
|
||||||
assert.equal(poly4._path.attributes.fill.value, '#94c4df')
|
assert.equal(poly4._path.attributes.fill.value, '#c6dbef')
|
||||||
assert.equal(poly9._path.attributes.fill.value, '#08306b')
|
assert.equal(poly9._path.attributes.fill.value, '#3182bd')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
<script src="../vendors/dompurify/purify.js"></script>
|
<script src="../vendors/dompurify/purify.js"></script>
|
||||||
<script src="../vendors/togpx/togpx.js"></script>
|
<script src="../vendors/togpx/togpx.js"></script>
|
||||||
<script src="../vendors/tokml/tokml.js"></script>
|
<script src="../vendors/tokml/tokml.js"></script>
|
||||||
<script src="../vendors/chroma/chroma.min.js"></script>
|
<script src="../vendors/simple-statistics/simple-statistics.min.js"></script>
|
||||||
|
<script src="../vendors/colorbrewer/colorbrewer.js"></script>
|
||||||
<script src="../js/umap.core.js"></script>
|
<script src="../js/umap.core.js"></script>
|
||||||
<script src="../js/umap.autocomplete.js"></script>
|
<script src="../js/umap.autocomplete.js"></script>
|
||||||
<script src="../js/umap.popup.js"></script>
|
<script src="../js/umap.popup.js"></script>
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
<script src="{{ STATIC_URL }}umap/vendors/tokml/tokml.js"></script>
|
<script src="{{ STATIC_URL }}umap/vendors/tokml/tokml.js"></script>
|
||||||
<script src="{{ STATIC_URL }}umap/vendors/locatecontrol/L.Control.Locate.js"></script>
|
<script src="{{ STATIC_URL }}umap/vendors/locatecontrol/L.Control.Locate.js"></script>
|
||||||
<script src="{{ STATIC_URL }}umap/vendors/dompurify/purify.js"></script>
|
<script src="{{ STATIC_URL }}umap/vendors/dompurify/purify.js"></script>
|
||||||
<script src="{{ STATIC_URL }}umap/vendors/chroma/chroma.min.js"></script>
|
<script src="{{ STATIC_URL }}umap/vendors/colorbrewer/colorbrewer.js"></script>
|
||||||
|
<script src="{{ STATIC_URL }}umap/vendors/simple-statistics/simple-statistics.min.js"></script>
|
||||||
{% endcompress %}
|
{% endcompress %}
|
||||||
{% if locale %}<script src="{{ STATIC_URL }}umap/locale/{{ locale }}.js"></script>{% endif %}
|
{% if locale %}<script src="{{ STATIC_URL }}umap/locale/{{ locale }}.js"></script>{% endif %}
|
||||||
{% compress js %}
|
{% compress js %}
|
||||||
|
|
|
@ -12,4 +12,4 @@
|
||||||
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[2.062908,44.976505],[2.09421,44.872012],[2.171637,44.790027],[2.169416,44.63807],[2.326791,44.669693],[2.435001,44.638875],[2.556123,44.721284],[2.602682,44.843163],[2.738258,44.941219],[2.849652,44.87149],[2.923267,44.728643],[2.998574,44.674443],[3.105495,44.886775],[3.182317,44.863735],[3.337942,44.955907],[3.412832,44.944842],[3.475771,44.815371],[3.740649,44.838697],[3.875462,44.740627],[3.905171,44.592709],[4.068445,44.405112],[4.051457,44.317322],[4.25885,44.264784],[4.336071,44.339519],[4.503539,44.340188],[4.649227,44.27036],[4.762255,44.325382],[4.81409,44.232315],[5.060561,44.308137],[5.1549,44.230941],[5.384527,44.201049],[5.454715,44.119226],[5.576192,44.188037],[5.686443,44.197158],[5.631598,44.328306],[5.49307,44.337174],[5.418533,44.424945],[5.597253,44.543274],[5.649631,44.617885],[5.790624,44.653293],[5.850394,44.750747],[6.136227,44.864072],[6.355363,44.854775],[6.318202,45.003859],[6.203923,45.012471],[6.229392,45.10875],[6.331295,45.118124],[6.393911,45.061818],[6.629992,45.109325],[6.767941,45.15974],[6.849855,45.127165],[6.968762,45.208058],[7.137593,45.255693],[7.110693,45.326509],[7.184271,45.407484],[7.000332,45.504414],[7.000692,45.6399],[6.829113,45.702831],[6.818078,45.834974],[6.939609,45.846733],[7.043891,45.922087],[7.018252,45.984185],[6.81473,46.129696],[6.864511,46.282986],[6.722865,46.40755],[6.545176,46.394725],[6.390033,46.340163],[6.279914,46.351093],[6.295651,46.226055],[6.126621,46.14046],[5.985317,46.143309],[5.971781,46.211519],[6.124246,46.251016],[6.169736,46.367935],[6.064006,46.416223],[5.908936,46.283951],[5.725182,46.260732],[5.649345,46.339495],[5.473052,46.265067],[5.310563,46.44677],[5.20114,46.508211],[5.052372,46.484874],[4.940022,46.517199],[4.780208,46.176676],[4.69311,46.302197],[4.618558,46.264794],[4.405814,46.296058],[4.389398,46.213601],[4.261025,46.178754],[4.104087,46.198391],[3.988788,46.169805],[3.890131,46.214487],[3.891239,46.285246],[3.986627,46.319196],[3.99804,46.465464],[3.890467,46.481246],[3.743289,46.567565],[3.696958,46.660583],[3.598001,46.723983],[3.215545,46.682893],[3.032063,46.794909],[2.959919,46.803872],[2.774489,46.718903],[2.70497,46.73939],[2.596648,46.637215],[2.614961,46.553276],[2.352004,46.512207],[2.281044,46.420404],[2.323023,46.329277],[2.478945,46.281146],[2.5598,46.173367],[2.59442,45.989441],[2.492228,45.86403],[2.388014,45.827373],[2.52836,45.681924],[2.465345,45.60082],[2.516327,45.553428],[2.487472,45.418842],[2.37825,45.414302],[2.350481,45.327561],[2.195364,45.220851],[2.171759,45.081497],[2.062908,44.976505]]]},"properties":{"code":"84","nom":"Auvergne-Rhône-Alpes","taux":"6.1"}},
|
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[2.062908,44.976505],[2.09421,44.872012],[2.171637,44.790027],[2.169416,44.63807],[2.326791,44.669693],[2.435001,44.638875],[2.556123,44.721284],[2.602682,44.843163],[2.738258,44.941219],[2.849652,44.87149],[2.923267,44.728643],[2.998574,44.674443],[3.105495,44.886775],[3.182317,44.863735],[3.337942,44.955907],[3.412832,44.944842],[3.475771,44.815371],[3.740649,44.838697],[3.875462,44.740627],[3.905171,44.592709],[4.068445,44.405112],[4.051457,44.317322],[4.25885,44.264784],[4.336071,44.339519],[4.503539,44.340188],[4.649227,44.27036],[4.762255,44.325382],[4.81409,44.232315],[5.060561,44.308137],[5.1549,44.230941],[5.384527,44.201049],[5.454715,44.119226],[5.576192,44.188037],[5.686443,44.197158],[5.631598,44.328306],[5.49307,44.337174],[5.418533,44.424945],[5.597253,44.543274],[5.649631,44.617885],[5.790624,44.653293],[5.850394,44.750747],[6.136227,44.864072],[6.355363,44.854775],[6.318202,45.003859],[6.203923,45.012471],[6.229392,45.10875],[6.331295,45.118124],[6.393911,45.061818],[6.629992,45.109325],[6.767941,45.15974],[6.849855,45.127165],[6.968762,45.208058],[7.137593,45.255693],[7.110693,45.326509],[7.184271,45.407484],[7.000332,45.504414],[7.000692,45.6399],[6.829113,45.702831],[6.818078,45.834974],[6.939609,45.846733],[7.043891,45.922087],[7.018252,45.984185],[6.81473,46.129696],[6.864511,46.282986],[6.722865,46.40755],[6.545176,46.394725],[6.390033,46.340163],[6.279914,46.351093],[6.295651,46.226055],[6.126621,46.14046],[5.985317,46.143309],[5.971781,46.211519],[6.124246,46.251016],[6.169736,46.367935],[6.064006,46.416223],[5.908936,46.283951],[5.725182,46.260732],[5.649345,46.339495],[5.473052,46.265067],[5.310563,46.44677],[5.20114,46.508211],[5.052372,46.484874],[4.940022,46.517199],[4.780208,46.176676],[4.69311,46.302197],[4.618558,46.264794],[4.405814,46.296058],[4.389398,46.213601],[4.261025,46.178754],[4.104087,46.198391],[3.988788,46.169805],[3.890131,46.214487],[3.891239,46.285246],[3.986627,46.319196],[3.99804,46.465464],[3.890467,46.481246],[3.743289,46.567565],[3.696958,46.660583],[3.598001,46.723983],[3.215545,46.682893],[3.032063,46.794909],[2.959919,46.803872],[2.774489,46.718903],[2.70497,46.73939],[2.596648,46.637215],[2.614961,46.553276],[2.352004,46.512207],[2.281044,46.420404],[2.323023,46.329277],[2.478945,46.281146],[2.5598,46.173367],[2.59442,45.989441],[2.492228,45.86403],[2.388014,45.827373],[2.52836,45.681924],[2.465345,45.60082],[2.516327,45.553428],[2.487472,45.418842],[2.37825,45.414302],[2.350481,45.327561],[2.195364,45.220851],[2.171759,45.081497],[2.062908,44.976505]]]},"properties":{"code":"84","nom":"Auvergne-Rhône-Alpes","taux":"6.1"}},
|
||||||
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[4.230281,43.460184],[4.554917,43.446213],[4.562798,43.372135],[4.855045,43.332619],[4.86685,43.404678],[4.96771,43.4261],[5.04104,43.327285],[5.36205,43.32196],[5.363649,43.207122],[5.53693,43.21449],[5.600895,43.162546],[5.812732,43.109367],[6.124052,43.079307],[6.387568,43.1449],[6.635535,43.172509],[6.665956,43.31822],[6.739809,43.412882],[6.917972,43.447739],[6.971833,43.545451],[7.040444,43.541583],[7.167666,43.657402],[7.320289,43.691329],[7.528519,43.790518],[7.495441,43.864356],[7.648598,43.97411],[7.716938,44.081763],[7.670853,44.153737],[7.426953,44.112875],[7.188913,44.197801],[7.008059,44.236435],[6.896505,44.374301],[6.854014,44.529125],[6.933509,44.575953],[6.987061,44.690138],[7.006773,44.839316],[6.859866,44.852903],[6.749751,44.907359],[6.740812,45.016733],[6.629992,45.109325],[6.393911,45.061818],[6.331295,45.118124],[6.229392,45.10875],[6.203923,45.012471],[6.318202,45.003859],[6.355363,44.854775],[6.136227,44.864072],[5.850394,44.750747],[5.790624,44.653293],[5.649631,44.617885],[5.597253,44.543274],[5.418533,44.424945],[5.49307,44.337174],[5.631598,44.328306],[5.686443,44.197158],[5.576192,44.188037],[5.454715,44.119226],[5.384527,44.201049],[5.1549,44.230941],[5.060561,44.308137],[4.81409,44.232315],[4.762255,44.325382],[4.649227,44.27036],[4.722071,44.187421],[4.70746,44.10367],[4.8421,43.986474],[4.690546,43.883899],[4.593035,43.68746],[4.487234,43.699241],[4.409353,43.561127],[4.230281,43.460184]]]},"properties":{"code":"93","nom":"Provence-Alpes-Côte d'Azur","taux":"7.8"}},
|
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[4.230281,43.460184],[4.554917,43.446213],[4.562798,43.372135],[4.855045,43.332619],[4.86685,43.404678],[4.96771,43.4261],[5.04104,43.327285],[5.36205,43.32196],[5.363649,43.207122],[5.53693,43.21449],[5.600895,43.162546],[5.812732,43.109367],[6.124052,43.079307],[6.387568,43.1449],[6.635535,43.172509],[6.665956,43.31822],[6.739809,43.412882],[6.917972,43.447739],[6.971833,43.545451],[7.040444,43.541583],[7.167666,43.657402],[7.320289,43.691329],[7.528519,43.790518],[7.495441,43.864356],[7.648598,43.97411],[7.716938,44.081763],[7.670853,44.153737],[7.426953,44.112875],[7.188913,44.197801],[7.008059,44.236435],[6.896505,44.374301],[6.854014,44.529125],[6.933509,44.575953],[6.987061,44.690138],[7.006773,44.839316],[6.859866,44.852903],[6.749751,44.907359],[6.740812,45.016733],[6.629992,45.109325],[6.393911,45.061818],[6.331295,45.118124],[6.229392,45.10875],[6.203923,45.012471],[6.318202,45.003859],[6.355363,44.854775],[6.136227,44.864072],[5.850394,44.750747],[5.790624,44.653293],[5.649631,44.617885],[5.597253,44.543274],[5.418533,44.424945],[5.49307,44.337174],[5.631598,44.328306],[5.686443,44.197158],[5.576192,44.188037],[5.454715,44.119226],[5.384527,44.201049],[5.1549,44.230941],[5.060561,44.308137],[4.81409,44.232315],[4.762255,44.325382],[4.649227,44.27036],[4.722071,44.187421],[4.70746,44.10367],[4.8421,43.986474],[4.690546,43.883899],[4.593035,43.68746],[4.487234,43.699241],[4.409353,43.561127],[4.230281,43.460184]]]},"properties":{"code":"93","nom":"Provence-Alpes-Côte d'Azur","taux":"7.8"}},
|
||||||
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[9.402271,41.858702],[9.412569,41.952476],[9.54998,42.104166],[9.558829,42.285265],[9.533196,42.545947],[9.449194,42.66224],[9.492385,42.8051],[9.463558,42.986401],[9.340873,42.994465],[9.311015,42.834679],[9.344478,42.73781],[9.085764,42.714609],[9.020694,42.644273],[8.886527,42.628966],[8.666509,42.515224],[8.674792,42.476243],[8.555885,42.36475],[8.689105,42.263528],[8.570341,42.230301],[8.590174,42.163885],[8.741329,42.040912],[8.5977,41.953238],[8.64145,41.909889],[8.803133,41.891381],[8.717242,41.722775],[8.914508,41.689724],[8.793077,41.629554],[8.788535,41.557736],[9.082201,41.441974],[9.219679,41.368212],[9.327205,41.616357],[9.387491,41.657359],[9.402271,41.858702]]]},"properties":{"code":"94","nom":"Corse","taux":"6.2"}}
|
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[9.402271,41.858702],[9.412569,41.952476],[9.54998,42.104166],[9.558829,42.285265],[9.533196,42.545947],[9.449194,42.66224],[9.492385,42.8051],[9.463558,42.986401],[9.340873,42.994465],[9.311015,42.834679],[9.344478,42.73781],[9.085764,42.714609],[9.020694,42.644273],[8.886527,42.628966],[8.666509,42.515224],[8.674792,42.476243],[8.555885,42.36475],[8.689105,42.263528],[8.570341,42.230301],[8.590174,42.163885],[8.741329,42.040912],[8.5977,41.953238],[8.64145,41.909889],[8.803133,41.891381],[8.717242,41.722775],[8.914508,41.689724],[8.793077,41.629554],[8.788535,41.557736],[9.082201,41.441974],[9.219679,41.368212],[9.327205,41.616357],[9.387491,41.657359],[9.402271,41.858702]]]},"properties":{"code":"94","nom":"Corse","taux":"6.2"}}
|
||||||
],"_umap_options": {"displayOnLoad": true,"browsable": true,"name": "Taux de chômage","labelKey": "{nom} ({taux})","type": "Choropleth","choropleth": {"property": "taux","steps": "5","brewer": "Blues"}}}
|
],"_umap_options": {"displayOnLoad": true,"browsable": true,"name": "Taux de chômage","labelKey": "{nom} ({taux})","type": "Choropleth","choropleth": {"property": "taux"}}}
|
||||||
|
|
|
@ -65,18 +65,18 @@ def test_basic_choropleth_map(map, live_server, page):
|
||||||
data = json.loads(path.read_text())
|
data = json.loads(path.read_text())
|
||||||
DataLayerFactory(data=data, map=map)
|
DataLayerFactory(data=data, map=map)
|
||||||
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
||||||
# Hauts-de-France, PACA, Occitanie
|
# Hauts-de-France
|
||||||
paths = page.locator("path[fill='#08306b']")
|
paths = page.locator("path[fill='#08519c']")
|
||||||
expect(paths).to_have_count(3)
|
|
||||||
# Normandie, Grand-Est, Centre-Val-de-Loire, IdF
|
|
||||||
paths = page.locator("path[fill='#2171b5']")
|
|
||||||
expect(paths).to_have_count(4)
|
|
||||||
# Bourgogne-Franceh-Comté
|
|
||||||
paths = page.locator("path[fill='#6baed6']")
|
|
||||||
expect(paths).to_have_count(1)
|
expect(paths).to_have_count(1)
|
||||||
# Corse, Nouvelle-Aquitaine
|
# Occitanie
|
||||||
paths = page.locator("path[fill='#c6dbef']")
|
paths = page.locator("path[fill='#3182bd']")
|
||||||
|
expect(paths).to_have_count(1)
|
||||||
|
# Grand-Est, PACA
|
||||||
|
paths = page.locator("path[fill='#6baed6']")
|
||||||
expect(paths).to_have_count(2)
|
expect(paths).to_have_count(2)
|
||||||
|
# Bourgogne-Franche-Comté, Centre-Val-de-Loire, IdF, Normandie, Corse, Nouvelle-Aquitaine
|
||||||
|
paths = page.locator("path[fill='#bdd7e7']")
|
||||||
|
expect(paths).to_have_count(6)
|
||||||
# Bretagne, Pays de la Loire, AURA
|
# Bretagne, Pays de la Loire, AURA
|
||||||
paths = page.locator("path[fill='#f7fbff']")
|
paths = page.locator("path[fill='#eff3ff']")
|
||||||
expect(paths).to_have_count(3)
|
expect(paths).to_have_count(3)
|
||||||
|
|
Loading…
Reference in a new issue