AquaView의 시각적 표현은 SVG 직접 조작, Recharts 쳄트, CSS 변수 기반 다크 테마 3가지 기술로 구성됩니다.
React에서 SVG를 JSX로 직접 작성하면 JavaScript로 연동된 동적 벡터 그래픽을 만들 수 있습니다.
5개 공정 박스를 SVG 너비를 동등분해 배치합니다:
const svgWidth = 700;
const slotW = svgWidth / STAGES.length; // 공정 1개당 너비 = 140px
// i번째 공정의 중심
const centerX = slotW * i + slotW / 2;
const boxW = slotW * 0.7; // 공정 박스 너비
<defs>
<linearGradient id="flowGrad" x1="0" x2="1" y1="0" y2="0">
<stop offset="0%" stopColor="#3b82f6" stopOpacity="0" />
<stop offset="50%" stopColor="#3b82f6" stopOpacity="0.8" />
<stop offset="100%" stopColor="#3b82f6" stopOpacity="0" />
<animateTransform
attributeName="gradientTransform"
type="translate"
from="-1 0" to="1 0"
dur="2s" repeatCount="indefinite"
/>
</linearGradient>
</defs>
animateTransform으로 그라디언트를 좌우로 이동시켜 정수가 흑러가는 듯한 시각 효과를 연출합니다.
<defs>
<marker id="arrowhead" markerWidth="8" markerHeight="8"
refX="6" refY="4" orient="auto">
<polygon points="0 0, 8 4, 0 8" fill="#475569" />
</marker>
</defs>
{/* 연결선에 화살표 적용 */}
<line
x1={prevCenterX + boxW / 2}
x2={centerX - boxW / 2}
y1={centerY} y2={centerY}
stroke="#334155"
markerEnd="url(#arrowhead)"
/>
const isSelected = stage.key === selectedStage;
const statusColor = getStatusColor(stageStatus); // normal/warning/danger → 색상
<g onClick={() => onSelectStage(stage.key)} style={{ cursor: "pointer" }}>
<rect
fill={`${stage.color}22`} // 헥사 컬러 16진수 투명도 (22 = 13%)
stroke={isSelected ? stage.color : "transparent"}
strokeWidth={isSelected ? 2 : 0}
/>
{/* 위험/경고 아이콘 */}
{stageStatus !== "normal" && (
<text fill={statusColor} fontSize="14">⚠</text>
)}
</g>
// HistoryChart.jsx
import {
LineChart, Line, XAxis, YAxis,
CartesianGrid, Tooltip, ReferenceLine, ResponsiveContainer
} from "recharts";
return (
<ResponsiveContainer width="100%" height={220}>
<LineChart data={history?.data ?? []}>
<CartesianGrid strokeDasharray="3 3" stroke="#334155" />
<XAxis
dataKey="timestamp"
tickFormatter={(v) => new Date(v).toLocaleTimeString("ko", { hour: "2-digit", minute: "2-digit" })}
/>
<YAxis domain={["auto", "auto"]} />
{/* 다크 테마 Tooltip */}
<Tooltip
contentStyle={{
background: "#1e293b",
border: "1px solid #334155",
color: "#e2e8f0",
}}
/>
{/* 정상 범위 기준선 */}
<ReferenceLine y={config.normal[0]} stroke="#22c55e" strokeDasharray="4 4"
label={{ value: "정상 하한", fill: "#22c55e", fontSize: 10 }} />
<ReferenceLine y={config.normal[1]} stroke="#22c55e" strokeDasharray="4 4"
label={{ value: "정상 상한", fill: "#22c55e", fontSize: 10 }} />
<Line
dataKey="value"
stroke="#38bdf8"
dot={false} // 각 포인트 컴 제거 (시각 포켬, 성능 향상)
activeDot={{ r: 4 }} // 호버 시만 컴 표시
strokeWidth={2}
isAnimationActive={false} // 폴링 업데이트 시 쳨리면성 낭매는 현상 방지
/>
</LineChart>
</ResponsiveContainer>
);
isAnimationActive={false}: 3초마다 데이터가 갱신되면 차트가 매번 애니메이션을 재시작하는 현상을 방지합니다.