Skip to content

Commit d93c72b

Browse files
committed
update(app): complete trading view
1 parent fc944c7 commit d93c72b

File tree

10 files changed

+160
-2
lines changed

10 files changed

+160
-2
lines changed

package-lock.json

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"p-min-delay": "^3.1.0",
3535
"react": "^16.8.6",
3636
"react-apollo": "^3.0.0",
37+
"react-async-script": "^1.1.1",
3738
"react-clear-cache": "^1.0.26",
3839
"react-dom": "^16.8.6",
3940
"react-flag-icon-css": "^1.0.25",

public/assets/tradingview

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 5a839dcaeaf0a6c1de47990b27bc180708f98bf7

public/index.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
66
<meta
77
name="viewport"
8-
content="width=device-width, initial-scale=1, shrink-to-fit=no"
8+
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, shrink-to-fit=no"
99
/>
10+
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
1011
<meta name="theme-color" content="#000000" />
1112
<!--
1213
manifest.json provides metadata used when your web app is installed on a
1314
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
1415
-->
1516
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
17+
<script src="%PUBLIC_URL%/assets/tradingview/datafeeds/udf/dist/polyfills.js"></script>
18+
<script src="%PUBLIC_URL%/assets/tradingview/datafeeds/udf/dist/bundle.js"></script>
1619
<!--
1720
Notice the use of %PUBLIC_URL% in the tags above.
1821
It will be replaced with the URL of the `public` folder during the build.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
declare module 'react-async-script' {
2+
// https://github.com/dozoisch/react-async-script/issues
3+
import { ReactNode } from "react";
4+
5+
interface IOptions {
6+
callbackName?: string,
7+
globalName?: string,
8+
removeOnUnmount?: boolean,
9+
scriptId?: string,
10+
}
11+
12+
export interface IAsyncScriptComponentProps { asyncScriptOnLoad: () => void }
13+
14+
export default function(getScriptUrl: string, options?: IOptions): ReactNode<IAsyncScriptComponentProps>
15+
}

src/components/TradingView.tsx

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
import AsyncScriptLoader from 'react-async-script';
4+
5+
import { TRADING_VIEW_DEFAULT_CONFIG } from '../utils/data/chartDataUtils';
6+
7+
const DEFAULT_INTERVAL = 'D';
8+
9+
interface ITradingView {
10+
id: string,
11+
symbol: string,
12+
}
13+
14+
interface ITradingViewState {
15+
widgetInstance: any,
16+
container_id: string,
17+
symbol: string,
18+
}
19+
20+
const StyledTradingView = styled.div`
21+
width: 100%;
22+
height: 570px;
23+
`;
24+
25+
const AsyncScriptLoaderTradingView = AsyncScriptLoader(
26+
'/assets/tradingview/charting_library/charting_library.min.js',
27+
)(StyledTradingView);
28+
29+
class TradingView extends React.PureComponent<ITradingView, ITradingViewState> {
30+
constructor(props: ITradingView) {
31+
super(props);
32+
this.state = {
33+
symbol: props.symbol,
34+
widgetInstance: null,
35+
container_id: `${props.id}-tv-identifier`,
36+
};
37+
this.initializedTradingView = this.initializedTradingView.bind(this);
38+
}
39+
40+
componentDidUpdate({ symbol }: ITradingView) {
41+
if (symbol !== this.props.symbol) {
42+
this.setState({ symbol: this.props.symbol }, () => {
43+
const { widgetInstance, symbol: symbolState } = this.state;
44+
if (widgetInstance) {
45+
widgetInstance.setSymbol(symbolState, DEFAULT_INTERVAL);
46+
}
47+
});
48+
}
49+
}
50+
51+
initializedTradingView() {
52+
if (!window) {
53+
return;
54+
}
55+
const { symbol, container_id } = this.state;
56+
const tvConfig = {
57+
symbol,
58+
container_id,
59+
interval: DEFAULT_INTERVAL,
60+
datafeed: new (window as any).Datafeeds.UDFCompatibleDatafeed(
61+
process.env.REACT_APP_DATA_FEED_URL,
62+
),
63+
...TRADING_VIEW_DEFAULT_CONFIG,
64+
};
65+
this.setState({
66+
widgetInstance: new (window as any).TradingView.widget(tvConfig),
67+
});
68+
}
69+
70+
render() {
71+
const { container_id } = this.state;
72+
return (
73+
<AsyncScriptLoaderTradingView
74+
asyncScriptOnLoad={this.initializedTradingView}
75+
id={container_id}
76+
/>
77+
);
78+
}
79+
}
80+
81+
export default TradingView;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
import { Row, Col, Card, Typography, Divider } from 'antd';
3+
4+
import TradingView from '../../TradingView';
5+
import { useMarketsContextValue } from '../../../contexts/MarketsContext';
6+
7+
const { Title } = Typography;
8+
9+
const PriceIndex = () => {
10+
const { market: { marketCode } } = useMarketsContextValue();
11+
12+
return (
13+
<Row type="flex" gutter={16}>
14+
<Col className="pb-2 pb-sm-3" xs={24}>
15+
<Card className="p-3" style={{ height: '100%' }} bodyStyle={{ padding: 0 }}>
16+
<Title level={4}>Market Cap Weighted Price Index of REITs</Title>
17+
<Divider className="my-3" />
18+
<TradingView
19+
id="market-cap-price-index"
20+
symbol={`RSI.${marketCode}`}
21+
/>
22+
</Card>
23+
</Col>
24+
</Row>
25+
);
26+
};
27+
28+
export default PriceIndex;

src/pages/Chart.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import React from 'react';
22
import { UserConsumer } from '../contexts/UserContext';
33
import AppLayout from '../components/layout/AppLayout';
44

5+
import PriceIndex from '../components/pages/charts/PriceIndex';
6+
57
class Chart extends React.Component<{ requireAuth: boolean }> {
68
render() {
79
const { requireAuth } = this.props;
@@ -10,7 +12,7 @@ class Chart extends React.Component<{ requireAuth: boolean }> {
1012
<UserConsumer>
1113
{(value) => {
1214
return (
13-
<div>Chart Page</div>
15+
<PriceIndex />
1416
);
1517
}}
1618
</UserConsumer>

src/utils/data/chartDataUtils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,20 @@ export const HEAT_COLORS = [
1818
export const SANS_SERIF_FONT = `
1919
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif
2020
`;
21+
22+
export const TRADING_VIEW_DEFAULT_CONFIG = {
23+
autosize: true,
24+
timezone: 'Asia/Singapore',
25+
library_path: '/assets/tradingview/charting_library/',
26+
client_id: 'tradingview.com',
27+
user_id: 'public_user_id',
28+
locale: 'en',
29+
disabled_features: ['use_localstorage_for_settings'],
30+
enabled_features: ['study_templates'],
31+
drawings_access: {
32+
type: 'black',
33+
tools: [{
34+
name: 'Regression Trend',
35+
}],
36+
},
37+
};

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"compilerOptions": {
3+
"typeRoots" : ["src/@types", "./node_modules/@types"],
34
"target": "es5",
45
"lib": [
56
"dom",

0 commit comments

Comments
 (0)