Skip to content

Commit 213c98f

Browse files
rdmuellerclaude
andcommitted
refactor: extract RadarChart into separate component file
Move RadarChart to src/components/RadarChart.jsx with its own CSS module. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3427e39 commit 213c98f

3 files changed

Lines changed: 41 additions & 34 deletions

File tree

src/RiskRadar.jsx

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,8 @@ import Asciidoctor from "@asciidoctor/core";
33
import T from "./i18n.js";
44
import { useTheme } from "./theme.js";
55
import { VERSION, TIER_BG, TYPE_COLORS } from "./constants.js";
6-
import { getTierIndex, polarToCartesian, detectBrowserLanguage } from "./utils.js";
7-
8-
function RadarChart({ values, dimensions, size = 320 }) {
9-
const cx = size / 2, cy = size / 2, maxR = size / 2 - 48, levels = 5, n = dimensions.length, step = 360 / n;
10-
const ti = getTierIndex(values);
11-
const tc = TIER_BG[ti];
12-
13-
return (
14-
<svg viewBox={`0 0 ${size} ${size}`} width="100%" style={{ maxWidth: size }}>
15-
{[1, 2, 3, 4, 5].map((l) => {
16-
const r = (maxR / levels) * l;
17-
const pts = Array.from({ length: n }, (_, i) => polarToCartesian(cx, cy, r, i * step));
18-
return <polygon key={l} points={pts.map((p) => `${p.x},${p.y}`).join(" ")} fill="none" stroke={l === 5 ? "var(--grid-line-outer)" : "var(--grid-line)"} strokeWidth={l === 5 ? 1.5 : 0.7} />;
19-
})}
20-
{dimensions.map((_, i) => {
21-
const p = polarToCartesian(cx, cy, maxR, i * step);
22-
return <line key={`a${i}`} x1={cx} y1={cy} x2={p.x} y2={p.y} stroke="var(--grid-line)" strokeWidth={0.7} />;
23-
})}
24-
{(() => {
25-
const pts = dimensions.map((d, i) => polarToCartesian(cx, cy, (maxR / levels) * (values[d.key] + 1), i * step));
26-
return (
27-
<>
28-
<polygon points={pts.map((p) => `${p.x},${p.y}`).join(" ")} fill={tc} fillOpacity={0.25} stroke={tc} strokeWidth={2.5} />
29-
{pts.map((p, i) => <circle key={i} cx={p.x} cy={p.y} r={5} fill={tc} stroke="var(--dot-stroke)" strokeWidth={1.5} />)}
30-
</>
31-
);
32-
})()}
33-
{dimensions.map((d, i) => {
34-
const lp = polarToCartesian(cx, cy, maxR + 26, i * step);
35-
return <text key={`l${i}`} x={lp.x} y={lp.y} textAnchor="middle" dominantBaseline="middle" fill="var(--text-secondary)" fontSize="15" fontWeight="600">{d.shortLabel}</text>;
36-
})}
37-
</svg>
38-
);
39-
}
6+
import { getTierIndex, detectBrowserLanguage } from "./utils.js";
7+
import RadarChart from "./components/RadarChart.jsx";
408

419
function MitigationCard({ group, active, accent, t }) {
4210
const [open, setOpen] = useState(false);

src/components/RadarChart.jsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { TIER_BG } from "../constants.js";
2+
import { getTierIndex, polarToCartesian } from "../utils.js";
3+
import styles from "./RadarChart.module.css";
4+
5+
export default function RadarChart({ values, dimensions, size = 320 }) {
6+
const cx = size / 2, cy = size / 2, maxR = size / 2 - 48, levels = 5, n = dimensions.length, step = 360 / n;
7+
const ti = getTierIndex(values);
8+
const tc = TIER_BG[ti];
9+
10+
return (
11+
<svg viewBox={`0 0 ${size} ${size}`} className={styles.chart} style={{ maxWidth: size }}>
12+
{[1, 2, 3, 4, 5].map((l) => {
13+
const r = (maxR / levels) * l;
14+
const pts = Array.from({ length: n }, (_, i) => polarToCartesian(cx, cy, r, i * step));
15+
return <polygon key={l} points={pts.map((p) => `${p.x},${p.y}`).join(" ")} fill="none" stroke={l === 5 ? "var(--grid-line-outer)" : "var(--grid-line)"} strokeWidth={l === 5 ? 1.5 : 0.7} />;
16+
})}
17+
{dimensions.map((_, i) => {
18+
const p = polarToCartesian(cx, cy, maxR, i * step);
19+
return <line key={`a${i}`} x1={cx} y1={cy} x2={p.x} y2={p.y} stroke="var(--grid-line)" strokeWidth={0.7} />;
20+
})}
21+
{(() => {
22+
const pts = dimensions.map((d, i) => polarToCartesian(cx, cy, (maxR / levels) * (values[d.key] + 1), i * step));
23+
return (
24+
<>
25+
<polygon points={pts.map((p) => `${p.x},${p.y}`).join(" ")} fill={tc} fillOpacity={0.25} stroke={tc} strokeWidth={2.5} />
26+
{pts.map((p, i) => <circle key={i} cx={p.x} cy={p.y} r={5} fill={tc} stroke="var(--dot-stroke)" strokeWidth={1.5} />)}
27+
</>
28+
);
29+
})()}
30+
{dimensions.map((d, i) => {
31+
const lp = polarToCartesian(cx, cy, maxR + 26, i * step);
32+
return <text key={`l${i}`} x={lp.x} y={lp.y} textAnchor="middle" dominantBaseline="middle" fill="var(--text-secondary)" fontSize="15" fontWeight="600">{d.shortLabel}</text>;
33+
})}
34+
</svg>
35+
);
36+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.chart {
2+
width: 100%;
3+
}

0 commit comments

Comments
 (0)