###### tags: `GitHub Page` `canvasjs` `JavaScript` `HTML` # LineTagAnalyze Using LINE's tags to generate cumulative graphs over time. # 網頁成果展示 > [網頁應用連結](https://yutingkung.github.io/LineTagAnalyze/) > [原始碼連結](https://github.com/YuTingKung/LineTagAnalyze) ![](https://i.imgur.com/pIAv5mD.png) # 邏輯流程圖 ```flow st=>start: 開始 e=>end: 結束 upload=>operation: 點按選擇檔案,選擇從LINE匯出的TXT檔案 analyze=>operation: 從TXT讀取各訊息的發送者名稱,再用發送者名稱來解析標記 graph=>operation: canvasJS讀取整理好的資料並產生頁面 st->upload->analyze->graph->e ``` # 使用技術 ## 程式語言: JavaScript 原生JavaScript,無使用框架。 ## 部署平台: GitHub Page > [參考連結](https://pages.github.com/) 在GitHub創立Repository,再將該Repository設定為GitHub Page,平台就會認定Repository內的index.html為初始檔案。 ## 圖表模組: canvasJS > [折線圖連結](https://canvasjs.com/javascript-charts/multi-series-line-chart/) 此專案選擇外部引用canvasJS。canvasJS支援多個框架和多種圖形,並且可直接於線上編輯,將測試資料帶入頁面,即可事先查看所產生的圖形是否符合需求。 # 程式補充說明 ## 1. 若使用者更改名稱,則會造成中間欄位名稱和右方標記不同。(下圖為從LINE匯出的格式參考) ![](https://i.imgur.com/uLTo4kP.jpg =360x640) ## 2. 部分標記後方有空白,部分則無,增加Regex的難度。 ## 3. 預期最佳解決方案,可再下方列出所有解析出的標記,並讓使用者選擇是否顯示或合併。 # 初版完整index.html程式碼 ```htmlembedded <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input type="file" name="file" id="file"> <div id="chartContainer" style="height: 370px; width: 100%;"></div> <div id="output"></div> <script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script> <script> const $output = document.getElementById('output') document.getElementById('file').onchange = function() { var file = this.files[0]; var reader = new FileReader(); var data = []; reader.onload = function(progressEvent) { const text = this.result; // $output.innerText = text // This line will show all text on screen, but the screen will get stocked if txt is too large. let lines = text.split('\n').slice(3); let table = []; let date = ''; let uniqueNameFromTitle = []; for (var line = 0; line < lines.length; line++) { let timeRegExp = new RegExp("^([0-9]{2})([:]{1})([0-9]{2})"); let isTime = timeRegExp.test(lines[line].substring(0, 10).split(' ')[0]); if (isTime) { let title = lines[line].split('\t')[1]; uniqueNameFromTitle.push(title); }; } uniqueNameFromTitle = uniqueNameFromTitle.filter((v, i, a) => a.indexOf(v) === i).filter(e => e != null && e.length > 0); let matchNameRegExp = uniqueNameFromTitle.map(e => `@${e}`).join('|'); for (var line = 0; line < lines.length; line++) { let dateRegExp = new RegExp("^([0-9]{4})([/]{1})([0-9]{1,2})([/]{1})([0-9]{1,2})"); let isDate = dateRegExp.test(lines[line].substring(0, 10).split(' ')[0]); if (isDate) { date = lines[line].slice(0, -4); } else { //let tagMatch = lines[line].match(/@.*?(?=[ ]|$)/g); // Match tag by @ and space let tagMatch = lines[line].match(new RegExp(matchNameRegExp, "g")); if (tagMatch) { tagMatch.forEach((tag) => { let lastCount = table.filter(e => e.name == tag)?.length ?? 0; table.push({date: date, name: tag, count: lastCount + 1 }); }); } } } // var uniqueNameFromTable = table.map(e => e.name).filter((v, i, a) => a.indexOf(v) === i); uniqueNameFromTitle.forEach((uniqueName) => { let item = { type:"line", axisYType: "secondary", name: uniqueName?.replace('@', '') ?? '', showInLegend: true, markerSize: 0, dataPoints: table.filter(e => e.name?.replace('@', '') == uniqueName)?.map(e => ({ x: new Date(e.date), y: Number(e.count)})) ?? [] } data.push(item); }); data = data.sort((a, b) => b.dataPoints.length - a.dataPoints.length).slice(0, 12); var chart = new CanvasJS.Chart("chartContainer", { title: { text: "每日標記數累加圖" }, toolTip: { shared: true }, legend: { cursor: "pointer", verticalAlign: "top", horizontalAlign: "center", dockInsidePlotArea: true, itemclick: toogleDataSeries }, data: data }); chart.render(); function toogleDataSeries(e){ if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) { e.dataSeries.visible = false; } else{ e.dataSeries.visible = true; } chart.render(); } }; reader.readAsText(file); }; </script> </body> </html> ```