전략평가 수정

This commit is contained in:
Macbook
2026-06-16 15:02:59 +09:00
parent 8eb6e4d47b
commit 779bc31694
4 changed files with 182 additions and 37 deletions
+48 -16
View File
@@ -32,15 +32,18 @@ const Y_STEPS: number[] = [1, 1.5, 2, 3, 5, 8, 12];
type ResizeDir = 'nw'|'n'|'ne'|'e'|'se'|'s'|'sw'|'w';
const HANDLE_SIZE = 14;
const HANDLE_OFFSET = -Math.round(HANDLE_SIZE / 2);
const HANDLES: { id: ResizeDir; cursor: string; style: React.CSSProperties }[] = [
{ id:'nw', cursor:'nw-resize', style:{ top:-5, left:-5 } },
{ id:'n', cursor:'n-resize', style:{ top:-5, left:'50%', transform:'translateX(-50%)' } },
{ id:'ne', cursor:'ne-resize', style:{ top:-5, right:-5 } },
{ id:'e', cursor:'e-resize', style:{ top:'50%', right:-5, transform:'translateY(-50%)' } },
{ id:'se', cursor:'se-resize', style:{ bottom:-5, right:-5 } },
{ id:'s', cursor:'s-resize', style:{ bottom:-5, left:'50%',transform:'translateX(-50%)' } },
{ id:'sw', cursor:'sw-resize', style:{ bottom:-5, left:-5 } },
{ id:'w', cursor:'w-resize', style:{ top:'50%', left:-5, transform:'translateY(-50%)' } },
{ id:'nw', cursor:'nw-resize', style:{ top:HANDLE_OFFSET, left:HANDLE_OFFSET } },
{ id:'n', cursor:'n-resize', style:{ top:HANDLE_OFFSET, left:'50%', transform:'translateX(-50%)' } },
{ id:'ne', cursor:'ne-resize', style:{ top:HANDLE_OFFSET, right:HANDLE_OFFSET } },
{ id:'e', cursor:'e-resize', style:{ top:'50%', right:HANDLE_OFFSET, transform:'translateY(-50%)' } },
{ id:'se', cursor:'se-resize', style:{ bottom:HANDLE_OFFSET, right:HANDLE_OFFSET } },
{ id:'s', cursor:'s-resize', style:{ bottom:HANDLE_OFFSET, left:'50%', transform:'translateX(-50%)' } },
{ id:'sw', cursor:'sw-resize', style:{ bottom:HANDLE_OFFSET, left:HANDLE_OFFSET } },
{ id:'w', cursor:'w-resize', style:{ top:'50%', left:HANDLE_OFFSET, transform:'translateY(-50%)' } },
];
function nearestStepIndex(steps: number[], cur: number): number {
@@ -257,14 +260,12 @@ const ChartMagnifier: React.FC<ChartMagnifierProps> = ({
(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
}, []);
const onHandleMove = useCallback((e: React.PointerEvent) => {
const applyResize = useCallback((clientX: number, clientY: number) => {
const rs = resizeStart.current;
if (!rs) return;
e.preventDefault();
e.stopPropagation();
const { dir, mx, my, px, py, pw, ph } = rs;
const dx = e.clientX - mx;
const dy = e.clientY - my;
const dx = clientX - mx;
const dy = clientY - my;
let nx = px, ny = py, nw = pw, nh = ph;
if (dir.includes('e')) { nw = Math.max(MIN_W, pw + dx); }
if (dir.includes('w')) { nw = Math.max(MIN_W, pw - dx); nx = px + pw - nw; }
@@ -278,11 +279,38 @@ const ChartMagnifier: React.FC<ChartMagnifierProps> = ({
setSize({ w: nw, h: nh });
}, []);
const onHandleMove = useCallback((e: React.PointerEvent) => {
if (!resizeStart.current) return;
e.preventDefault();
e.stopPropagation();
applyResize(e.clientX, e.clientY);
}, [applyResize]);
const onHandleUp = useCallback((e: React.PointerEvent) => {
e.stopPropagation();
resizeStart.current = null;
}, []);
useEffect(() => {
if (!enabled) return;
const onWindowMove = (e: PointerEvent) => {
if (!resizeStart.current) return;
e.preventDefault();
applyResize(e.clientX, e.clientY);
};
const onWindowUp = () => {
resizeStart.current = null;
};
window.addEventListener('pointermove', onWindowMove, { passive: false });
window.addEventListener('pointerup', onWindowUp);
window.addEventListener('pointercancel', onWindowUp);
return () => {
window.removeEventListener('pointermove', onWindowMove);
window.removeEventListener('pointerup', onWindowUp);
window.removeEventListener('pointercancel', onWindowUp);
};
}, [enabled, applyResize]);
const stopChartPointer = useCallback((e: React.PointerEvent | React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
@@ -379,11 +407,15 @@ const ChartMagnifier: React.FC<ChartMagnifierProps> = ({
>×</button>
</div>
<canvas ref={canvasRef} className="chart-magnifier-canvas" />
<div className="chart-magnifier-body">
<canvas ref={canvasRef} className="chart-magnifier-canvas" />
</div>
{HANDLES.map(h => (
<div key={h.id} className="chart-magnifier-handle"
style={{ ...h.style, cursor: h.cursor, position: 'absolute', width: 10, height: 10 }}
<div
key={h.id}
className={`chart-magnifier-handle chart-magnifier-handle--${h.id}`}
style={{ ...h.style, cursor: h.cursor }}
onPointerDown={e => onHandleDown(e, h.id)}
onPointerMove={onHandleMove}
onPointerUp={onHandleUp}