VNInvestCharts SDK v3.0
v3.0.0-StableReact 19 Supported~145 KB Gzipped

Hướng Dẫn Tích Hợp & Nhúng

Tài liệu hướng dẫn chi tiết dành cho nhà phát triển về cách nhúng, cấu hình, tùy biến giao diện và tích hợp nguồn cấp dữ liệu cho biểu đồ VNInvestCharts chuyên nghiệp.

1

Các Phương Thức Nhúng Widget

Widget hỗ trợ ba kiến trúc nhúng độc lập tùy thuộc vào yêu cầu kiểm soát CSS và bảo mật của ứng dụng ký chủ (Host App):

Tích Hợp SâuReact App

React Component

Nhúng trực tiếp component vào cây React DOM của ứng dụng. Chia sẻ bộ nhớ và Context của ứng dụng Host.

Host App➔Component
✔Ưu điểm: Tích hợp sâu, hiệu năng cao nhất, dễ dàng truyền hàm callback.
✘Nhược điểm: Nguy cơ đụng độ các quy tắc CSS toàn cục.
Cô Lập CSSVanilla JS

Shadow DOM Isolation

Bọc widget trong một Shadow Root độc lập. Cách ly hoàn toàn CSS của widget khỏi ứng dụng Host.

Host➔ShadowRoot➔Widget
✔Ưu điểm: Cách ly CSS hoàn toàn, không lo đụng độ CSS làm vỡ layout.
✘Nhược điểm: Cần xử lý các sự kiện click-outside qua composedPath.
Cô Lập Tuyệt ĐốiCross-Domain

Iframe PostMessage SDK

Cách ly hoàn toàn cả mã nguồn Javascript lẫn CSS thông qua thẻ iframe bảo mật đa miền.

Host⇄[PostMsg]⇄Iframe
✔Ưu điểm: Cách ly tuyệt đối JS & CSS, bảo mật tuyệt đối đa tên miền.
✘Nhược điểm: Phải giao tiếp điều khiển bất đồng bộ qua SDK.
2

Nhúng React Component Tiêu Chuẩn

Phương pháp nhúng trực tiếp component vào cây thư mục của ứng dụng React.

Import Component và Styles

ImportStyles.tsx
import { VNInvestCharts, widgetMessagesVi, widgetMessagesEn } from "vninvestcharts-widget";

// Import stylesheet hỗ trợ giao diện đầy đủ (CSS Modules)
import "vninvestcharts-widget/dist/index.css";

Sử dụng trong Component

ChartContainer.tsx
function ChartContainer() {
  return (
    <div style={{ width: "100%", height: "600px", position: "relative" }}>
      <VNInvestCharts
        symbol="VCB"
        timeframe="1D"
        theme="dark"
        locale="vi"
        messages={widgetMessagesVi}
        drawingUiEnabled={true}
      />
    </div>
  );
}
⚠️ CHÚ Ý QUAN TRỌNG:
Đảm bảo thẻ bọc ngoài (Container) của &lt;VNInvestCharts&gt; có kích thước chiều rộng/cao xác định. Widget sử dụng ResizeObserver để co giãn tự động theo kích thước thẻ cha.
3

Nhúng Cách Ly Với Shadow DOM (Shadow DOM Isolation)

Để ngăn chặn việc CSS của biểu đồ làm vỡ layout của Host App (hoặc ngược lại), bạn có thể nhúng widget bên trong một Shadow Root.

Bản vá Cơ chế Click-Outside & Dropdown

Khi nằm trong Shadow DOM, các sự kiện click sẽ bị trình duyệt che giấu nguồn gốc (e.target trỏ vào chính shadow host). Để dropdown, ô tìm kiếm mã, và thanh công cụ vẽ hoạt động chính xác:

  1. Thư viện sử dụng e.composedPath()[0] thay vì e.target để lấy chính xác phần tử được nhấp chuột bên trong Shadow DOM.
  2. Cần dẫn truyền Shadow Root context xuống widget qua biến toàn cục window.__vnscShadowRoot hoặc thuộc tính shadowRoot.

Cấu hình Khởi tạo (IIFE Entry)

shadowDOMInit.js
// Tạo phần tử chứa widget
const hostContainer = document.getElementById("chart-widget-host");
const shadowRoot = hostContainer.attachShadow({ mode: "open" });

// 1. Inject thẻ CSS trực tiếp vào bên trong Shadow Root
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = "vninvestcharts-widget/dist/index.css";
shadowRoot.appendChild(link);

