Files
2026-06-11 18:47:38 +09:00

284 lines
11 KiB
PHP

<?php
$sub_menu = '720100';
include_once('./_common.php');
auth_check_menu($auth, $sub_menu, "r");
$g5['title'] = "접속통계";
include_once(G5_ADMIN_PATH.'/admin.head.php');
//--- 데이터 처리 시작 ---//
$type = isset($_GET['type']) ? preg_replace('/[^a-z]/i', '', $_GET['type']) : 'summary';
// 날짜 검색
$start_day = isset($_GET['start_day']) && preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $_GET['start_day']) ? $_GET['start_day'] : G5_TIME_YMD;
$end_day = isset($_GET['end_day']) && preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $_GET['end_day']) ? $_GET['end_day'] : G5_TIME_YMD;
$list = [];
$sum_count = 0;
$max = 0;
$chart_data = ['labels' => [], 'datasets' => [['data' => []]]];
$page_title = '';
$chart_type = 'bar';
$sql_common = " from {$g5['visit_table']} ";
$sql_search = " where vi_date between '{$start_day}' and '{$end_day}' ";
switch ($type) {
case 'time':
$page_title = '시간별 통계';
$sql = " select SUBSTRING(vi_time, 1, 2) as `key`, count(vi_id) as `cnt` {$sql_common} {$sql_search} group by `key` order by `key` ";
break;
case 'week':
$page_title = '요일별 통계';
$sql = " select weekday(vi_date) as `key`, count(vi_id) as `cnt` {$sql_common} {$sql_search} group by `key` order by `key` ";
break;
case 'date':
$page_title = '일별 통계';
$chart_type = 'line';
$sql = " select vi_date as `key`, count(vi_id) as `cnt` {$sql_common} {$sql_search} group by `key` order by `key` ";
break;
case 'month':
$page_title = '월별 통계';
$chart_type = 'line';
$sql = " select SUBSTRING(vi_date, 1, 7) as `key`, count(vi_id) as `cnt` {$sql_common} {$sql_search} group by `key` order by `key` ";
break;
case 'browser':
$page_title = '접속 브라우저';
$chart_type = 'pie';
$sql = " select vi_browser as `key`, count(vi_id) as `cnt` {$sql_common} {$sql_search} group by `key` order by `cnt` desc limit 10";
break;
case 'os':
$page_title = '접속 OS';
$chart_type = 'pie';
$sql = " select vi_os as `key`, count(vi_id) as `cnt` {$sql_common} {$sql_search} group by `key` order by `cnt` desc limit 10";
break;
// ... (다른 케이스들)
default:
$page_title = '접속통계 요약';
break;
}
if ($type !== 'summary' && $sql) {
$result = sql_query($sql);
while($row = sql_fetch_array($result)) {
$list[] = $row;
$sum_count += $row['cnt'];
if ($row['cnt'] > $max) $max = $row['cnt'];
}
}
//--- 데이터 처리 끝 ---//
?>
<link rel="stylesheet" href="statistics.css?ver=<?php echo G5_CSS_VER; ?>">
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<div class="notbox">
<p>시간 흐름(시간/일간/월간)에 따른 방문자 현황 등을 한눈에 볼 수 있습니다.<br>
하루 하루 나타나는 데이터를 출력하여 모아 놓으면, 아주 소중한 사이트 운영가이드책이 될 수 있습니다.</p>
</div>
<dl class="srchb lnb4_col bg2_col">
<table class="bg_col">
<tbody><tr>
<td class="ctlt bno">통계분류</td>
<td class="wbg pl7">
<ul class="List">
<li><a href="./" class="<?php echo ($type == 'summary') ? 'btn_ov01' : 'btn_ov02'; ?>">접속통계</a></li>
<li><a href="./?type=time" class="<?php echo ($type == 'time') ? 'btn_ov01' : 'btn_ov02'; ?>">시간별 통계</a></li>
<li><a href="./?type=week" class="<?php echo ($type == 'week') ? 'btn_ov01' : 'btn_ov02'; ?>">요일별 통계</a></li>
<li><a href="./?type=date" class="<?php echo ($type == 'date') ? 'btn_ov01' : 'btn_ov02'; ?>">일별 통계</a></li>
<li><a href="./?type=month" class="<?php echo ($type == 'month') ? 'btn_ov01' : 'btn_ov02'; ?>">월별 통계</a></li>
<li><a href="./?type=domain" class="<?php echo ($type == 'domain') ? 'btn_ov01' : 'btn_ov02'; ?>">접속전 도메인</a></li>
<li><a href="./?type=ip" class="<?php echo ($type == 'ip') ? 'btn_ov01' : 'btn_ov02'; ?>">접속 IP</a></li>
<li><a href="./?type=browser" class="<?php echo ($type == 'browser') ? 'btn_ov01' : 'btn_ov02'; ?>">접속 브라우저</a></li>
<li><a href="./?type=os" class="<?php echo ($type == 'os') ? 'btn_ov01' : 'btn_ov02'; ?>">접속 OS</a></li>
</ul>
</td>
</tr>
</tbody></table>
</dl>
<?php if ($type !== 'summary'): ?>
<div class="pt5">
<dl class="srchb lnb4_col bg2_col">
<form name="statisticsSearchFrm" method="GET" id="statisticsSearchFrm">
<input type="hidden" name="type" value="<?php echo $type; ?>">
<dl class="tc pd7 wbg">
<input name="start_day" type="date" class="frm_input hasDatepicker" id="start_day" value="<?php echo $start_day; ?>"> ~
<input name="end_day" type="date" class="frm_input hasDatepicker" id="end_day" value="<?php echo $end_day; ?>">
<a class="btn btn_03 set_day" data-date="today">오늘</a>
<a class="btn btn_03 set_day" data-date="week">이번주</a>
<a class="btn btn_03 set_day" data-date="month">이번달</a>
<a class="btn btn_03 set_day" data-date="7day">1주일</a>
<a class="btn btn_03 set_day" data-date="15day">15일</a>
<a class="btn btn_03 set_day" data-date="30day">1개월</a>
<a class="btn btn_03 set_day" data-date="60day">3개월</a>
<a class="btn btn_03 set_day" data-date="120day">6개월</a>
&nbsp;
<button type="submit" class="btn_submit btn">검색</button>
<button type="button" class="btn" onclick="$('#statisticsSearchFrm').get(0).reset();">초기화</button>
</dl>
</form>
</dl>
</div>
<!-- 💡 [핵심 추가] 차트 종류 선택 UI -->
<div id="chart-type-selector" class="local_sch01 local_sch">
<strong>차트 모양</strong>
<a class="btn btn_03 chart-btn active" data-chart-type="bar">세로막대</a>
<a class="btn btn_03 chart-btn" data-chart-type="line">선그래프</a>
<a class="btn btn_03 chart-btn" data-chart-type="pie">원형</a>
<a class="btn btn_03 chart-btn" data-chart-type="doughnut">도넛</a>
<a class="btn btn_03 chart-btn" data-chart-type="radar">레이더</a>
</div>
<dl class="ntlt lnb_col"><img src="img/bul_10.png" class="t"> <?php echo $page_title; ?></dl>
<div class="chart-container">
<canvas id="myChart"></canvas>
</div>
<table width="100%" class="access ttlt tf">
<colgroup>
<col width="200">
<col>
<col width="100">
<col width="100">
</colgroup>
<thead>
<tr class="bg">
<th>항목</th>
<th>그래프</th>
<th>방문자수</th>
<th>비율(%)</th>
</tr>
</thead>
<tbody>
<?php
if (count($list)) {
foreach ($list as $row) {
$key = $row['key'] ?: '알수없음';
if ($type == 'week') {
$week_name = ['월', '화', '수', '목', '금', '토', '일'];
$key = isset($week_name[$row['key']]) ? $week_name[$row['key']] : '알수없음';
}
$rate = ($sum_count > 0) ? $row['cnt'] / $sum_count * 100 : 0;
$bar_width = ($max > 0) ? $row['cnt'] / $max * 100 : 0;
$chart_data['labels'][] = $key;
$chart_data['datasets'][0]['data'][] = $row['cnt'];
?>
<tr>
<td class="ct"><?php echo $key; ?></td>
<td><div class="graph"><span class="bar" style="width:<?php echo $bar_width; ?>%"></span></div></td>
<td class="rt"><?php echo number_format($row['cnt']); ?></td>
<td class="rt"><?php echo number_format($rate, 1); ?></td>
</tr>
<?php
}
} else {
echo '<tr><td colspan="4" class="empty_table">데이터가 없습니다.</td></tr>';
}
?>
</tbody>
</table>
<?php endif; ?>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
$(function(){
$(".hasDatepicker").datepicker({
dateFormat: "yy-mm-dd"
});
$('.set_day').click(function(){
var term = $(this).data('date');
var today = new Date();
var start_day, end_day;
end_day = $.datepicker.formatDate('yy-mm-dd', today);
switch(term) {
case 'today':
start_day = end_day;
break;
case 'week':
today.setDate(today.getDate() - today.getDay() + (today.getDay() === 0 ? -6 : 1));
start_day = $.datepicker.formatDate('yy-mm-dd', today);
break;
case 'month':
start_day = $.datepicker.formatDate('yy-mm-01', today);
break;
default:
var days = parseInt(term.replace('day', ''));
today.setDate(today.getDate() - (days - 1));
start_day = $.datepicker.formatDate('yy-mm-dd', today);
break;
}
$('#start_day').val(start_day);
$('#end_day').val(end_day);
// 💡 [핵심 수정] 선택된 버튼 스타일 적용
$('.set_day').removeClass('active');
$(this).addClass('active');
});
// 💡 [핵심 수정] 차트 생성 및 변경 로직
var chartData = <?php echo json_encode($chart_data); ?>;
var defaultChartType = '<?php echo $chart_type; ?>';
var ctx = document.getElementById('myChart');
var myChart;
function createChart(type) {
if (myChart) {
myChart.destroy();
}
if(ctx && chartData.labels.length > 0) {
// 💡 [핵심 수정] 원형/도넛 차트용 색상 배열 생성
if (['pie', 'doughnut', 'radar'].includes(type)) {
const colors = [
'rgba(255, 99, 132, 0.5)', 'rgba(54, 162, 235, 0.5)', 'rgba(255, 206, 86, 0.5)',
'rgba(75, 192, 192, 0.5)', 'rgba(153, 102, 255, 0.5)', 'rgba(255, 159, 64, 0.5)',
'rgba(255, 99, 132, 0.8)', 'rgba(54, 162, 235, 0.8)', 'rgba(255, 206, 86, 0.8)',
'rgba(75, 192, 192, 0.8)'
];
chartData.datasets[0].backgroundColor = colors;
} else {
chartData.datasets[0].backgroundColor = 'rgba(54, 162, 235, 0.5)';
}
myChart = new Chart(ctx, {
type: type,
data: {
labels: chartData.labels,
datasets: chartData.datasets
},
options: {
scales: { y: { beginAtZero: true } }
}
});
}
}
// 초기 차트 생성
createChart('bar');
// 차트 종류 변경 버튼 이벤트
$('.chart-btn').click(function(){
var chartType = $(this).data('chart-type');
createChart(chartType);
$('.chart-btn').removeClass('active');
$(this).addClass('active');
});
});
</script>
<?php
include_once(G5_ADMIN_PATH.'/admin.tail.php');
?>