飲み過ぎを自覚できます
筆者は30代半ばになりますが、歳のせいかアルコールが抜けなくなってきました。
読者の皆様におきましても、あぁ~今日はちょっと飲み過ぎちゃったななんて経験はあるのではないでしょうか。
飲み過ぎたという漠然とした後悔は感じつつも、果たしてどのくらい飲み過ぎてしまったのかを意識できている方はいますか?少なくとも私は意識できていません(笑)
一般的に、1日に3単位(純アルコール量 60g)以上摂取した場合を飲み過ぎと言うらしいです。
何はともあれシステムエンジニアの端くれとして、飲み過ぎを可視化してみようと思います。
飲んだアルコールをカウントするだけ
代表的な飲み物(ビール、日本酒、焼酎、ワイン、ウィスキー、梅酒)をラインナップし、それぞれに設置しているカウントボタン押下で計上します。するとリアルタイムにグラフに反映されます。飲み過ぎ基準の3単位(純アルコール量 60g)のラインを危険閾値として表示しています。
★実際のWebアプリはこちら ⇒ アルコール換算
飲み過ぎを自覚するために必要なモノ
世の中いろいろと便利になってきていて、タダでスピーディーにWebアプリを開発できる時代になりました。
今回はその恩恵を存分に享受して、難しことはあまり考えずにサクッとWebアプリを作ってしまおうと思います。
・CodePen
ブラウザ上でHTML,CSS,JavaScriptのコードを記述し、リアルタイムで表示を確認しながら開発をすることができるサービスです。
CodePenの使い方(知らない人向け)
・JSライブラリ
chartjs-plugin-annotation
Chart.jsのグラフに横線を入れることができる。Chart.jsには様々なプラグインが用意されている。 グラフ内にデータ以外の線を引いたり、四角で囲ったりするにはプラグイン「chartjs-plugin-annotation」を使用する。Chart.jsで横棒を表示するだけのサンプル
CodePenでエクスポートしたプロジェクトとNetlilfyにデプロイすることでWebアプリを公開できる。
超便利ホスティングサービス Netlify
Webアプリソースコード
html
<!DOCTYPE html>
<html lang="ja" >
<head>
<meta charset="UTF-8">
<title>Alcohol intake</title>
<meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.bundle.min.js" integrity="sha256-eA+ych7t31OjiXs3fYU0iWjn9HvXMiCLmunP2Gpghok=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@0.5.7/chartjs-plugin-annotation.min.js" integrity="sha256-Olnajf3o9kfkFGloISwP1TslJiWUDd7IYmfC+GdCKd4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
</head>
<h1>アルコール換算</h1>
<p id="p1">アルコール摂取量の基準とされるお酒の1単位とは、純アルコールに換算して20gです。<br>
多量飲酒とは 、1日に純アルコール量 60g以上摂取した場合を言い、多量飲酒習慣により肝障害や高血圧、 脳卒中、糖尿病などの生活習慣病をひき起こし、進行させる危険性が高くなります。
</p>
<h2>お酒を入力してみましょう! グラフが表示されます!</h2>
<div id="vue-app">
・ビール(中ジョッキ:320ml):<button @click="voteP">+1</button> <button @click="voteM">-1</button> ※アルコール:5%<br>
アルコール摂取量:<span>{{ vueCounter }}</span>g
</div>
<br>
<div id="vue-app2">
・日本酒(1合):<button @click="voteP">+1</button> <button @click="voteM">-1</button> ※アルコール:15%<br>
アルコール摂取量:<span>{{ vueCounter2 }}</span>g
</div>
<br>
<div id="vue-app3">
・焼酎(1合):<button @click="voteP">+1</button> <button @click="voteM">-1</button> ※アルコール:20%<br>
アルコール摂取量:<span>{{ vueCounter3 }}</span>g
</div>
<br>
<div id="vue-app4">
・ワイン(グラス:120ml):<button @click="voteP">+1</button> <button @click="voteM">-1</button> ※アルコール:12%<br>
アルコール摂取量:<span>{{ vueCounter4 }}</span>g
</div>
<br>
<div id="vue-app5">
・ウィスキー(シングル):<button @click="voteP">+1</button> <button @click="voteM">-1</button> ※アルコール:40%<br>
アルコール摂取量:<span>{{ vueCounter5 }}</span>g
</div>
<br>
<div id="vue-app6">
・梅酒(1合):<button @click="voteP">+1</button> <button @click="voteM">-1</button> ※アルコール:15%<br>
アルコール摂取量:<span>{{ vueCounter6 }}</span>g
</div>
<br>
******************************************
<div id="vue-appTotal">
アルコール摂取量(単位換算)<button @click="vote">計算</button>:<span>{{ vueCounterTotal }}</span>
</div>
<canvas id="chart">
Canvas not supported...
</canvas>
<!-- partial -->
<script src="./script.js"></script>
</body>
</html>
css
h1 {
color: #505050;/*文字色*/
padding: 0.5em;/*文字周りの余白*/
display: inline-block;/*おまじない*/
line-height: 1.3;/*行高*/
background: #dbebf8;/*背景色*/
vertical-align: middle;
border-radius: 25px 0px 0px 25px;/*左側の角を丸く*/
}
h1:before {
content: '●';
color: white;
margin-right: 8px;
}
h2 {
position: relative;
padding: 1rem 2rem;
border-radius: 10px;
background: #27acd9;
color: #fff;
}
h2:after {
position: absolute;
content: '';
width: 0;
height: 0;
bottom: -10px;
left: 1.5em;
border-width: 10px 10px 0 10px;
border-style: solid;
border-color: #27acd9 transparent transparent transparent;
}
p {
position: relative;
padding: 1rem 2rem;
border: solid 2px #27acd9;
}
p:after {
position: absolute;
content: "アルコール換算について";
top: -10px;
left: 15px;
background: #fff;
font-size: 0.75rem;
color: #27acd9;
padding: 0 10px;
}
JavaScript
//window.onload = function () {
// Vue.jsの場合
var amount = 0;
const app = new Vue({
el: '#vue-app',
data: { vueCounter: 0, intCnt: 0,}, // アルコール量と回数を保持する
methods: {
voteP: function () {
this.intCnt++; // クリック回数を増やす
this.vueCounter = this.intCnt * 13;
amount = amount + 0.65;
draw();
console.log('amount: ',amount);
console.log('ビール1杯削除', this.vueCounter);
// データが変化すると、DOMも勝手に更新される。便利!
},
voteM: function () {
this.intCnt--; // クリック回数を減らす
this.vueCounter = this.intCnt * 13;
amount = amount - 0.65;
draw();
console.log('amount: ',amount);
console.log('ビール1杯追加', this.vueCounter);
// データが変化すると、DOMも勝手に更新される。便利!
},
},
});
const app2 = new Vue({
el: '#vue-app2',
data: { vueCounter2: 0, intCnt2: 0,}, // アルコール量と回数を保持する
methods: {
voteP: function () {
this.intCnt2++; // クリック回数を増やす
this.vueCounter2 = this.intCnt2 * 20;
amount = amount + 1;
draw();
console.log('amount: ',amount);
console.log('日本酒1杯追加', this.vueCounter2);
// データが変化すると、DOMも勝手に更新される。便利!
},
voteM: function () {
this.intCnt2--; // クリック回数を減らす
this.vueCounter2 = this.intCnt2 * 20;
amount = amount - 1;
draw();
console.log('amount: ',amount);
console.log('日本酒1杯削除', this.vueCounter2);
// データが変化すると、DOMも勝手に更新される。便利!
},
},
});
const app3 = new Vue({
el: '#vue-app3',
data: { vueCounter3: 0, intCnt3: 0,}, // アルコール量と回数を保持する
methods: {
voteP: function () {
this.intCnt3++; // クリック回数を増やす
this.vueCounter3 = this.intCnt3 * 29;
amount = amount + 1.45;
draw();
console.log('amount: ',amount);
console.log('焼酎1杯追加', this.vueCounter3);
// データが変化すると、DOMも勝手に更新される。便利!
},
voteM: function () {
this.intCnt3--; // クリック回数を減らす
this.vueCounter3 = this.intCnt3 * 29;
amount = amount - 1.45;
draw();
console.log('amount: ',amount);
console.log('焼酎1杯削除', this.vueCounter3);
// データが変化すると、DOMも勝手に更新される。便利!
},
},
});
const app4 = new Vue({
el: '#vue-app4',
data: { vueCounter4: 0, intCnt4: 0,}, // アルコール量と回数を保持する
methods: {
voteP: function () {
this.intCnt4++; // クリック回数を増やす
this.vueCounter4 = this.intCnt4 * 12;
amount = amount + 0.6;
draw();
console.log('amount: ',amount);
console.log('ワイン1杯追加', this.vueCounter4);
// データが変化すると、DOMも勝手に更新される。便利!
},
voteM: function () {
this.intCnt4--; // クリック回数を減らす
this.vueCounter4 = this.intCnt4 * 12;
amount = amount - 0.6;
draw();
console.log('amount: ',amount);
console.log('ワイン1杯削除', this.vueCounter4);
// データが変化すると、DOMも勝手に更新される。便利!
},
},
});
const app5 = new Vue({
el: '#vue-app5',
data: { vueCounter5: 0, intCnt5: 0,}, // アルコール量と回数を保持する
methods: {
voteP: function () {
this.intCnt5++; // クリック回数を増やす
this.vueCounter5 = this.intCnt5 * 10;
amount = amount + 0.5;
draw();
console.log('amount: ',amount);
console.log('ウィスキー1杯追加', this.vueCounter5);
// データが変化すると、DOMも勝手に更新される。便利!
},
voteM: function () {
this.intCnt5--; // クリック回数を減らす
this.vueCounter5 = this.intCnt5 * 10;
amount = amount - 0.5;
draw();
console.log('amount: ',amount);
console.log('ウィスキー1杯削除', this.vueCounter5);
// データが変化すると、DOMも勝手に更新される。便利!
},
},
});
const app6 = new Vue({
el: '#vue-app6',
data: { vueCounter6: 0, intCnt6: 0,}, // アルコール量と回数を保持する
methods: {
voteP: function () {
this.intCnt6++; // クリック回数を増やす
this.vueCounter6 = this.intCnt6 * 22;
amount = amount + 1.1;
draw();
console.log('amount: ',amount);
console.log('梅酒1杯追加', this.vueCounter6);
// データが変化すると、DOMも勝手に更新される。便利!
},
voteM: function () {
this.intCnt6--; // クリック回数を減らす
this.vueCounter6 = this.intCnt6 * 22;
amount = amount - 1.1;
draw();
console.log('amount: ',amount);
console.log('梅酒1杯削除', this.vueCounter6);
// データが変化すると、DOMも勝手に更新される。便利!
},
},
});
const appTotal = new Vue({
el: '#vue-appTotal',
data: { vueCounterTotal: 0,},
methods: {
vote: function () {
this.vueCounterTotal = amount;
console.log('amount: ',amount);
// データが変化すると、DOMも勝手に更新される。便利!
},
},
});
function draw(){
var ctx = document.getElementById('chart').getContext('2d');
var myChart = new Chart(ctx, {
// The type of chart we want to create
type: 'bar',
// The data for our dataset
data: {
labels: ['アルコール摂取量'],
datasets: [{
label: 'アルコール摂取量',
backgroundColor: 'rgba(255, 99, 132, 0.5)',
borderColor: 'rgb(255, 99, 132)',
fill: false,
data: [amount,0,10]
}]
},
// Configuration options go here
options: {
title: {
display: true,
text: "アルコール摂取量"
},
annotation: {
drawTime: 'afterDatasetsDraw',
annotations: [
{
id: 'hline',
type: 'line',
mode: 'horizontal',
scaleID: 'y-axis-0',
value: 3,
borderColor: 'black',
borderWidth: 3,
label: {
backgroundColor: "red",
content: "危険",
enabled: true
},
},
]
}
}
});
}
//}
自覚しました
せっかく作ったので、最近の実績を計上してみます。
飲み過ぎ基準の約2倍でした。どうりで二日酔いになるはずです。。。
Web上のサービスとJSライブラリを利用するだけで、ここまで簡単に自覚させられるとは思ってもいませんでした。肝臓を労わろうと思います。
今回も閲覧ありがとうございました。こんなライブラリ使うと面白いよ!等ありましたらご一報(コメント)ください。