radiacode_docker_usb/webserver.html
2023-07-04 22:11:39 +03:00

164 lines
7.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Kyiv Radioactive!</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-apexcharts"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<style>
#app > div {
margin: 5px auto;
width: 80%;
text-align: center;
padding: 5px;
border: 1px #aaa dashed;
}
#app fieldset {
display: inline-block;
border: 0;
padding: 0;
margin-left: 20px;
}
#app > .notification {
border: none;
}
</style>
</head>
<body>
<section class="section">
<div class="container">
<h1 class="title">
неРадіоактивна ситуація в Києві.
</h1>
<h2 class="subtitle">В реальному часі.</h2>
<div class="notification is-warning">
Використовуйте ландшавтну орієнтацію екрану для зручного перегляду. Або планшет чи компьютер.
</div>
<div id="app">
<div>
<apexchart type="line" height="350" :options="ratesChartOptions" :series="rates_series"></apexchart>
<button @click="rates_autoupdate = !rates_autoupdate" class="button">Автооновлення: {{ rates_autoupdate ? "ВКЛ" : "ВИКЛ" }}</button>
</div>
<div class="notification">
<strong>До 0,3 мк3в/г - нормальний радіаційний фон.</strong>
<p>
Швидкість дози в мікрозівертах на годину вказує, скільки мікрозівертів (одиниця виміру еквівалентної дози) радіації поглинається організмом або матеріалом за одну годину. Ця величина може використовуватися для оцінки рівня радіаційного впливу на людей, а також для моніторингу і контролю радіаційної безпеки в радіаційних зонах, ядерних установках або природному середовищі.
</p>
<p>
Наприклад, якщо швидкість дози становить 10 μSv/h, це означає, що організм або матеріал отримує дозу 10 мікрозівертів радіації за кожну годину. Це може вказувати на наявність джерела радіації в цьому місці або на необхідність заходів з радіаційного захисту.
</p>
</div>
<div>
<apexchart type="bar" height="350" :options="spectrumChartOptions" :series="spectrum_series"></apexchart>
<div>
<fieldset>
<label class="checkbox" for="spectrum_x_accum"><input type="checkbox" id="spectrum_x_accum" v-model="spectrum_accum"> Акумульований</label>
</fieldset>
<fieldset class="control">
<label class="radio" for="spectrum_x_channel"><input type="radio" id="spectrum_x_channel" v-bind:value="false" v-model="spectrum_energy"> Канал</label>
<label class="radio" for="spectrum_x_energy"><input type="radio" id="spectrum_x_energy" v-bind:value="true" v-model="spectrum_energy"> Енергія</label>
</fieldset>
<fieldset class="control">
<label class="radio" for="spectrum_linear"><input type="radio" id="spectrum_linear" v-bind:value="false" v-model="spectrum_logarithmic"> Лінійне</label>
<label class="radio" for="spectrum_log"><input type="radio" id="spectrum_log" v-bind:value="true" v-model="spectrum_logarithmic"> Логарифмічне</label>
</fieldset>
</div>
<button @click="updateSpectrum" class="button">Оновити спектр</button>
</div>
</div>
<h2 class="subtitle">(Частина проекту <a href="https://dead.guru/">dead.guru</a>)</h2>
</div>
</section>
<script>
const common_options = {
chart: {
animations: {enabled: false},
zoom: {autoScaleYaxis: true},
},
tooltip: {intersect: false},
grid: {xaxis: {lines: {show: true}}},
dataLabels: {enabled: false},
};
var app = new Vue({
el: '#app',
components: {
apexchart: VueApexCharts,
},
data: function() {
return {
ws: null,
spectrum_duration: 0,
rates_autoupdate: true,
rates_series: [],
spectrum_accum: false,
spectrum_series: [],
spectrum_coef: [0, 0, 0],
spectrum_logarithmic: true,
spectrum_energy: true,
ratesChartOptions: {
...common_options,
title: {text: 'Активнсть подій (подій в секунду) і доза'},
xaxis: {type: 'datetime'},
yaxis: [
{seriesName: 'Подій', title: {text: 'ПНС'}, labels: {formatter:(v) => v.toFixed(2) + ' ПНС'}},
{seriesName: 'Доза', title: {text: 'мк3в/г'}, labels: {formatter:(v) => v.toFixed(4) + ' мк3в/г'}, opposite: true},
],
},
};
},
watch: {
spectrum_accum() {
this.updateSpectrum();
}
},
computed: {
spectrumChartOptions() {
const a0 = this.spectrum_coef[0], a1 = this.spectrum_coef[1], a2 = this.spectrum_coef[2];
const fmt = this.spectrum_energy ? ((c) => (a0 + a1*c + a2*c*c).toFixed(0)) : undefined;
const title = this.spectrum_energy ? 'кеВ' : 'канал';
return{
...common_options,
title: {text: `Спектр, ${this.spectrum_duration} секунд`},
xaxis: {type: 'numeric', title: {text: title}, tickAmount: 25, labels: {formatter:fmt}},
yaxis: {logarithmic: this.spectrum_logarithmic, decimalsInFloat: 0},
plotOptions: {bar: {columnWidth: '95%'}},
};
},
},
created() {
this.ws = new WebSocket('wss://' + window.location.host + '/ws')
this.ws.onmessage = this.onmessage;
this.updateSpectrum();
},
beforeDestroy: function() {
this.ws.close();
},
methods: {
onmessage(ev) {
if (!this.rates_autoupdate) {
return;
}
const d = JSON.parse(ev.data);
this.rates_series = d.series;
},
updateSpectrum() {
fetch(`/spectrum?accum=${this.spectrum_accum}`)
.then(response => response.json())
.then(data => (this.spectrum_duration=data.duration, this.spectrum_coef=data.coef, this.spectrum_series=data.series));
},
},
});
</script>
</body>
</html>