Commit 98f1d353 authored by Anne Blankert's avatar Anne Blankert

support quantile classification

parent fb6dab19
......@@ -13,6 +13,8 @@
flex-wrap: wrap;
}
#map {display: inline-block; width: 500px; height: 500px; border: 1 px solid lightblue;}
#legendcontainer {display: flex;}
#legend {min-width: 250px;}
#featurecontainer {
display: flex;
flex-direction: column;
......@@ -48,8 +50,8 @@
const attrType = urlParams.get("columntype");
const geomType = urlParams.get('geomtype');
const geomColumn = urlParams.get('geom_column');
document.querySelector('#tablename').innerHTML = `${fullTableName} ${geomColumn}`;
document.querySelector('#columnname').innerHTML = `${attrName} (${attrType})`;
document.querySelector('#tablename').innerHTML = `Layer: ${fullTableName}<br>Geometry: ${geomColumn}`;
document.querySelector('#columnname').innerHTML = `Attribute: ${attrName} (${attrType})`;
document.querySelector('#back').innerHTML = `<a href="tableinfo.html?table=${fullTableName}&geom_column=${geomColumn}">Back to layer info</a>`;
initMap();
......@@ -354,39 +356,94 @@
function classButton(classType) {
if (prepareLegend()) {
const classCount = document.querySelector('#classcount').value;
const classCount = Number(document.querySelector('#classcount').value);
if (classCount === 1) {
// special case, single classification
} else {
// classCount > 1
const layerType = map.getLayer('attrlayer').type;
const rowCount = globalStats.percentiles.reduce((result, percentile)=>result + percentile.count, 0);
let mapboxPaint;
switch(classType) {
case 'qualitative':
let classValues = globalStats.values.filter(value=>value.value !== null);
if (classValues.length > classCount) {
const needsSlice = classValues.length > classCount;
if (needsSlice) {
classValues = classValues.slice(0, classCount - 1);
const classValuesRowCount = classValues.reduce((result, value)=>result+value.count,0);
classValues.push({
value:"other",
count: rowCount - classValuesRowCount
})
}
const schemes = getColorSchemes(classCount, 'qual');
const mapboxPaint = [
mapboxPaint = [
"match",
["get",`${globalStats.column}`]
];
classValues.forEach((value, index) => {
addLegendLine(schemes[0].colors[index], value.value, layerType);
if (value.value !== 'other') {
if (index < classValues.length - 1 || !needsSlice) {
mapboxPaint.push(value.value);
mapboxPaint.push(schemes[0].colors[index]);
}
});
mapboxPaint.push(schemes[0].colors[classValues.length -1]);
break;
case 'quantile':
let percentileBreaks = globalStats.percentiles.reduce((result, percentile)=>{
percentile.pcount = 1;
if (result.length === 0) {
result.push(percentile);
return result;
}
if (result[result.length - 1].to === percentile.from) {
result[result.length - 1].to = percentile.to;
result[result.length - 1].count += percentile.count;
result[result.length - 1].pcount++;
return result;
}
result.push(percentile);
return result;
},[]);
const seqSchemes = getColorSchemes(classCount, 'qual');
if (classCount > percentileBreaks.length) {
classCount = percentileBreaks.length
} else {
let totalPCount = percentileBreaks.reduce((result, percentile)=>result+percentile.pcount, 0);
const pCountPerClass = totalPCount / classCount;
let sumPCount = 0;
let sumClassCount = 0
percentileBreaks = percentileBreaks.reduce((result, percentile)=>{
sumPCount += percentile.pcount;
if (sumPCount > sumClassCount * pCountPerClass) {
// new class
result.push(percentile);
sumClassCount++;
} else {
result[result.length - 1].to = percentile.to;
result[result.length - 1].count += percentile.count;
result[result.length - 1].pcount += percentile.pcount;
}
return result;
},[])
}
mapboxPaint = [
"case"
]
percentileBreaks.forEach((brk, index, arr)=>{
addLegendLine(seqSchemes[0].colors[index], `${brk.from} - ${brk.to}`, layerType);
mapboxPaint.push(["<",["get", globalStats.column],brk.to],seqSchemes[0].colors[index])
})
mapboxPaint.push(seqSchemes[0].colors[classCount - 1])
break;
}
const colorprop = `${layerType}-color`;
map.setPaintProperty('attrlayer', colorprop, mapboxPaint);
updateLayerJsonDisplay();
}
}
const nullValues = globalStats.values.filter(value=>value.value === null).reduce((result, value)=>result+value.count,0);
const checkButtonNullValues = document.querySelector('#hidenulls')
......@@ -417,6 +474,8 @@
<div id="map"></div>
<div id="featurecontainer">
<div id="legendcontainer">
<div id="legend"></div>
<div id="legendformcontainer">
<select id="classcount" name="classcount">
<option value="1" selected>1</option>
<option value="2">2</option>
......@@ -435,7 +494,7 @@
<button onclick="classButton('quantile')">quantile</button>
<button onclick="classButton('qualitative')">qualitative</button><br>
<input type="checkbox" id="hidenulls" name="hidenulls" checked><label for="hidenulls">Hide no-data</label>
<div id="legend"></div>
</div>
</div>
<div id="featureinfo"></div>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment