Merge branch 'main' into pages

This commit is contained in:
frankknoll
2022-03-15 12:00:58 +01:00
5 changed files with 594 additions and 441 deletions

113
docs/FreeBedsChartView.js Normal file
View File

@@ -0,0 +1,113 @@
class FreeBedsChartView {
#canvas;
#chart;
constructor(canvas) {
this.#canvas = canvas;
}
displayChart({ data, title }) {
if (this.#chart != null) {
this.#chart.destroy();
}
this.#chart = new Chart(
this.#canvas,
{
type: 'line',
data: this.#getData(data),
options: this.#getOptions(title),
plugins: [this.#getBackgroundTrafficLightsPlugin()]
});
}
#getBackgroundTrafficLightsPlugin() {
function fillRect({ chart, startInPercent, endInPercent, color }) {
const ctx = chart.ctx;
const chartArea = chart.chartArea;
const chartWidth = chartArea.right - chartArea.left;
const chartHeight = chartArea.bottom - chartArea.top
const y = chartArea.bottom - chartHeight * endInPercent / 100;
const height = chartHeight * (endInPercent - startInPercent) / 100;
ctx.fillStyle = color;
ctx.fillRect(chartArea.left, y, chartWidth, height);
}
function drawTrafficLights(chart) {
const RED = 'rgba(240, 59, 32, 0.75)';
const YELLOW = 'rgba(254, 178, 76, 0.75)';
const GREEN = 'rgba(56, 168, 0, 0.75)';
chart.ctx.save();
fillRect({ chart: chart, startInPercent: 0, endInPercent: 10, color: RED });
fillRect({ chart: chart, startInPercent: 10, endInPercent: 25, color: YELLOW });
fillRect({ chart: chart, startInPercent: 25, endInPercent: 100, color: GREEN });
chart.ctx.restore();
}
return { beforeDraw: drawTrafficLights };
}
#getData(data) {
return {
datasets: [
{
label: 'Anteil freier Betten',
data: data,
parsing: {
yAxisKey: 'free_beds_divided_by_all_beds_in_percent'
},
backgroundColor: 'rgba(0, 0, 150, 1)'
}
]
};
}
#getOptions(title) {
return {
plugins: {
title: {
display: true,
text: title
},
tooltip: {
callbacks: {
label: function (context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += context.parsed.y.toFixed(1) + "%";
}
return label;
}
}
}
},
responsive: true,
scales: {
x: {
type: 'time',
time: {
unit: 'month'
}
},
y: {
min: 0,
max: 100,
title: {
display: true,
text: "Anteil freier Betten"
},
ticks: {
callback: value => value + "%"
}
}
},
parsing: {
xAxisKey: 'date'
}
};
}
}

View File

@@ -29,7 +29,7 @@ class IntensiveCareCapacitiesChartView {
parsing: { parsing: {
yAxisKey: 'betten_belegt' yAxisKey: 'betten_belegt'
}, },
backgroundColor: 'rgba(255, 0, 0, 1)', backgroundColor: 'rgba(255, 0, 0, 1)'
}, },
{ {
label: 'Freie Betten', label: 'Freie Betten',
@@ -37,7 +37,7 @@ class IntensiveCareCapacitiesChartView {
parsing: { parsing: {
yAxisKey: 'betten_frei' yAxisKey: 'betten_frei'
}, },
backgroundColor: 'rgba(0, 255, 0, 1)', backgroundColor: 'rgba(0, 255, 0, 1)'
} }
] ]
}; };

View File

@@ -12,4 +12,8 @@ class UIUtils {
canvas: chartViewElement.querySelector(".canvas") canvas: chartViewElement.querySelector(".canvas")
}; };
} }
static getSelectedOption(selectElement) {
return selectElement.options[selectElement.selectedIndex];
}
} }

View File

