Skip to content

Commit

Permalink
Merge pull request #44 from deriv-com/henry/grwt-4935/contract-detail…
Browse files Browse the repository at this point in the history
…s-chart

fix: contract details chart
  • Loading branch information
ahmadtaimoor-deriv authored Feb 20, 2025
2 parents 27310e7 + e243e40 commit 8c2a957
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 53 deletions.
38 changes: 19 additions & 19 deletions src/components/Chart/Chart.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
import React, { useRef, useMemo } from "react";
import { SmartChart } from "./SmartChart";
import { useChartData } from "@/hooks/useChartData";
import { generateHistoricalTicks } from "@/utils/generateHistoricalData";
import { transformTickData } from "@/utils/transformChartData";
import { generateHistoricalCandles } from "@/utils/generateHistoricalData";
import { transformCandleData } from "@/utils/transformChartData";

export const TradeChart: React.FC = () => {
const ref = useRef<{
hasPredictionIndicators(): void;
triggerPopup(arg: () => void): void;
}>(null);

// const historicalData = useMemo(() => {
// const data = generateHistoricalCandles(100, 60);
// return transformCandleData(data);
// }, []);

const historicalData = useMemo(() => {
const data = generateHistoricalTicks('1HZ100V', 100);
return transformTickData(data);
const data = generateHistoricalCandles(100, 60);
return transformCandleData(data);
}, []);

// const streamingData = useChartData({
// useMockData: true,
// instrumentId: '1HZ100V',
// type: 'candle',
// durationInSeconds: 60
// });
// const historicalData = useMemo(() => {
// const data = generateHistoricalTicks('1HZ100V', 100);
// return transformTickData(data);
// }, []);

const streamingData = useChartData({
useMockData: true,
instrumentId: '1HZ100V',
type: 'tick',
durationInSeconds: 0
type: 'candle',
durationInSeconds: 60
});

// const streamingData = useChartData({
// useMockData: true,
// instrumentId: '1HZ100V',
// type: 'tick',
// durationInSeconds: 0
// });

return (
<div style={{ display: "flex", height: "100%", position: "relative" }}>
<SmartChart
Expand All @@ -54,7 +54,7 @@ export const TradeChart: React.FC = () => {
requestForget={() => {}}
requestForgetStream={() => {}}
enabledChartFooter={false}
granularity={0}
granularity={60}
isVerticalScrollEnabled
isConnectionOpened
clearChart={false}
Expand All @@ -68,7 +68,7 @@ export const TradeChart: React.FC = () => {
top: 76,
}}
leftMargin={80}
chartType="line"
chartType="candles"
ticksHistory={historicalData}
streamingData={streamingData}
/>
Expand Down
48 changes: 48 additions & 0 deletions src/components/ContractDetailsChart/ChartErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Component, ErrorInfo, ReactNode } from "react";

interface Props {
children: ReactNode;
}

interface State {
hasError: boolean;
}

export class ChartErrorBoundary extends Component<Props, State> {
public state: State = {
hasError: false,
};

public static getDerivedStateFromError(_: Error): State {
return { hasError: true };
}

public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error("Contract Details Chart Error:", error, errorInfo);
}

public render() {
if (this.state.hasError) {
return (
<div className="flex-1 bg-white w-full rounded-lg relative h-full flex items-center justify-center">
<div className="text-center p-4">
<h2 className="text-lg font-semibold text-gray-800 mb-2">
Chart Error
</h2>
<p className="text-gray-600">
There was an error loading the contract details chart.
</p>
<button
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
onClick={() => this.setState({ hasError: false })}
>
Try Again
</button>
</div>
</div>
);
}

return this.props.children;
}
}
67 changes: 67 additions & 0 deletions src/components/ContractDetailsChart/ContractDetailsChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useRef, useMemo } from "react";
import { SmartChart } from "@/components/Chart/SmartChart";
import { useChartData } from "@/hooks/useChartData";
import { generateHistoricalTicks } from "@/utils/generateHistoricalData";
import { transformTickData } from "@/utils/transformChartData";

