모의투자, 백테스팅 레이아웃 수정
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user