보조지표 툴바추가

This commit is contained in:
Macbook
2026-05-29 23:51:13 +09:00
parent 095b0d7db7
commit 6332d198b1
11 changed files with 846 additions and 436 deletions
@@ -1,6 +1,7 @@
import React, { useCallback, useEffect, useRef } from 'react';
import type { ChartManager } from '../utils/ChartManager';
import type { ChartPaneSeparatorOptions } from '../types/chartPaneSeparator';
import type { ChartPaneSeparatorOptions, PaneSeparatorStyle } from '../types/chartPaneSeparator';
import { classifyPaneBoundary } from '../types/chartPaneSeparator';
import { plotColorCss } from '../utils/plotColorUtils';
interface Props {
@@ -8,12 +9,29 @@ interface Props {
options: ChartPaneSeparatorOptions;
}
function applyLineDash(ctx: CanvasRenderingContext2D, style: ChartPaneSeparatorOptions['lineStyle']) {
function applyLineDash(ctx: CanvasRenderingContext2D, style: PaneSeparatorStyle['lineStyle']) {
if (style === 'dashed') ctx.setLineDash([6, 4]);
else if (style === 'dotted') ctx.setLineDash([2, 3]);
else ctx.setLineDash([]);
}
function strokeBoundary(
ctx: CanvasRenderingContext2D,
cssW: number,
y: number,
style: PaneSeparatorStyle,
) {
if (!style.visible) return;
ctx.strokeStyle = plotColorCss(style.color);
ctx.lineWidth = style.width;
applyLineDash(ctx, style.lineStyle);
const lineY = y + style.width / 2;
ctx.beginPath();
ctx.moveTo(0, lineY);
ctx.lineTo(cssW, lineY);
ctx.stroke();
}
const PaneSeparatorOverlay: React.FC<Props> = ({ manager, options }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
@@ -37,24 +55,22 @@ const PaneSeparatorOverlay: React.FC<Props> = ({ manager, options }) => {
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
ctx.clearRect(0, 0, cssW, cssH);
if (!options.visible) return;
const layouts = manager.getPaneLayouts()
.filter(l => l.height > 8)
.sort((a, b) => a.topY - b.topY);
if (layouts.length < 2) return;
ctx.strokeStyle = plotColorCss(options.color);
ctx.lineWidth = options.width;
applyLineDash(ctx, options.lineStyle);
for (let i = 0; i < layouts.length - 1; i++) {
const y = layouts[i].topY + layouts[i].height;
const lineY = y + options.width / 2;
ctx.beginPath();
ctx.moveTo(0, lineY);
ctx.lineTo(cssW, lineY);
ctx.stroke();
const lower = layouts[i];
const upper = layouts[i + 1];
const kind = classifyPaneBoundary(lower.paneIndex, upper.paneIndex);
if (kind === 'other') continue;
const style = kind === 'mainToIndicator'
? options.mainToIndicator
: options.indicatorToIndicator;
const y = lower.topY + lower.height;
strokeBoundary(ctx, cssW, y, style);
}
}, [manager, options]);