Deploy to git-pages / deploy (push) Successful in 12s
The district-name watermark inside the arrests-over-time chart was redundant with the page's own heading and was the direct cause of a label collision (a high point's rate label rendered on top of it). Removes it. Two more collisions, both edge cases the screenshot happened to hit: the first wave's label sat close enough to the plot's top that it could overlap the topmost gridline text, and a point sitting flush on the plot's left edge had its center-anchored label bleed into the y-axis tick labels. Fixes both with more vertical clearance and edge-aware text anchoring (first point anchors right, last point anchors left, matching the same fix already applied to chart 4's wave ticks before that chart was cut). Adds a shared niceTicks() utility (Heckbert's nice-numbers algorithm) so axis ticks read as round numbers (0/100/200) instead of arbitrary fractions of the data max (0/113/226/339) — applied to all three charts for consistency. Also fixes a legend/mark mismatch in the arrests-over-time chart (the modeled series legend showed a diamond; the actual mark is a dot) by adding a proper 'dot' shape to ChartLegend. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
44 lines
1.6 KiB
React
44 lines
1.6 KiB
React
/**
|
|
* Plain-HTML chart legend — replaces every chart's hand-rolled SVG legend.
|
|
* Both of the app's stray-`}` CSS bugs lived inside hand-written SVG legend
|
|
* `fill="..."` strings; keeping legends out of SVG removes that bug class.
|
|
*
|
|
* items: [{ color, label, shape: 'swatch' | 'diamond' | 'line' | 'dot' }]
|
|
*/
|
|
export default function ChartLegend({ items }) {
|
|
return (
|
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '1.25rem', marginTop: 'var(--space-2)' }}>
|
|
{items.map((item) => (
|
|
<div key={item.label} style={{ display: 'flex', alignItems: 'center', gap: '0.4rem' }}>
|
|
<LegendMark shape={item.shape} color={item.color} />
|
|
<span style={{ fontSize: '0.8rem', color: 'var(--cv-ink-2)' }}>{item.label}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function LegendMark({ shape, color }) {
|
|
if (shape === 'diamond') {
|
|
return (
|
|
<span
|
|
style={{
|
|
display: 'inline-block',
|
|
width: '9px',
|
|
height: '9px',
|
|
background: color,
|
|
transform: 'rotate(45deg)',
|
|
flexShrink: 0,
|
|
}}
|
|
/>
|
|
)
|
|
}
|
|
if (shape === 'line') {
|
|
return <span style={{ display: 'inline-block', width: '16px', height: '3px', background: color, borderRadius: '2px', flexShrink: 0 }} />
|
|
}
|
|
if (shape === 'dot') {
|
|
return <span style={{ display: 'inline-block', width: '10px', height: '10px', background: color, borderRadius: '50%', flexShrink: 0 }} />
|
|
}
|
|
return <span style={{ display: 'inline-block', width: '11px', height: '11px', background: color, borderRadius: '3px', flexShrink: 0 }} />
|
|
}
|