diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 04aed97..86e8571 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -109,13 +109,6 @@ SQL } } - // 月間グラフ用の配列初期化 - $month = Carbon::now()->firstOfMonth()->subMonth(11); // 直近12ヶ月 - for ($i = 0; $i < 12; $i++) { - $monthlySum[$month->format('Y/m')] = 0; - $month->addMonth(); - } - foreach ($groupByDay as $data) { $date = Carbon::createFromFormat('Y/m/d', $data->date); $yearAndMonth = $date->format('Y/m'); @@ -123,21 +116,18 @@ SQL $dailySum[$date->timestamp] = $data->count; $yearlySum[$date->year] += $data->count; $dowSum[$date->dayOfWeek] += $data->count; - if (isset($monthlySum[$yearAndMonth])) { - $monthlySum[$yearAndMonth] += $data->count; - } + $monthlySum[$yearAndMonth] = ($monthlySum[$yearAndMonth] ?? 0) + $data->count; } foreach ($groupByHour as $data) { $hour = (int)$data->hour; $hourlySum[$hour] += $data->count; } - + $graphData = [ 'dailySum' => $dailySum, 'dowSum' => $dowSum, - 'monthlyKey' => array_keys($monthlySum), - 'monthlySum' => array_values($monthlySum), + 'monthlySum' => $monthlySum, 'yearlyKey' => array_keys($yearlySum), 'yearlySum' => array_values($yearlySum), 'hourlyKey' => array_keys($hourlySum), diff --git a/package.json b/package.json index 76d71d7..dec71a0 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "cal-heatmap": "^3.3.10", "chart.js": "^2.7.1", "cross-env": "^5.2.0", + "date-fns": "^1.30.1", "husky": "^1.3.1", "jquery": "^3.2.1", "js-cookie": "^2.2.0", diff --git a/resources/assets/js/user/stats.js b/resources/assets/js/user/stats.js index adb9628..25e4895 100644 --- a/resources/assets/js/user/stats.js +++ b/resources/assets/js/user/stats.js @@ -1,9 +1,12 @@ import CalHeatMap from 'cal-heatmap'; import Chart from 'chart.js'; +import {addMonths, format, startOfMonth, subMonths} from 'date-fns'; + +const graphData = JSON.parse(document.getElementById('graph-data').textContent); function createLineGraph(id, labels, data) { const context = document.getElementById(id).getContext('2d'); - new Chart(context, { + return new Chart(context, { type: 'line', data: { labels: labels, @@ -62,7 +65,22 @@ function createBarGraph(id, labels, data) { }); } -const graphData = JSON.parse(document.getElementById('graph-data').textContent); +/** + * @param {Date} from + */ +function createMonthlyGraphData(from) { + const keys = []; + const values = []; + + for (let i = 0; i < 12; i++) { + const current = addMonths(from, i); + const yearAndMonth = format(current, 'YYYY/MM'); + keys.push(yearAndMonth); + values.push(graphData.monthlySum[yearAndMonth] || 0); + } + + return {keys, values}; +} new CalHeatMap().init({ itemSelector: '#cal-heatmap', @@ -76,7 +94,40 @@ new CalHeatMap().init({ legend: [1, 2, 3, 4] }); -createLineGraph('monthly-graph', graphData.monthlyKey, graphData.monthlySum); +// 直近1年の月間グラフのデータを準備 +const monthlyTermFrom = subMonths(startOfMonth(new Date()), 11); +const {keys: monthlyKey, values: monthlySum} = createMonthlyGraphData(monthlyTermFrom); + +const monthlyGraph = createLineGraph('monthly-graph', monthlyKey, monthlySum); createLineGraph('yearly-graph', graphData.yearlyKey, graphData.yearlySum); createBarGraph('hourly-graph', graphData.hourlyKey, graphData.hourlySum); -createBarGraph('dow-graph', ['日', '月', '火', '水', '木', '金', '土'], graphData.dowSum); \ No newline at end of file +createBarGraph('dow-graph', ['日', '月', '火', '水', '木', '金', '土'], graphData.dowSum); + +// 月間グラフの期間セレクターを準備 +const monthlyTermSelector = document.getElementById('monthly-term'); +for (let year = monthlyTermFrom.getFullYear(); year <= new Date().getFullYear(); year++) { + const opt = document.createElement('option'); + opt.setAttribute('value', year); + opt.textContent = `${year}年`; + monthlyTermSelector.insertBefore(opt, monthlyTermSelector.firstChild); +} +if (monthlyTermSelector.children.length) { + monthlyTermSelector.selectedIndex = 0; +} + +monthlyTermSelector.addEventListener('change', function (e) { + let monthlyTermFrom; + if (e.target.selectedIndex === 0) { + // 今年のデータを表示する時は、直近12ヶ月を表示 + monthlyTermFrom = subMonths(startOfMonth(new Date()), 11); + } else { + // 過去のデータを表示する時は、選択年の1〜12月を表示 + monthlyTermFrom = new Date(e.target.value, 0, 1); + } + + const {keys, values} = createMonthlyGraphData(monthlyTermFrom); + + monthlyGraph.data.labels = keys; + monthlyGraph.data.datasets[0].data = values; + monthlyGraph.update(); +}); diff --git a/resources/views/user/stats.blade.php b/resources/views/user/stats.blade.php index e6e7658..d202234 100644 --- a/resources/views/user/stats.blade.php +++ b/resources/views/user/stats.blade.php @@ -15,7 +15,14 @@