今回は、はてなブログ記事へのフォロアー数チャート描画
1.ストーリー
描画、データとともにはてなブログ内に置く
はてなプログにアップしたページにjavascriptを埋め込んでチャートを描画する
データは、csvファイルデータを下書きページに埋め込んで描画ページから読み込む
下書きページのデータを更新してチャートページを開けば最新データで描画される
2.下書きファイル読込
1)csvファイルのアップロード 詳細step04による
区切り文字 "-" になるように加工してアップロードする
2)ファイル読込
(1)URL
下書きプレビュー共有URLを使う
(2)読込
XMLHttpRequest で読み込む
Promise でチャート描画と同期させる
3.csvデータの抽出
1)読み込んだ下書き内のデータ所在と書式
<div class="entry-content">\n \n <p>-2019/10/19 11:41:11,1031874-2019/10/19 11:56:19,1031881-2019/10/19 11:57:38,1031881-2019/10/19 12:04:52,1031888-</p>\n<p>\xc2\xa0</p>\n \n\n \n</div>
2)csv抽出手順 javascript
// // convertCSVtoArray() 読み込んだCSVデータを二次元配列に変換 function convertCSVtoArray(str){ // 読み込んだCSVデータが文字列として渡される var start_entry = str.indexOf( 'entry-content' ); // entry-content 文字位置を探す var end_entry = str.indexOf('div',start_entry); // その後のdiv文字位置を探す var str_raw = str.substr(start_entry,end_entry-start_entry+1); // entry-contentを抜き出す var str_a = str_raw.split(/[-]/); // - を区切り文字として分割する // 各行ごとにカンマで区切った文字列を要素とした二次元配列を生成 var n=0; // 有効なデータ数 for(var i=0;i<str_a.length;++i) { if(str_a[i].substr(0,2)=='20') { // 文字列先頭が 20 なら有効判定 result[n++] = str_a[i].split(','); // 区切り文字 , で2分割 } } }
4.チャート描画
1)ライブラリの選定
Chart.js にする(見た目で決定)
2)描画
描画領域のためのcanvasタグは、scriptの中に入れて保護する
【注意】scriptの外に置くとサーバに消される
ファイル読み込み、データ抽出が完了したらPromiseのresponseを返す
データとチャート書式を整えて描画する
5.はてなブログに書き込むチャート描画コード
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script> <script> // canvas設定 【注意】script内に記載すること document.write("<div class='chart-container' style='position: relative; height:100%; width:100%'>"); document.write("<canvas id='myLineChart'></canvas>"); document.write("</div>"); // // 変数設定 var result = []; // 日時,fans 二次元配列を入れるための配列 // // 関数 // Chart.js 描画 function drawChart() { var ctx = document.getElementById('myLineChart'); // chart 本体 var dt = []; // datetime var fans = []; // fans for(var i = 0; i < result.length; i++) { // データ構築 dt[i] = result[i][0]; // datetime fans[i] = result[i][1]; } // chart設定 var data = { labels: dt, datasets: [{ label: 'fans', data: fans, borderColor: 'rgba(255, 0, 30, 1)', lineTension: 0, fill: false, // 塗りつぶさない borderWidth: 3 }] }; var options = { title: { display: true, text: '圏9微博フォロアー数' }, legend: {position: 'bottom'}, scales: { xAxes: [{ // format指定 type: "time", time: { unit: 'day', displayFormats: {day: "YYYY/MM/DD"} }, display: true, scaleLabel: {display: true, labelString: 'Date Time'} }], yAxes: [{ // 3桁コンマ区切り ticks: { callback: function(label, index, labels) { return label.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } } }] } }; var myLineChart = new Chart(ctx, { type: 'line', data: data, options: options }); } // getCSV() CSVファイルを読み込む Promiseで同期 // csvデータを貼り付けた下書きページのURLから読み込む function getCSV(url){ // Return a new promise. return new Promise(function(resolve, reject) { var req = new XMLHttpRequest(); // HTTPでファイルを読み込むためのXMLHttpRrequestオブジェクトを生成 // csvデータを貼り付けた下書きページのURLから読み込む req.open("get", url, true); req.send(null); // HTTPリクエストの発行 // レスポンスが返ってきたらconvertCSVtoArray()を呼ぶ req.onload = function(){ convertCSVtoArray(req.responseText); // 渡されるのは読み込んだCSVデータ resolve(req.response); // rejectは未実装 } }); } // // convertCSVtoArray() 読み込んだCSVデータを二次元配列に変換 function convertCSVtoArray(str){ // 読み込んだCSVデータが文字列として渡される var start_entry = str.indexOf( 'entry-content' ); // entry-content 文字位置を探す var end_entry = str.indexOf('div',start_entry); // その後のdiv文字位置を探す var str_raw = str.substr(start_entry,end_entry-start_entry+1); // entry-contentを抜き出す var str_a = str_raw.split(/[-]/); // - を区切り文字として分割する // 各行ごとにカンマで区切った文字列を要素とした二次元配列を生成 var n=0; // 有効なデータ数 for(var i=0;i<str_a.length;++i) { if(str_a[i].substr(0,2)=='20') { // 文字列先頭が 20 なら有効判定 result[n++] = str_a[i].split(','); // 区切り文字 , で2分割 } } } // // START getCSV("https://luke24e-hb.hatenablog.com/draft/Zn3TPhKGLqvVk-rm3ODmHUsa7Z0") .then(function(response) { // promise 完了処理 drawChart(); // グラフを描画する為のコールバック関数を指定 }); </script>
完成したチャート
luke24e-hb.hatenablog.com
part04へ続く