// 2. Tạo điểm gắn kết React inside Shadow DOM
const mountPoint = document.createElement("div");
mountPoint.id = "vnsc-shadow-root-mount";
shadowRoot.appendChild(mountPoint);

// 3. Khai báo biến toàn cục để thông báo ranh giới Shadow Root
window.__vnscShadowRoot = shadowRoot;

// 4. Khởi tạo Widget
window.VNInvestCharts.mount(mountPoint, {
  symbol: "VCB",
  timeframe: "1D",
  theme: "dark",
  locale: "vi",
  shadowRoot: shadowRoot // Cung cấp shadowRoot trực tiếp cho event listeners
});
4

Nhúng Qua Iframe SDK (PostMessage Bridge)

Phương pháp này cách ly hoàn toàn mã nguồn của Widget khỏi Host App. Phù hợp khi bạn nhúng biểu đồ sang một tên miền khác.

Host Application
window.postMessage()
WidgetController.setSymbol('FPT')
◀ PostMessage Bridge ▶
Asynchronous JSON
Iframe Context
chart.domain.com/iframe.html
[React Core Widget]

Bước 1: Setup File iframe.html phía Widget Server

Tệp iframe.html sẽ tải mã đóng gói dist/iframe/vnbrokerchart.iframe.js và tự động lắng nghe các lệnh điều khiển:

iframe.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>VNInvestCharts Iframe Node</title>
  <link rel="stylesheet" href="injected.css">
  <style>
    html, body, #root { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; }
  </style>
</head>
<body>
  <div id="root"></div>
  <script src="vnbrokerchart.iframe.js"></script>
</body>
</html>

Bước 2: Sử dụng Host SDK bên phía Host App

Host App sử dụng class WidgetController để giao tiếp bất đồng bộ thông qua window.postMessage:

hostSDKController.ts
import { WidgetController } from "vninvestcharts-widget/iframe";

// 1. Tạo controller trỏ tới thẻ iframe
const iframeElement = document.getElementById("my-chart-iframe") as HTMLIFrameElement;
const controller = new WidgetController({
  iframe: iframeElement,
  targetOrigin: "https://chart.domain.com", // Bảo mật: Chỉ định rõ domain nguồn của iframe
  allowAnyOrigin: false // Bắt buộc đặt false trên production để tránh tin tặc giả mạo lệnh
});

// 2. Lắng nghe các sự kiện gửi ra từ biểu đồ
controller.on("symbolChange", (data) => {
  console.log("Người dùng đổi mã trên biểu đồ sang:", data.symbol);
});

controller.on("drawingsChange", (data) => {
  console.log("Danh sách hình vẽ kỹ thuật vừa cập nhật:", data.drawings);
});

// 3. Gửi lệnh điều khiển vào biểu đồ (không cần re-render iframe)
async function updateChartState() {
  // Đổi mã
  await controller.setSymbol("FPT");
  
  // Đổi khung thời gian
  await controller.setTimeframe("15m");
  
  // Áp dụng chỉ báo
  await controller.addIndicator("StrengthRelative", { period: 14 });
}
5

Tích Hợp Data Adapter & Cơ Chế Khóa Biên Lịch Sử (Boundary Lock)

Để nạp dữ liệu nến cho biểu đồ nhúng, bạn cần cung cấp một StockDataAdapter. Bản nâng cấp v3.0 cải tiến cơ chế đối chiếu lịch sử để loại bỏ hoàn toàn hiện tượng lặp yêu cầu mạng vô hạn.

Cơ Chế Hoạt Động Của Bộ Backfill

  • Khi biểu đồ được kéo sang trái hoặc sang phải để zoom/pan, hook useWidgetDataBackfill sẽ tính toán xem khoảng thời gian hiển thị có bị thiếu nến không.
  • Nếu thiếu nến, hệ thống sẽ phát tín hiệu tải thêm qua fetchBarsBefore (lùi) hoặc fetchBarsInRange (tiến).

Điểm Cần Lưu Ý Khi Viết Adapter

Khi API của bạn đã hết sạch dữ liệu lịch sử hoặc dữ liệu thời gian thực (đã chạm biên của mã giao dịch), Adapter bắt buộc phải trả về một mảng nến rỗng hoặc báo cáo trạng thái boundary-exhausted.

