私の業務は全体をまとめるような仕事だ。
ただし、今後は私自身がどこかのチームに所属して、開発業務に従事するように 上司から言われた。
考えて考えて施策を提案、皆を牽引した事で実現できたのに「実現したから、もう不要」って。
何十年も離れていて、いまさら開発業務で即戦力になれると思えないよ……。
サラリーマンって本当に理不尽だ。
先週末は「Bootstrap」と「Google Chart」で、簡単な自動更新サイトを構築して終わってしまった……。
最近は、Pythonでスクリプトを書くぐらいで、Webサイトを作るモチベーションなんて全く無かった。アイデアも浮かばないし。
でも、前回作成したグラフが、日記を書く目的だけの実装で終わるのは勿体ない。
「釣りサイト」は作りたいと昔から思ってたし、自分自身にも役に立つので作ってみることにした。
今まで「Chart.js」を使ったグラフ出力の経験があるが「Google Chart」は使ったことがない。
数年前に確認した時に「Google Chart」の方が「Chart.js」より圧倒的にシェアが高そうだったが、複雑だと思って使わなかった。
趣味では新しいことを経験して成長するために「Google Chart」を使ってみた。
Bootstrap5でサイトを作成する
他にも新しいものを使ってみる。
2021年3月23日、Bootstrap5 beta3 が公開された……らしい。
が、こんなものイチイチ把握してないよ。
まぁ、2020年6月16日にBootstrap5 alphaがリリースされていた事も知らなかったが。
まだBootstrap3で作ってるサイトだってある。
以前確認した時は、互換性は無いに等しく「3→4」にするとレイアウトがボロボロになった。
今回の「Bootstrap5」を見る限り、レイアウトは崩れるような大きな変更はなさそうだけど……。
- 1.脱JQUERY
- 2.INTERNET EXPLORER非サポート
- 3.ブレークポイント「XXL」追加
- 4.ガターを細かく設定できるG-*クラス登場
- 5.CSS カスタムプロパティ (変数) が使える
- 6.クラス名にも変更がある
実際にBootstrap4で作成した後、「Bootstrap CDN」を使って Bootstrap5に変更してみた。
マージン対応の「mb/mt」でズレた。さらに、なんか横幅が大きくなった気がする。
更にJQUERYが無くなった事で、依存している場合は厄介な気はする。
Google Chartを使ってCSVを読み込み複合グラフを出力
Bootstrapでサイトのデザインを作成後は、ひたすらJavascriptのカスタマイズ。
あまりJavascriptって書かないんだよね。
でも、少し楽しくなって最終的に次のようなページを作成した。
魚の写真は、このような目的のために自分で撮りためたものと、Wikipedia等からPublic freeを確認して拝借した。
CSVをGoogle Chartで読み込む
ここから残りの内容はGoogle Chartのコード説明なので、不要な人は読まなくて良いだろう。
Google Chartで表示するデータの設定部分は、DataTableのインスタンスを生成して、列の設定・データの追加をする方法のほか、CSV形式のような記述や、JSON形式にも対応している。
因みに「CSV形式のような記述」は次のとおり。
1 2 3 4 5 6 7 8 9 10 |
var data = google.visualization.arrayToDataTable([ [ "日", "人数", "アジ", "イワシ"] ["12月8日", 32, 80, 99], ["12月9日", 574, 54, 69], ["12月10日", 51, 56, 75], ["12月11日", 37, 109, 61], ["12月12日", 402, 72, 59], ["12月13日", 532, 16, 23], ["12月14日", 188, 91, 93] ]); |
でも、コレジャナイ……。
CSVそのままで読み込めないと、PythonのPandasで出力したデータ形式の変換が必要で面倒だ。
CSVを読み込んで使うには自分で関数を用意する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// 該当名(url)の csvファイルをchartデータとして整形 function getCsv(url) { //CSVファイルを文字列で取得。 var txt = new XMLHttpRequest(); txt.open('get', url, false); txt.send(); // 改行ごとに配列化 var arr = txt.responseText.split('\n'); // 1次元配列を2次元配列に変換 res = []; for (var i = 0; i < arr.length; i++) { // 空白行が出てきた時点で終了 if (arr[i] == '') break; // ","ごとに配列化 res[i] = arr[i].split(','); for (var i2 = 1; i2 < res[i].length; i2++) { // 数字の場合は「"」を削除 ・・・ 2列目以降に適用 if (res[i][i2].match(/\-?\d+(.\d+)?(e[\+\-]d+)?/)) { res[i][i2] = parseFloat(res[i][i2].replace('"', '')); } } } return res; }; // getCsv(url) --------------------------- |
まぁ、これ自体はどこかのサイトから、そのまま貰ったものだけど。
複数軸(ComboChart)を表示する
今回は「釣れた魚の数(匹)」と「釣り人数(人)」を左右の軸に表示したい。
ググって「targetAxisIndex: 1」などの指定が必要な事は分かったが、肝心の軸が表示されずに困っていた。
色々と調べて分かったことは、hAxisの複数形がhAxesで この記述が必要だった。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// 3) 該当データ(ma)をgoogle.chartsで表示 function drawVisualization() { data = google.visualization.arrayToDataTable(ma); var options = { title : '', titleTextStyle : { color: '#333', fontSize: 24 }, // hAxisの複数形がhAxes vAxes: { 0: {title: '魚数(匹)', format: '0'}, //0の軸のタイトルを設定 1: {title: '人数(人)', format: '0'}, //1の軸のタイトルを設定 }, hAxis: {title: ''}, seriesType: 'bars', // focusTarget: 'category', series: { 0: { color: '#666',type: "line", targetAxisIndex: 1}, 1: { targetAxisIndex: 0}, }, // 0 人数だけ折れ線グラフ legendTextStyle : { color: '#333', fontSize: 12 }, isStacked: true // 積み上げグラフ }; |
折れ線グラフで人数を表現し、積み上げグラフで魚ごとの匹数を表現している。
Googleチャートの縦軸を整数にする
グラフの軸が人数や引数なのに「3.0」のように小数点が付くのはオカシイ。
縦軸を整数にするには「format: ‘0’」を付ける必要がある。
クリックすると該当する魚名だけのグラフを表示する
これは、ググっても例が無かった。
実現方法を迷った結果、CSVを読み込む時点で不要なデータを削除することにした。
1 2 3 4 5 6 |
// 不要な列を削除 for(var i2 = res[i].length - 1; i2 >= 1; i2--) { if (i2 != num) { res[i].splice(i2, 1); } } |
spliceを使って、不要なデータを削除。
何番目の棒がクリックされたか
棒グラフをクリックしたら、そのデータに該当するURLにリンクを貼って飛ばす方法。
1 2 3 4 5 6 7 8 9 10 |
google.visualization.events.addListener(chart, 'select', selectHandler); // 何番目の棒がクリックされたか function selectHandler() { var selectedItem = chart.getSelection()[0]; if (selectedItem) { var value = selectedItem.row; alert(value); } } |
ただ、スマホだとクリックしないと「吹き出し文字」が表示されないので、URLに飛ばすUXだと微妙だね。
これは検討はしたけど一旦見送りにした。
[番外] ローディングの画面の作成
自分のスマホで見ると読み込みに10秒ぐらい必要だった。
仕方ないので「くるくる(ローディング)」的な画面を追加した。
最近はCSSメインで実現できるのね、凄い。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<style> /* ローディング画面 */ #loading { width: 100vw; height: 430px; transition: all 1s; background-color: #0bd; /* 以下のコードを追加 */ position: fixed; top: 0; left: 0; z-index: 9999; } .spinner { width: 100px; height: 100px; margin: 200px auto; background-color: #fff; border-radius: 100%; animation: sk-scaleout 1.0s infinite ease-in-out; } /* ローディングアニメーション */ @keyframes sk-scaleout { 0% { transform: scale(0); } 100% { transform: scale(1.0); opacity: 0; } } .loaded { opacity: 0; visibility: hidden; } </style> <body onload="const spinner = document.getElementById('loading'); spinner.classList.add('loaded');"> <!-- ローディング画面 --> <div id="loading"> <div class="spinner"></div> <div> |
イメージ通りな画面ができた。本当は高速化したいけど……。
まとめ
人は来ないと思うが、ターゲットの魚と時期を決める際に自分自身の役に立つので活用しよう。
全国版を作れた良いけどデータが無いな……。
また、写真投稿サイトを作ったり……とも考えた事もあるが、閑古鳥がなくような弱小サイトでは寂しいだけで終わる。
最近は新規サイト作成のアイデアは出てこないなぁ……。