Replace omicron cutoff with generic percentile cutoff

main
xenofem 2022-12-30 12:30:05 -05:00
parent 8721de448e
commit bf278259e2
2 changed files with 20 additions and 38 deletions

View File

@ -51,8 +51,8 @@
<input id="endDate" type="date"> <input id="endDate" type="date">
</label> </label>
<label> <label>
Cut off Omicron spike? Cut off large spikes?
<input id="cutOmicron" type="checkbox"> <input id="cutSpikes" type="checkbox">
</label> </label>
</div> </div>
<div class="chart"> <div class="chart">

View File

@ -1,14 +1,14 @@
const startInput = document.getElementById('startDate'); const startInput = document.getElementById('startDate');
const endInput = document.getElementById('endDate'); const endInput = document.getElementById('endDate');
const cutOmicronInput = document.getElementById('cutOmicron'); const cutSpikesInput = document.getElementById('cutSpikes');
const hashParams = new URLSearchParams(window.location.hash.substring(1)); const hashParams = new URLSearchParams(window.location.hash.substring(1));
startInput.value = hashParams.get('start'); startInput.value = hashParams.get('start');
endInput.value = hashParams.get('end'); endInput.value = hashParams.get('end');
cutOmicronInput.checked = hashParams.get('cutOmicron') === 'true'; cutSpikesInput.checked = hashParams.get('cutSpikes') === 'true';
const OMICRON_START_DATE = '2021-11-01'; const SPIKE_PERCENTILE = 95;
const OMICRON_END_DATE = '2022-02-31'; const Y_ROUNDING = 500;
fetch('/data.json') fetch('/data.json')
.then(resp => resp.json()) .then(resp => resp.json())
@ -113,24 +113,12 @@ function extractWithErrorBars(data, region) {
return extracted; return extracted;
} }
function maxExcludingOmicron(data, start, end) { function getPercentile(data, start, end, percentile) {
let max = 0; let sorted = data
let secondMax = 0; .filter((row) => (start === "" || row.x >= start) && (end === "" || row.x <= end))
for (const row of data) { .map((row) => row.yMax)
if ( .sort((a,b) => a - b);
(start !== "" && row.x < start) return sorted[Math.ceil(sorted.length*percentile/100) - 1];
|| (end != "" && row.x > end)
|| (OMICRON_START_DATE < row.x && row.x < OMICRON_END_DATE)
) {
continue;
}
if (row.yMax > max) {
secondMax = max;
max = row.yMax;
}
}
// To exclude single weird outliers
return secondMax;
} }
function updateShareLink(chart, link) { function updateShareLink(chart, link) {
@ -191,17 +179,11 @@ function plot(data) {
const southOptions = getOptions("South"); const southOptions = getOptions("South");
const updateYMax = () => { const updateYMax = () => {
if ( const cutoffPercentile = cutSpikesInput.checked ? SPIKE_PERCENTILE : 100;
cutOmicronInput.checked const rawMax = getPercentile(northData.concat(southData), startInput.value, endInput.value, cutoffPercentile);
&& (startInput.value === "" || startInput.value < OMICRON_END_DATE) const max = Y_ROUNDING * Math.ceil(rawMax / Y_ROUNDING);
&& (endInput.value === "" || endInput.value > OMICRON_START_DATE) northOptions.scales.y.max = max;
) { southOptions.scales.y.max = max;
northOptions.scales.y.max = maxExcludingOmicron(northData, startInput.value, endInput.value);
southOptions.scales.y.max = maxExcludingOmicron(southData, startInput.value, endInput.value);
} else {
northOptions.scales.y.max = null;
southOptions.scales.y.max = null;
}
}; };
updateYMax(); updateYMax();
@ -321,8 +303,8 @@ function plot(data) {
if (end !== '') { if (end !== '') {
params.set('end', end); params.set('end', end);
} }
if (cutOmicronInput.checked) { if (cutSpikesInput.checked) {
params.set('cutOmicron', 'true'); params.set('cutSpikes', 'true');
} }
window.location.hash = params.toString(); window.location.hash = params.toString();
}; };
@ -337,7 +319,7 @@ function plot(data) {
southOptions.scales.x.max = e.target.value; southOptions.scales.x.max = e.target.value;
update(); update();
}); });
cutOmicronInput.addEventListener('change', (e) => { cutSpikesInput.addEventListener('change', (e) => {
update(); update();
}); });
const northShare = document.getElementById('northShare'); const northShare = document.getElementById('northShare');