/** * 图表通用工具函数 * * 包含图表初始化、技术指标管理等通用逻辑 */ import type { Chart, ActionType } from 'klinecharts'; /** * 安全地执行图表操作(捕获异常) * * @param operation 操作名称 * @param fn 执行函数 * @returns T | null 执行结果或 null */ export const safeChartOperation = ( operation: string, fn: () => T ): T | null => { try { return fn(); } catch (error) { return null; } }; /** * 创建技术指标 * * @param chart KLineChart 实例 * @param indicatorName 指标名称(如 'MA', 'MACD', 'VOL') * @param params 指标参数(可选) * @param isStack 是否叠加(主图指标为 true,副图为 false) * @returns string | null 指标 ID */ export const createIndicator = ( chart: Chart, indicatorName: string, params?: number[], isStack: boolean = false ): string | null => { return safeChartOperation(`createIndicator:${indicatorName}`, () => { const indicatorId = chart.createIndicator( { name: indicatorName, ...(params && { calcParams: params }), }, isStack ); return indicatorId; }); }; /** * 移除技术指标 * * @param chart KLineChart 实例 * @param indicatorId 指标 ID(不传则移除所有指标) */ export const removeIndicator = (chart: Chart, indicatorId?: string): void => { safeChartOperation('removeIndicator', () => { if (indicatorId) { chart.removeIndicator({ id: indicatorId }); } else { chart.removeIndicator({}); } }); }; /** * 批量创建副图指标 * * @param chart KLineChart 实例 * @param indicators 指标名称数组 * @returns string[] 指标 ID 数组 */ export const createSubIndicators = ( chart: Chart, indicators: string[] ): string[] => { const ids: string[] = []; indicators.forEach((name) => { const id = createIndicator(chart, name, undefined, false); if (id) { ids.push(id); } }); return ids; }; /** * 设置图表缩放级别 * * @param chart KLineChart 实例 * @param zoom 缩放级别(0.5 - 2.0) */ export const setChartZoom = (chart: Chart, zoom: number): void => { safeChartOperation('setChartZoom', () => { // KLineChart 10.0: 使用 setBarSpace 方法调整 K 线宽度(实现缩放效果) const baseBarSpace = 8; // 默认 K 线宽度(px) const newBarSpace = Math.max(4, Math.min(16, baseBarSpace * zoom)); // 注意:KLineChart 10.0 可能没有直接的 zoom API,需要通过调整样式实现 chart.setStyles({ candle: { bar: { upBorderColor: undefined, // 保持默认 upColor: undefined, downBorderColor: undefined, downColor: undefined, }, // 通过调整蜡烛图宽度实现缩放效果 tooltip: { showRule: 'always', }, }, }); }); }; /** * 滚动到指定时间 * * @param chart KLineChart 实例 * @param timestamp 目标时间戳 */ export const scrollToTimestamp = (chart: Chart, timestamp: number): void => { safeChartOperation('scrollToTimestamp', () => { // KLineChart 10.0: 使用 scrollToTimestamp 方法 chart.scrollToTimestamp(timestamp); }); }; /** * 调整图表大小(响应式) * * @param chart KLineChart 实例 */ export const resizeChart = (chart: Chart): void => { safeChartOperation('resizeChart', () => { chart.resize(); }); }; /** * 获取图表可见数据范围 * * @param chart KLineChart 实例 * @returns { from: number, to: number } | null 可见范围 */ export const getVisibleRange = (chart: Chart): { from: number; to: number } | null => { return safeChartOperation('getVisibleRange', () => { const data = chart.getDataList(); if (!data || data.length === 0) { return null; } // 简化实现:返回所有数据范围 // 实际项目中可通过 chart 的内部状态获取可见范围 return { from: 0, to: data.length - 1, }; }); }; /** * 清空图表数据 * * @param chart KLineChart 实例 */ export const clearChartData = (chart: Chart): void => { safeChartOperation('clearChartData', () => { chart.resetData(); }); }; /** * 截图(导出图表为图片) * * @param chart KLineChart 实例 * @param includeOverlay 是否包含 overlay * @returns string | null Base64 图片数据 */ export const exportChartImage = ( chart: Chart, includeOverlay: boolean = true ): string | null => { return safeChartOperation('exportChartImage', () => { // KLineChart 10.0: 使用 getConvertPictureUrl 方法 const imageData = chart.getConvertPictureUrl(includeOverlay, 'png', '#ffffff'); return imageData; }); }; /** * 切换十字光标显示 * * @param chart KLineChart 实例 * @param show 是否显示 */ export const toggleCrosshair = (chart: Chart, show: boolean): void => { safeChartOperation('toggleCrosshair', () => { chart.setStyles({ crosshair: { show, }, }); }); }; /** * 切换网格显示 * * @param chart KLineChart 实例 * @param show 是否显示 */ export const toggleGrid = (chart: Chart, show: boolean): void => { safeChartOperation('toggleGrid', () => { chart.setStyles({ grid: { show, }, }); }); }; /** * 订阅图表事件 * * @param chart KLineChart 实例 * @param eventName 事件名称 * @param handler 事件处理函数 */ export const subscribeChartEvent = ( chart: Chart, eventName: ActionType, handler: (...args: any[]) => void ): void => { safeChartOperation(`subscribeChartEvent:${eventName}`, () => { chart.subscribeAction(eventName, handler); }); }; /** * 取消订阅图表事件 * * @param chart KLineChart 实例 * @param eventName 事件名称 * @param handler 事件处理函数 */ export const unsubscribeChartEvent = ( chart: Chart, eventName: ActionType, handler: (...args: any[]) => void ): void => { safeChartOperation(`unsubscribeChartEvent:${eventName}`, () => { chart.unsubscribeAction(eventName, handler); }); };