export const ContractDetailsChart: React.FC = () => {
const ref = useRef<{
hasPredictionIndicators(): void;
triggerPopup(arg: () => void): void;
}>(null);

const historicalData = useMemo(() => {
const data = generateHistoricalTicks("1HZ100V", 100);
return transformTickData(data);
}, []);

const streamingData = useChartData({
useMockData: true,
instrumentId: "1HZ100V",
type: "tick",
durationInSeconds: 0,
});

return (
<div className="h-[400px] relative bg-white shadow-md rounded-lg">
<div className="absolute inset-0">
<SmartChart
ref={ref}
id="replay-chart"
barriers={[]}
chartStatusListener={(isChartReady: boolean) =>
console.log("isChartReady", isChartReady)
}
crosshair={0}
isLive
chartControlsWidgets={null}
requestSubscribe={() => {}}
toolbarWidget={() => <></>}
symbol={"R_10"}
topWidgets={() => <div />}
enabledNavigationWidget={false}
requestForget={() => {}}
requestForgetStream={() => {}}
enabledChartFooter={false}
granularity={0}
isVerticalScrollEnabled
isConnectionOpened
clearChart={false}
shouldFetchTradingTimes={false}
allowTickChartTypeOnly={false}
feedCall={{
activeSymbols: false,
}}
isMobile={false}
yAxisMargin={{
top: 76,
}}
leftMargin={80}
chartType="line"
ticksHistory={historicalData}
streamingData={streamingData}
/>
</div>
</div>
);
};
13 changes: 13 additions & 0 deletions src/components/ContractDetailsChart/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";
import { ContractDetailsChart as BaseChart } from "./ContractDetailsChart";
import { ChartErrorBoundary } from "./ChartErrorBoundary";

const ContractDetailsChartWithErrorBoundary = (props: React.ComponentProps<typeof BaseChart>) => {
return (
<ChartErrorBoundary>
<BaseChart {...props} />
</ChartErrorBoundary>
);
};

export { ContractDetailsChartWithErrorBoundary as ContractDetailsChart };
70 changes: 36 additions & 34 deletions src/screens/ContractDetailsPage/ContractDetailsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,69 @@
import React, { useEffect } from "react"
import { useNavigate } from "react-router-dom"
import { useDeviceDetection } from "@/hooks/useDeviceDetection"
import { useHeaderStore } from "@/stores/headerStore"
import { useBottomNavStore } from "@/stores/bottomNavStore"
import DesktopContractDetailsPage from "./DesktopContractDetailsPage"
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useHeaderStore } from "@/stores/headerStore";
import { useBottomNavStore } from "@/stores/bottomNavStore";
import DesktopContractDetailsPage from "./DesktopContractDetailsPage";
import { ContractDetailsChart } from "@/components/ContractDetailsChart";
import {
Header,
ContractSummary,
OrderDetails,
Chart,
Payout,
EntryExitDetails,
} from "./components"
} from "./components";
import { useDeviceDetection } from "@/hooks/useDeviceDetection";

const MobileContractDetailsPage: React.FC = () => {
const navigate = useNavigate()
const setHeaderVisible = useHeaderStore((state) => state.setIsVisible)
const setBottomNavVisible = useBottomNavStore((state) => state.setIsVisible)
const navigate = useNavigate();
const setHeaderVisible = useHeaderStore((state) => state.setIsVisible);
const setBottomNavVisible = useBottomNavStore((state) => state.setIsVisible);

useEffect(() => {
setHeaderVisible(false)
setBottomNavVisible(false)
setHeaderVisible(false);
setBottomNavVisible(false);
return () => {
setHeaderVisible(true)
setBottomNavVisible(true)
}
}, [setHeaderVisible, setBottomNavVisible])
setHeaderVisible(true);
setBottomNavVisible(true);
};
}, [setHeaderVisible, setBottomNavVisible]);

return (
<div className="w-full bg-gray-100 h-screen flex flex-col">
<Header />
<div className="flex-1 overflow-y-auto w-full lg:w-3/5 mx-auto">
<div className="p-2 pb-[56px]">
<ContractSummary />
<Chart />
<div className="min-h-[400px] bg-white rounded-lg border-b border-gray-300">
<ContractDetailsChart />
</div>
<OrderDetails />
<Payout />
<EntryExitDetails />
</div>
</div>

{/* Close Button */}
<div className="fixed bottom-0 left-0 right-0 z-[60]">
<div className="mx-2 text-center">
<button
onClick={() => navigate(-1)}
className="text-white bg-black max-w-[500px] mx-auto w-full p-3 px-8 text-center rounded-xl shadow-md"
>
Close
</button>
{/* Close Button */}
<div className="fixed bottom-0 left-0 right-0 z-[60]">
<div className="mx-2 text-center">
<button
onClick={() => navigate(-1)}
className="text-white bg-black max-w-[500px] mx-auto w-full p-3 px-8 text-center rounded-xl shadow-md"
>
Close
</button>
</div>
</div>
</div>
</div>
)
}
);
};

const ContractDetailsPage: React.FC = () => {
const { isMobile } = useDeviceDetection()
const { isMobile } = useDeviceDetection();
return isMobile ? (
<MobileContractDetailsPage />
) : (
<DesktopContractDetailsPage />
)
}
);
};

export default ContractDetailsPage
export default ContractDetailsPage;

0 comments on commit 8c2a957

Please sign in to comment.