모의투자, 백테스팅 레이아웃 수정

This commit is contained in:
Macbook
2026-05-24 20:13:21 +09:00
parent 958b813f3b
commit af230a4233
23 changed files with 2394 additions and 782 deletions
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
ReactFlow,
Background,
@@ -54,6 +54,11 @@ import { StrategyFlowEdge } from './StrategyFlowEdge';
import { edgeDisconnectRef, edgeBindingUpdateRef, layoutFlushRef } from './strategyEditorCallbacks';
import { MultiSelectionDeleteButton } from './MultiSelectionDeleteButton';
import { getMinimapColors } from './minimapTheme';
import {
loadCanvasInteractionMode,
saveCanvasInteractionMode,
type StrategyCanvasInteractionMode,
} from '../../utils/strategyCanvasInteractionStorage';
import type { FlowLayoutChangePayload } from '../../utils/strategyEditorLayoutStorage';
export type FlowLayoutSeed = {
@@ -190,6 +195,14 @@ function StrategyEditorCanvasInner({
const structureKeyRef = useRef<string | null>(null);
const orphanKeyRef = useRef<string | null>(null);
const layoutEmitTimerRef = useRef<number | null>(null);
const [interactionMode, setInteractionMode] = useState<StrategyCanvasInteractionMode>(
() => loadCanvasInteractionMode(),
);
const handleInteractionModeChange = useCallback((mode: StrategyCanvasInteractionMode) => {
setInteractionMode(mode);
saveCanvasInteractionMode(mode);
}, []);
const [nodes, setNodes, onNodesChangeBase] = useNodesState<Node>([]);
const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>([]);
@@ -839,7 +852,7 @@ function StrategyEditorCanvasInner({
return (
<div
className={`se-canvas-wrap se-canvas-wrap--${signalTab}`}
className={`se-canvas-wrap se-canvas-wrap--${signalTab} se-canvas-wrap--${interactionMode}`}
onKeyDown={onKeyDown}
tabIndex={0}
>
@@ -865,9 +878,9 @@ function StrategyEditorCanvasInner({
nodesDraggable
nodesConnectable
elementsSelectable
selectionOnDrag
selectionOnDrag={interactionMode === 'select'}
selectionMode={SelectionMode.Partial}
panOnDrag={[1, 2]}
panOnDrag={interactionMode === 'pan' ? true : [1, 2]}
selectNodesOnDrag={false}
multiSelectionKeyCode={['Meta', 'Control', 'Shift']}
deleteKeyCode={null}
@@ -893,8 +906,28 @@ function StrategyEditorCanvasInner({
/>
<Panel position="top-left" className="se-canvas-toolbar">
<span className="se-canvas-toolbar-title"> </span>
<div className="se-canvas-interaction" role="group" aria-label="캔버스 조작 모드">
<button
type="button"
className={`se-canvas-interaction-btn${interactionMode === 'pan' ? ' se-canvas-interaction-btn--on' : ''}`}
title="빈 영역 드래그로 그래프 이동"
onClick={() => handleInteractionModeChange('pan')}
>
</button>
<button
type="button"
className={`se-canvas-interaction-btn${interactionMode === 'select' ? ' se-canvas-interaction-btn--on' : ''}`}
title="드래그로 전략 요소 다중 선택"
onClick={() => handleInteractionModeChange('select')}
>
</button>
</div>
<span className="se-canvas-toolbar-hint">
× · × · Del
{interactionMode === 'pan'
? '빈 영역 드래그 → 그래프 이동 · 노드 드래그 → 위치 변경'
: '빈 영역 드래그 → 다중 선택 · Del 삭제 · 연결선 × 끊기'}
{orphans.length > 0 ? ` · 미연결 ${orphans.length}` : ''}
</span>
</Panel>