@@ -1,25 +1,33 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1.0" name="viewport" /> <meta content="width=device-width, initial-scale=1.0" name="viewport" />
<title>DIVI-Intensivregister auf Landkreisebene</title> <title>DIVI-Intensivregister auf Landkreisebene 2020 bis heute</title>
<link href="forkMeOnGitHub.css" rel="stylesheet" type="text/css" /> <link href="forkMeOnGitHub.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.jsdelivr.net/npm/chart.js@^3"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js@^3"></script>
<script src="https://cdn.jsdelivr.net/npm/moment@^2"></script> <script src="https://cdn.jsdelivr.net/npm/moment@^2"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@^1"></script> <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@^1"></script>
<script src="./UIUtils.js"></script> <script src="./UIUtils.js"></script>
<script src="./IntensiveCareCapacitiesChartView.js"></script> <script src="./IntensiveCareCapacitiesChartView.js"></script>
<script src="./FreeBedsChartView.js"></script>
<script src="./intensivstationen.js"></script> <script src="./intensivstationen.js"></script>
<script> <script>
document.addEventListener( document.addEventListener(
"DOMContentLoaded", "DOMContentLoaded",
event => { event => {
const intensiveCareCapacitiesChartView = new IntensiveCareCapacitiesChartView(document.querySelector(".canvas")); const intensiveCareCapacitiesChartView = new IntensiveCareCapacitiesChartView(document.getElementById("intensiveCareCapacities"));
document.querySelector('#kreisSelect').addEventListener( const freeBedsChartView = new FreeBedsChartView(document.getElementById('freeBeds'));
const kreisSelect = document.querySelector('#kreisSelect');
onKreisOptionSelected(kreisSelect, intensiveCareCapacitiesChartView, freeBedsChartView);
kreisSelect.addEventListener(
'change', 'change',
event => { event => onKreisOptionSelected(kreisSelect, intensiveCareCapacitiesChartView, freeBedsChartView));
const selectedOption = getSelectedOption(event.target); });
function onKreisOptionSelected(kreisSelect, intensiveCareCapacitiesChartView, freeBedsChartView) {
const selectedOption = UIUtils.getSelectedOption(kreisSelect);
displayIntensiveCareCapacitiesChart( displayIntensiveCareCapacitiesChart(
{ {
intensiveCareCapacitiesChartView: intensiveCareCapacitiesChartView, intensiveCareCapacitiesChartView: intensiveCareCapacitiesChartView,
@@ -28,25 +36,19 @@
kreisText: selectedOption.text, kreisText: selectedOption.text,
kreisValue: selectedOption.value kreisValue: selectedOption.value
}); });
}); displayFreeBedsChart(
displayIntensiveCareCapacitiesChart(
{ {
intensiveCareCapacitiesChartView: intensiveCareCapacitiesChartView, freeBedsChartView: freeBedsChartView,
headingElement: document.querySelector(".heading"), kreisText: selectedOption.text,
populationElement: document.querySelector(".population"), kreisValue: selectedOption.value
kreisText: 'Alle Landkreise',
kreisValue: 'de'
}); });
});
function getSelectedOption(select) {
return select.options[select.selectedIndex];
} }
</script> </script>
</head> </head>
<body> <body>
<span id="forkongithub"><a href="https://github.com/KnollFrank/HowBadIsMyBatch">Fork me on GitHub</a></span> <span id="forkongithub"><a href="https://github.com/KnollFrank/HowBadIsMyBatch">Fork me on GitHub</a></span>
<h1>DIVI-Intensivregister auf Landkreisebene</h1> <h1>DIVI-Intensivregister auf Landkreisebene 2020 bis heute</h1>
<label>Landkreis:</label> <label>Landkreis:</label>
<select id="kreisSelect" name="kreis"> <select id="kreisSelect" name="kreis">
<option selected="" value="de">Alle Landkreise</option> <option selected="" value="de">Alle Landkreise</option>
@@ -435,10 +437,11 @@
<option value="Zweibrücken, kreisfreie Stadt">Zweibrücken, kreisfreie Stadt</option> <option value="Zweibrücken, kreisfreie Stadt">Zweibrücken, kreisfreie Stadt</option>
<option value="Zwickau">Zwickau</option> <option value="Zwickau">Zwickau</option>
</select> </select>
<h2 class="heading"></h2> <h2>Freie und belegte Intensivbetten</h2>
<h3 class="heading"></h3>
Einwohnerzahl: <span class="population"></span> Einwohnerzahl: <span class="population"></span>
<p> <p>
<canvas class="canvas"></canvas> <canvas id="intensiveCareCapacities"></canvas>
</p> </p>
<dl> <dl>
<dt>Belegte Betten:</dt> <dt>Belegte Betten:</dt>
@@ -447,10 +450,22 @@
<dt>Freie Betten:</dt> <dt>Freie Betten:</dt>
<dd>Anzahl der freien, betreibbaren Intensivbetten (Low- und High-Care) für Erwachsene und Kinder zur <dd>Anzahl der freien, betreibbaren Intensivbetten (Low- und High-Care) für Erwachsene und Kinder zur
Behandlung von allen intensivpflichtigen Erkrankungen.</dd> Behandlung von allen intensivpflichtigen Erkrankungen.</dd>
</dl>
<h2>Anteil der freien Betten an der Gesamtzahl der Intensivbetten</h2>
<p>
<canvas id="freeBeds"></canvas>
</p>
<dl>
<dt>Datensatz:</dt> <dt>Datensatz:</dt>
<dd><a href="https://www.intensivregister.de/#/aktuelle-lage/downloads" target="_blank">Landkreis-Daten</a></dd> <dd><a href="https://www.intensivregister.de/#/aktuelle-lage/downloads" target="_blank">Landkreis-Daten</a></dd>
<dt>siehe auch:</dt>
<dd><a href="https://experience.arcgis.com/experience/3a132983ad3c4ab8a28704e9addefaba" target="_blank">Dashboard
DIVI-Intensivregister auf Landkreisebene</a></dd>
<dd><a href="https://www.intensivregister.de/#/aktuelle-lage/kartenansichten" target="_blank">Kartenansichten</a>
</dd>
<dt>Datenstand:</dt> <dt>Datenstand:</dt>
<dd id="Datenstand">14.03.2022, 12:38 Uhr</dd> <dd id="Datenstand">12.03.2022, 12:38 Uhr</dd>
</dl> </dl>
</body> </body>
</html> </html>

View File

@@ -9,3 +9,24 @@ function displayIntensiveCareCapacitiesChart(
intensiveCareCapacitiesChartView.displayChart({ data: json.data, title: kreisText }); intensiveCareCapacitiesChartView.displayChart({ data: json.data, title: kreisText });
}); });
} }
function displayFreeBedsChart({ freeBedsChartView, kreisText, kreisValue }) {
fetch(`data/intensivstationen/intensivstationen-${kreisValue}.json`)
.then(response => response.json())
.then(json =>
freeBedsChartView.displayChart(
{
data: get_free_beds_divided_by_all_beds_in_percent(json.data),
title: kreisText
}));
}
function get_free_beds_divided_by_all_beds_in_percent(data) {
return data.map(({ date, betten_frei, betten_belegt }) =>
(
{
"date": date,
"free_beds_divided_by_all_beds_in_percent": betten_frei / (betten_frei + betten_belegt) * 100
}
));
}