简介
该 React 组件封装 TradingView Charting Library,并一次性加入 iC Candle 的 形态扫描器、结果 iframe、形态追踪 与 新闻/事件 集成。
以 ESM 与 CommonJS 发布;组件样式在运行时打包并注入(无需单独导入 CSS)。
| 界面 | 作用 |
|---|---|
| 扫描器弹窗 | 覆盖在图表上的可拖动浮层。通过组件管理的 date_range 选择器选择 K 线窗口,然后执行扫描或订阅形态提醒。 |
| 结果 iframe | 宿主持有的并排面板,指向 iC Candle 嵌入应用(embed-iccandle-app.iccandle.ai)— 搜索结果、相似事件、登录与计费。通过 submitCallback 导航;使用 header=false 可隐藏嵌入顶栏。 |
| 图表同步 | 双向 postMessage 桥接:形态选择、图表回放、新闻标记、登录令牌、加载状态、定价、图表周期。 |
安装
npm install @iccandle/reactjs-widget
# 或
pnpm add @iccandle/reactjs-widget
前提条件
| 要求 | 说明 |
|---|---|
| React 18+ | react 与 react-dom 为 peer 依赖 — 请在应用中安装。 |
| TradingView Charting Library | 从 TradingView 获取,托管静态资源(例如 public 下的 /charting_library/),并自行初始化图表。本包不包含图表库。 |
快速开始
import { useCallback, useEffect, useRef, useState } from "react";
import type {
ChartingLibraryWidgetOptions,
IChartingLibraryWidget,
ResolutionString,
} from "charting_library/charting_library";
import { widget } from "charting_library/charting_library";
import {
WidgetIccandle,
withPlayChart,
getCustomIndicators,
handleResultIframeLoad,
WIDGET_RESULT_URL,
} from "@iccandle/reactjs-widget";
const LIBRARY_PATH = "/charting_library/";
function App() {
const containerRef = useRef<HTMLDivElement>(null);
const resultIframeRef = useRef<HTMLIFrameElement | null>(null);
const [chartWidget, setChartWidget] = useState<IChartingLibraryWidget | null>(
null,
);
const [iframeSrc, setIframeSrc] = useState(
`${WIDGET_RESULT_URL}/zh?theme=light&header=false`,
);
const [iframeLoaded, setIframeLoaded] = useState(false);
const submitCallback = useCallback((nextSrc: string) => {
const url = new URL(nextSrc);
url.searchParams.set("header", "false");
setIframeSrc((prev) => (prev === url.toString() ? prev : url.toString()));
}, []);
const handleIframeLoad = useCallback(() => {
setIframeLoaded(true);
handleResultIframeLoad(resultIframeRef.current);
}, []);
return (
<div className="iccandle-selector-widget__container">
<div className="iccandle-selector-widget__chart-pane">
<WidgetIccandle
chartWidget={chartWidget}
submitCallback={submitCallback}
theme="light"
language="zh"
iframeLoaded={iframeLoaded}
resultIframeRef={resultIframeRef}
>
<ChartHost
containerRef={containerRef}
onReady={setChartWidget}
/>
</WidgetIccandle>
</div>
<iframe
ref={resultIframeRef}
src={iframeSrc}
className="iccandle-selector-widget__iframe"
title="iC Candle results"
onLoad={handleIframeLoad}
/>
</div>
);
}
function ChartHost({
containerRef,
onReady,
}: {
containerRef: React.RefObject<HTMLDivElement | null>;
onReady: (w: IChartingLibraryWidget | null) => void;
}) {
useEffect(() => {
const el = containerRef.current;
if (!el) return;
const options: ChartingLibraryWidgetOptions = {
container: el,
library_path: LIBRARY_PATH,
symbol: "EURUSD",
interval: "60" as ResolutionString,
datafeed: withPlayChart(yourDatafeed), // 启用图表回放注入
locale: "zh",
autosize: true,
drawings_access: {
type: "black",
tools: [{ name: "Date Range" }],
},
custom_indicators_getter: () => getCustomIndicators("light"),
};
const tv = new widget(options);
onReady(tv);
return () => {
try {
tv.remove();
} catch {
/* no-op */
}
onReady(null);
};
}, [containerRef, onReady]);
return <div ref={containerRef} style={{ height: "100%", width: "100%" }} />;
}
传入 resultIframeRef,并在 iframe 加载时调用 handleResultIframeLoad,以便嵌入端收到宿主 origin(登录后才能正确写入 iccandle_token),以及 Stripe ?payment=success 返回后刷新订阅状态。
典型流程
- 用户激活扫描器并调整 K 线窗口(组件在图表上管理
date_range形状)。 - 扫描器缓存所选 K 线,并通过
submitCallback传入嵌入 URL(宿主设置结果 iframe 的src;使用header=false可隐藏嵌入顶栏)。 - 嵌入应用返回匹配结果;选择形态后会在图表上重绘区间。回放 / 新闻流程通过自定义指标注入预测 K 线。