UI 개선 — 모바일 사진 업로드 카메라/갤러리 버튼 분리, 에러코드 차트 단순화

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
byun
2026-06-01 16:25:48 +09:00
parent d75bd5f358
commit e52e916dc8
5 changed files with 70 additions and 99 deletions

View File

@@ -231,7 +231,7 @@
<div class="card" style="margin-bottom:20px">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;flex-wrap:wrap;gap:8px">
<div class="card-title" style="margin:0">⚠️ 에러코드 누적 순위 Top 10</div>
<span style="font-size:11px;color:var(--gray4)">에러코드 입력된 신고 기준 · 색상 = 충전기</span>
<span style="font-size:11px;color:var(--gray4)">에러코드 입력된 신고 기준</span>
</div>
<div id="errorCodesChartWrap" style="position:relative">
<canvas id="errorCodesChart"></canvas>
@@ -645,48 +645,38 @@ async function loadErrorCodesChart() {
wrap.innerHTML = '<div style="color:var(--gray4);font-size:13px;text-align:center;padding:30px 0">에러코드가 입력된 신고가 없습니다.</div>';
return;
}
const { error_codes, charger_labels, dataset_keys } = data;
const CHARGER_COLORS = ['#3B82F6','#EF4444','#F59E0B','#10B981','#8B5CF6','#94A3B8'];
wrap.style.height = (error_codes.length * 32 + 50) + 'px';
const { error_codes } = data;
wrap.style.height = (error_codes.length * 34 + 40) + 'px';
if (_errorCodesChart) _errorCodesChart.destroy();
const ctx = document.getElementById('errorCodesChart').getContext('2d');
_errorCodesChart = new Chart(ctx, {
type: 'bar',
data: {
labels: error_codes.map(e => e.error_code),
datasets: dataset_keys.map((key, i) => ({
label: charger_labels[key],
data: error_codes.map(e => e[key] || 0),
backgroundColor: CHARGER_COLORS[i % CHARGER_COLORS.length],
borderRadius: 3,
stack: 'err',
}))
datasets: [{
data: error_codes.map(e => e.total),
backgroundColor: '#1565C0',
borderRadius: 4,
}]
},
options: {
indexAxis: 'y',
responsive: true,
maintainAspectRatio: false,
onHover: (evt, elems) => { evt.native.target.style.cursor = elems.length ? 'pointer' : 'default'; },
plugins: {
legend: { display: true, position: 'top',
labels: { font: { size: 11 }, boxWidth: 12, boxHeight: 12, padding: 12 } },
legend: { display: false },
tooltip: {
callbacks: {
title: items => {
const e = error_codes[items[0].dataIndex];
return `에러코드: ${e.error_code} (총 ${e.total}건)`;
},
label: c => `${c.dataset.label}: ${c.raw}`,
title: items => `에러코드: ${error_codes[items[0].dataIndex].error_code}`,
label: c => `누적 ${c.raw}`,
}
}
},
scales: {
x: { stacked: true, grid: { color: '#F1F5F9' }, border: { dash: [3,3] },
beginAtZero: true,
ticks: { font: { size: 11 }, color: '#64748B', stepSize: 1,
x: { beginAtZero: true, grid: { color: '#F1F5F9' }, border: { dash: [3,3] },
ticks: { font: { size: 11 }, color: '#64748B',
callback: v => Number.isInteger(v) ? v + '건' : '' } },
y: { stacked: true, grid: { display: false },
y: { grid: { display: false },
ticks: { font: { size: 12 }, color: '#334155' } }
}
}