Merge pull request #246 from shikorism/feature/monthly-graph-term

月間チェックイングラフの表示期間を選択可能にする
This commit is contained in:
shibafu 2019-08-08 00:23:15 +09:00 committed by GitHub
commit 1b2b043be2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 19 deletions

View File

@ -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) { foreach ($groupByDay as $data) {
$date = Carbon::createFromFormat('Y/m/d', $data->date); $date = Carbon::createFromFormat('Y/m/d', $data->date);
$yearAndMonth = $date->format('Y/m'); $yearAndMonth = $date->format('Y/m');
@ -123,9 +116,7 @@ SQL
$dailySum[$date->timestamp] = $data->count; $dailySum[$date->timestamp] = $data->count;
$yearlySum[$date->year] += $data->count; $yearlySum[$date->year] += $data->count;
$dowSum[$date->dayOfWeek] += $data->count; $dowSum[$date->dayOfWeek] += $data->count;
if (isset($monthlySum[$yearAndMonth])) { $monthlySum[$yearAndMonth] = ($monthlySum[$yearAndMonth] ?? 0) + $data->count;
$monthlySum[$yearAndMonth] += $data->count;
}
} }
foreach ($groupByHour as $data) { foreach ($groupByHour as $data) {
@ -136,8 +127,7 @@ SQL
$graphData = [ $graphData = [
'dailySum' => $dailySum, 'dailySum' => $dailySum,
'dowSum' => $dowSum, 'dowSum' => $dowSum,
'monthlyKey' => array_keys($monthlySum), 'monthlySum' => $monthlySum,
'monthlySum' => array_values($monthlySum),
'yearlyKey' => array_keys($yearlySum), 'yearlyKey' => array_keys($yearlySum),
'yearlySum' => array_values($yearlySum), 'yearlySum' => array_values($yearlySum),
'hourlyKey' => array_keys($hourlySum), 'hourlyKey' => array_keys($hourlySum),

View File

@ -16,6 +16,7 @@
"cal-heatmap": "^3.3.10", "cal-heatmap": "^3.3.10",
"chart.js": "^2.7.1", "chart.js": "^2.7.1",
"cross-env": "^5.2.0", "cross-env": "^5.2.0",
"date-fns": "^1.30.1",
"husky": "^1.3.1", "husky": "^1.3.1",
"jquery": "^3.2.1", "jquery": "^3.2.1",
"js-cookie": "^2.2.0", "js-cookie": "^2.2.0",

View File

@ -1,9 +1,12 @@
import CalHeatMap from 'cal-heatmap'; import CalHeatMap from 'cal-heatmap';
import Chart from 'chart.js'; 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) { function createLineGraph(id, labels, data) {
const context = document.getElementById(id).getContext('2d'); const context = document.getElementById(id).getContext('2d');
new Chart(context, { return new Chart(context, {
type: 'line', type: 'line',
data: { data: {
labels: labels, 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({ new CalHeatMap().init({
itemSelector: '#cal-heatmap', itemSelector: '#cal-heatmap',
@ -76,7 +94,40 @@ new CalHeatMap().init({
legend: [1, 2, 3, 4] 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); createLineGraph('yearly-graph', graphData.yearlyKey, graphData.yearlySum);
createBarGraph('hourly-graph', graphData.hourlyKey, graphData.hourlySum); 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();
});

View File

@ -15,7 +15,14 @@
<h5 class="my-4">Shikontribution graph</h5> <h5 class="my-4">Shikontribution graph</h5>
<div id="cal-heatmap" class="tis-contribution-graph"></div> <div id="cal-heatmap" class="tis-contribution-graph"></div>
<hr class="my-4"> <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> <canvas id="monthly-graph" class="w-100"></canvas>
<hr class="my-4"> <hr class="my-4">
<h5 class="my-4">年間チェックイン回数</h5> <h5 class="my-4">年間チェックイン回数</h5>

View File

@ -2333,7 +2333,7 @@ d3@^3.0.6:
resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8" resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8"
integrity sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g= integrity sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=
date-fns@^1.27.2: date-fns@^1.27.2, date-fns@^1.30.1:
version "1.30.1" version "1.30.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==