像股票一樣,虛擬幣也有已經開發好可用的即時蠟燭圖,TradingView這個網站讓我們甚至不用安裝套件,就可以直接嵌入任何網站。

但是react是es6 module,所以沒辦法直接用他官網的範例(CDN)直接貼上,所以我們需要改寫一下做成component方便放在各頁面中使用。

創建Component

先指定圖表要放在哪個html元素裡面:

import React, { useEffect, createRef } from "react";
const tvRef = createRef();

const Report = ({ market, code }) => {
  return (
    <div
      ref={tvRef}
      style={{ height: "100%" }}
    >
      <div id={`${market}:${code}`} style={{ height: "100%" }}></div>
    </div>
  );
}

這邊為什麼高度都要設100%呢?因為我外層是要用grid做RWD,所以我不會寫死圖表的高度,只要我把這個component不論放到哪裡,它都要撐滿我放置的範圍。

market和code是我們要顯示的圖表參數,從props帶進來,就可以顯示不同的圖表。

注入JS

這邊就是跟官網不一樣的地方,官網讓我們直接寫在html中<script src"..." />,但react jsx不適合,所以我們自己創建。

const tvUrl = "https://s3.tradingview.com/tv.js";

//...

useEffect(() => {
    if (!market || !code) return;
    const script = document.createElement("script");
    script.src = tvUrl;
    script.async = true;
    script.onload = handleInit; //初始化
    binanceRef.current.appendChild(script);
}, [market, code]);

可以看到我們要初始化圖表的function放在script.onload,是因為js必須載入成功,我們才能在window.TradingView裡面去找到實例來使用。

初始化

可以看到我們若要RWD,就把autosize=true,然後就不用給他widthheight了。

決定圖表的資料內容取決於symbol

然後大家可以看到container_id這個選項,和我們剛剛的html裡面的<div id={`${market}:${code}`}></div>有關,這兩個必須一樣,他才能知道你的畫面要渲染在哪裡。

至於我為什麼用${market}:${code},因為我懶得再多傳一個取名字的props,所以既然market+code一定會是唯一的key,那就用它當作id就好了。

const handleInit = () => {
    const TV = window.TradingView;
    new TV.widget({
      autosize: true,
      symbol: `${market}:${code}`,
      interval: "D",
      timezone: "Etc/UTC",
      theme: "dark",
      style: "1",
      locale: "zh_TW",
      toolbar_bg: "#f1f3f6",
      enable_publishing: false,
      allow_symbol_change: true,
      container_id: `${market}:${code}`,
    });
};

 

完整程式碼

整個component結構如下:

import React, { useEffect, createRef } from "react";
const tvRef = createRef();
const tvUrl = "https://s3.tradingview.com/tv.js";

const Report = ({ market, code }) => {
  const handleInit = () => {
    const TV = window.TradingView;
    new TV.widget({
      autosize: true,
      symbol: `${market}:${code}`,
      interval: "D",
      timezone: "Etc/UTC",
      theme: "dark",
      style: "1",
      locale: "zh_TW",
      toolbar_bg: "#f1f3f6",
      enable_publishing: false,
      allow_symbol_change: true,
      container_id: `${market}:${code}`,
    });
  };
  useEffect(() => {
    if (!market || !code) return;
    const script = document.createElement("script");
    script.src = tvUrl;
    script.async = true;
    script.onload = handleInit;
    binanceRef.current.appendChild(script);
  }, [market, code]);
  return (
    <div
      className="tradingview-widget-container"
      ref={tvRef}
      style={{ height: "100%" }}
    >
      <div id={`${market}:${code}`} style={{ height: "100%" }}></div>
    </div>
  );
};
export default Report;

在頁面中使用:

import TV from 'components/TV';

 <TV market={"BINANCE"} code={'ENSUSDT'} />
react tradingview
0
0 回復

發表評論

想要加入討論嗎?
請盡情發表您的想法!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。