일목균형표 수정
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import type { ChartManager } from '../utils/ChartManager';
|
||||
import type { ChartPaneSeparatorOptions } from '../types/chartPaneSeparator';
|
||||
import { plotColorCss } from '../utils/plotColorUtils';
|
||||
|
||||
interface Props {
|
||||
manager: ChartManager;
|
||||
options: ChartPaneSeparatorOptions;
|
||||
}
|
||||
|
||||
function applyLineDash(ctx: CanvasRenderingContext2D, style: ChartPaneSeparatorOptions['lineStyle']) {
|
||||
if (style === 'dashed') ctx.setLineDash([6, 4]);
|
||||
else if (style === 'dotted') ctx.setLineDash([2, 3]);
|
||||
else ctx.setLineDash([]);
|
||||
}
|
||||
|
||||
const PaneSeparatorOverlay: React.FC<Props> = ({ manager, options }) => {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||
|
||||
const redraw = useCallback(() => {
|
||||
const canvas = canvasRef.current;
|
||||
const container = manager.getContainer();
|
||||
if (!canvas || !container) return;
|
||||
|
||||
const cssW = container.clientWidth;
|
||||
const cssH = container.clientHeight;
|
||||
if (cssW <= 0 || cssH <= 0) return;
|
||||
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
canvas.width = Math.round(cssW * dpr);
|
||||
canvas.height = Math.round(cssH * dpr);
|
||||
canvas.style.width = `${cssW}px`;
|
||||
canvas.style.height = `${cssH}px`;
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) return;
|
||||
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();
|
||||
}
|
||||
}, [manager, options]);
|
||||
|
||||
useEffect(() => {
|
||||
redraw();
|
||||
const unsub = manager.subscribePaneLayout(redraw);
|
||||
const container = manager.getContainer();
|
||||
const ro = new ResizeObserver(() => redraw());
|
||||
if (container) ro.observe(container);
|
||||
return () => {
|
||||
unsub();
|
||||
ro.disconnect();
|
||||
};
|
||||
}, [manager, redraw]);
|
||||
|
||||
return (
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
className="pane-separator-overlay"
|
||||
aria-hidden
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
pointerEvents: 'none',
|
||||
zIndex: 4,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default PaneSeparatorOverlay;
|
||||
Reference in New Issue
Block a user