feat(review): 요약 패널 그래프 단독화 + 카드 6축 미터바를 제목행으로 이동
- 요약(상단) 패널: 육각 그래프에 이미 축명/점수 라벨이 표시되므로 옆의 범례(미터바)를 제거하고 그래프만 중앙 배치 (buildRadarLegend 호출 삭제) - 리뷰 카드: 컴팩트 육각 아이콘 + sr-only 범례를 걷어내고, 닉네임 옆 제목행에 6축 미니 세로 미터바(game-reviews__title-meter)를 노출 — 4개 배치 샘플(Artifact)을 사용자가 검토 후 C안(타이틀 내부 통합형) 선택 - buildRadarLegend/.game-reviews__axis-legend*/.game-reviews__card-radar 등 완전히 죽은 코드 제거 검증: node --check (스크립트 블록, JSP EL 치환) 통과, docker compose app 재기동 후 /game/3 실제 렌더 확인(요약 그래프 중앙 단독, 카드 6곳 모두 제목행 미터바 노출), 콘솔 에러 없음. 자동화 테스트 대상 아님(순수 뷰/JS, 서버 로직·매퍼 변경 없음). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011h6etRXJLx1xdfxmVcHjBg
This commit is contained in:
parent
f086b12142
commit
0c8da405e7
|
|
@ -998,6 +998,7 @@
|
|||
margin: 0 0 1.25rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1.25rem;
|
||||
padding: 1rem 1.25rem;
|
||||
background:
|
||||
|
|
@ -1081,75 +1082,38 @@
|
|||
font-size: 0.75rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.game-reviews__axis-legend {
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
min-width: 11.5rem;
|
||||
display: grid;
|
||||
gap: 0.4rem 0;
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-muted);
|
||||
.game-reviews__title-meter {
|
||||
display: inline-flex;
|
||||
align-items: flex-end;
|
||||
gap: 0.15rem;
|
||||
height: 0.95rem;
|
||||
}
|
||||
.game-reviews__axis-legend-row {
|
||||
display: grid;
|
||||
grid-template-columns: 3.4rem 1fr 1.15rem;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
}
|
||||
.game-reviews__axis-legend dt {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.game-reviews__axis-legend dd {
|
||||
margin: 0;
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: 700;
|
||||
text-align: right;
|
||||
color: var(--accent);
|
||||
}
|
||||
.game-reviews__axis-meter {
|
||||
.game-reviews__title-meter .stick {
|
||||
position: relative;
|
||||
height: 0.4rem;
|
||||
border-radius: 999px;
|
||||
width: 0.2rem;
|
||||
height: 100%;
|
||||
border-radius: 2px;
|
||||
background: var(--border);
|
||||
overflow: hidden;
|
||||
}
|
||||
.game-reviews__axis-meter::before {
|
||||
content: '';
|
||||
.game-reviews__title-meter .stick span {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 2;
|
||||
pointer-events: none;
|
||||
background-image: repeating-linear-gradient(90deg,
|
||||
transparent 0, transparent calc(20% - 1px),
|
||||
rgba(255, 255, 255, 0.45) calc(20% - 1px), rgba(255, 255, 255, 0.45) 20%);
|
||||
mix-blend-mode: overlay;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
border-radius: 2px;
|
||||
background: linear-gradient(180deg, #f0c978, var(--accent));
|
||||
animation: game-title-meter-grow 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
|
||||
transform-origin: bottom;
|
||||
}
|
||||
.game-reviews__axis-meter span {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: block;
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, #f0c978, var(--accent));
|
||||
animation: game-meter-grow 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
|
||||
transform-origin: left;
|
||||
}
|
||||
@keyframes game-meter-grow {
|
||||
from { transform: scaleX(0); }
|
||||
to { transform: scaleX(1); }
|
||||
@keyframes game-title-meter-grow {
|
||||
from { transform: scaleY(0); }
|
||||
to { transform: scaleY(1); }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.game-reviews__radar .game-axis-poly,
|
||||
.game-reviews__radar .game-axis-dot,
|
||||
.game-reviews__axis-meter span { animation: none; }
|
||||
}
|
||||
.game-reviews__card-radar {
|
||||
margin-top: 0.6rem;
|
||||
display: inline-flex;
|
||||
}
|
||||
.game-reviews__card-radar svg {
|
||||
display: block;
|
||||
.game-reviews__title-meter .stick span { animation: none; }
|
||||
}
|
||||
|
||||
/* ── sort 토글 / 더보기 ──────────────────────────────── */
|
||||
|
|
@ -1756,28 +1720,29 @@
|
|||
return { svg: svg, nums: nums, hasData: hasData };
|
||||
}
|
||||
|
||||
// 시각 보조 <dl> (축명/미터바/점수) — 폴리곤만으로 종료 금지(§6.6)
|
||||
function buildRadarLegend(nums, hasData) {
|
||||
var dl = document.createElement('dl');
|
||||
dl.className = 'game-reviews__axis-legend';
|
||||
AXIS_KEYS.forEach(function (k, i) {
|
||||
var row = document.createElement('div');
|
||||
row.className = 'game-reviews__axis-legend-row';
|
||||
var dt = document.createElement('dt');
|
||||
dt.textContent = AXIS_LABELS_KO[k];
|
||||
var meter = document.createElement('div');
|
||||
meter.className = 'game-reviews__axis-meter';
|
||||
var bar = document.createElement('span');
|
||||
bar.style.width = (hasData ? (nums[i] / 5 * 100) : 0) + '%';
|
||||
meter.appendChild(bar);
|
||||
var dd = document.createElement('dd');
|
||||
dd.textContent = hasData ? String(nums[i]) : '–';
|
||||
row.appendChild(dt);
|
||||
row.appendChild(meter);
|
||||
row.appendChild(dd);
|
||||
dl.appendChild(row);
|
||||
// 리뷰 카드 제목행 삽입용 6축 미니 미터바 — axes 없으면 null(§6.6: 그래프는 요약에만, 카드는 이 미터바로 대체)
|
||||
function buildTitleMeter(axes) {
|
||||
var nums = AXIS_KEYS.map(function (k) {
|
||||
var v = axes ? Number(axes[k]) : 0;
|
||||
return (isFinite(v) && v > 0) ? v : 0;
|
||||
});
|
||||
return dl;
|
||||
var hasData = nums.some(function (v) { return v > 0; });
|
||||
if (!hasData) return null;
|
||||
var wrap = document.createElement('div');
|
||||
wrap.className = 'game-reviews__title-meter';
|
||||
wrap.setAttribute('role', 'img');
|
||||
wrap.setAttribute('aria-label', '6축 평가: ' + AXIS_KEYS.map(function (k, i) {
|
||||
return AXIS_LABELS_KO[k] + ' ' + nums[i];
|
||||
}).join(', '));
|
||||
nums.forEach(function (v) {
|
||||
var stick = document.createElement('span');
|
||||
stick.className = 'stick';
|
||||
var fill = document.createElement('span');
|
||||
fill.style.height = (v / 5 * 100) + '%';
|
||||
stick.appendChild(fill);
|
||||
wrap.appendChild(stick);
|
||||
});
|
||||
return wrap;
|
||||
}
|
||||
|
||||
// ===== 별점 radiogroup 완전 패턴 (C6) =====
|
||||
|
|
@ -2234,6 +2199,9 @@
|
|||
mb.textContent = '내 리뷰';
|
||||
head.appendChild(mb);
|
||||
}
|
||||
// 6축 미니 미터바 — 제목행 노출(§6.6: 요약 그래프와 별개로 카드 단위 시각화)
|
||||
var titleMeter = buildTitleMeter(r.axes);
|
||||
if (titleMeter) head.appendChild(titleMeter);
|
||||
var t = document.createElement('time');
|
||||
t.className = 'game-reviews__time';
|
||||
t.dateTime = (r.updatedAt || r.createdAt) || '';
|
||||
|
|
@ -2255,25 +2223,6 @@
|
|||
li.appendChild(p);
|
||||
}
|
||||
|
||||
// 카드 컴팩트 육각형 (6축). axes null/누락 시 "데이터 없음"
|
||||
var cardScores = AXIS_KEYS.map(function (k) { return r.axes ? Number(r.axes[k]) || 0 : 0; });
|
||||
var cardRadar = buildHexRadar(cardScores, 60, 60, 44);
|
||||
var radarWrap = document.createElement('div');
|
||||
radarWrap.className = 'game-reviews__radar game-reviews__card-radar';
|
||||
if (cardRadar.hasData) {
|
||||
radarWrap.appendChild(cardRadar.svg);
|
||||
// §6.6: 폴리곤만으로 종료 금지 — 시각/스크린리더 보조 표 동반(시각적으로 숨김)
|
||||
var legend = buildRadarLegend(cardRadar.nums, true);
|
||||
legend.className += ' sr-only';
|
||||
radarWrap.appendChild(legend);
|
||||
} else {
|
||||
var none = document.createElement('span');
|
||||
none.className = 'game-reviews__radar-empty';
|
||||
none.textContent = '6축 평가 데이터 없음';
|
||||
radarWrap.appendChild(none);
|
||||
}
|
||||
li.appendChild(radarWrap);
|
||||
|
||||
if (canActOn(r.userId)) {
|
||||
var foot = document.createElement('div');
|
||||
foot.className = 'game-reviews__footer';
|
||||
|
|
@ -2322,7 +2271,6 @@
|
|||
rSummaryPanel.hidden = false;
|
||||
if (radar.hasData) {
|
||||
rSummaryRadar.appendChild(radar.svg);
|
||||
rSummaryRadar.appendChild(buildRadarLegend(radar.nums, true));
|
||||
} else {
|
||||
var none = document.createElement('span');
|
||||
none.className = 'game-reviews__radar-empty';
|
||||
|
|
|
|||
Loading…
Reference in New Issue