Merge pull request #246 from shikorism/feature/monthly-graph-term
月間チェックイングラフの表示期間を選択可能にする
This commit is contained in:
commit
1b2b043be2
@ -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),
|
||||
|
@ -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",
|
||||
|
59
resources/assets/js/user/stats.js
vendored
59
resources/assets/js/user/stats.js
vendored
@ -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);
|
||||
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();
|
||||
});
|
||||
|
@ -15,7 +15,14 @@
|
||||
<h5 class="my-4">Shikontribution graph</h5>
|
||||
<div id="cal-heatmap" class="tis-contribution-graph"></div>
|
||||
<hr class="my-4">
|
||||
<h5 class="my-4">月間チェックイン回数</h5>
|
||||
<div class="row my-4">
|
||||
<div class="col-12 col-lg-6 d-flex align-items-center">
|
||||
<h5 class="my-0">月間チェックイン回数</h5>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 mt-2 mt-lg-0">
|
||||
<select id="monthly-term" class="form-control"></select>
|
||||
</div>
|
||||
</div>
|
||||
<canvas id="monthly-graph" class="w-100"></canvas>
|
||||
<hr class="my-4">
|
||||
<h5 class="my-4">年間チェックイン回数</h5>
|
||||
|
@ -2333,7 +2333,7 @@ d3@^3.0.6:
|
||||
resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8"
|
||||
integrity sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=
|
||||
|
||||
date-fns@^1.27.2:
|
||||
date-fns@^1.27.2, date-fns@^1.30.1:
|
||||
version "1.30.1"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
|
||||
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
|
||||
|
Loading…
Reference in New Issue
Block a user