mySecureAdapter.ts
export const mySecureAdapter: StockDataAdapter = {
  fetchBarsBefore: async (symbol, timeframe, beforeDate, limit) => {
    const bars = await api.getBars({ symbol, timeframe, before: beforeDate.getTime(), limit });
    
    // Dữ liệu trống -> khóa biên lịch sử (tương tự [] hoặc boundary-exhausted)
    // Hệ thống sẽ khóa biên trái và không bao giờ gọi lại trước mốc thời gian đó nữa.
    return bars; 
  },
  
  fetchBarsInRange: async (symbol, timeframe, fromDate, toDate) => {
    const bars = await api.getBars({ symbol, timeframe, from: fromDate.getTime(), to: toDate.getTime() });
    
    // Nạp theo mốc, nếu không có nến mới hơn, hệ thống sẽ khóa biên phải tại nến cuối cùng
    return bars;
  }
};
6

Xác Thực (Authentication) & Cấu Hình Giấy Phép (License Key)

Các tính năng nâng cấp bảo mật và giấy phép mới cho phiên bản phân phối thương mại:

Cấu hình PAT (Personal Access Token) cho Data Adapter

Với các adapter yêu cầu bảo mật thông tin như VNInvestDataAdapter, mã token của người dùng (PAT) không được mã hóa cứng mà được truyền động qua bộ xử lý xác thực:

authConfig.tsx
const authHandler = {
  getPAT: () => localStorage.getItem("vninvest_pat_token") ?? "",
  setPAT: (token: string) => localStorage.setItem("vninvest_pat_token", token)
};

// Sử dụng trong React Render
<VNInvestCharts
  adapter={vninvestDataAdapter}
  authHandler={authHandler}
  // ... các cấu hình khác
/>

Xác thực Bản quyền Nhúng (License Key)

Widget cung cấp cơ chế kiểm tra bản quyền nhúng. Khi truyền prop licenseKey, widget sẽ hiển thị tab thông tin bản quyền trong phần Cài đặt và thực hiện xác thực chữ ký tên miền (Domain Signature Validation):

licenseConfig.tsx
<VNInvestCharts
  licenseKey="vninvest-lic-xxxx-yyyy-zzzz"
  // ...
/>

Giao diện tab "Giấy phép" (Licensing) sẽ trình bày chi tiết:

  • Trạng thái bản quyền (Đang hoạt động / Không hợp lệ).
  • Tên miền đăng ký được ủy quyền.
  • Ngày hết hạn bản quyền.
7

Tài Liệu Props Chi Tiết Cho Bản Nâng Cấp v3.0

Liệt kê chi tiết các props đầu vào của biểu đồ &lt;VNInvestCharts&gt; để cấu hình theo nhu cầu. Sử dụng thanh tìm kiếm để định vị nhanh:

Thuộc tínhKiểu dữ liệuTrạng tháiÝ nghĩa & Mô tả
symbolstringRequiredMã chứng khoán hoặc mã coin cần hiển thị trên biểu đồ (ví dụ: FPT, HPG, BTCUSDT).
timeframestringRequiredKhung thời gian mặc định của biểu đồ (ví dụ: 5m, 15m, 1h, 1d, 1w, 1M).
theme"light" | "dark"Default: darkChủ đề màu sắc hiển thị của giao diện biểu đồ.
locale"vi" | "en"Default: viNgôn ngữ hiển thị của giao diện và các chú thích chỉ báo.
messagesRecord<string, string>OptionalBản dịch từ điển ngôn ngữ tùy biến bổ sung để ghi đè giao diện.
drawingUiEnabledbooleanDefault: falseBật/Tắt hiển thị thanh công cụ vẽ kỹ thuật bên trái.
showToolbarbooleanDefault: falseHiển thị/Ẩn thanh công cụ vẽ bên trái.
showHeaderbooleanDefault: falseHiển thị/Ẩn thanh điều khiển phía trên (chọn mã, khung thời gian, chỉ báo).
showFooterbooleanDefault: falseHiển thị/Ẩn thanh thông tin trạng thái phía dưới.
licenseKeystringOptionalChuỗi mã số giấy phép kích hoạt tính năng thương mại của widget.
authHandlerWidgetAuthHandlerOptionalTrình điều khiển lấy/lưu trữ mã xác thực cá nhân (PAT) của người dùng cuối.
shadowRootShadowRootOptionalRanh giới Shadow Root bọc ngoài. Bắt buộc truyền nếu nhúng biểu đồ trong chế độ Shadow DOM cô lập.
useWebGLbooleanDefault: falseBật tăng tốc phần cứng thông qua WebGL cho các đường vẽ chỉ báo kỹ thuật nặng.
onError(err: Error) => voidOptionalTiếp nhận lỗi nạp dữ liệu (như 504 Timeout) để hiển thị thông báo thay vì gây crash giao diện.
VNInvest — Tài liệu Kỹ thuật VNInvestCharts & API Reference