diff --git a/landing/src/pages/market/components/ANCPriceChart.tsx b/landing/src/pages/market/components/ANCPriceChart.tsx index 143d9fd42..38c4e8daf 100644 --- a/landing/src/pages/market/components/ANCPriceChart.tsx +++ b/landing/src/pages/market/components/ANCPriceChart.tsx @@ -6,207 +6,209 @@ import { } from '@terra-dev/styled-neumorphism'; import big from 'big.js'; import { Chart } from 'chart.js'; -import React, { useEffect, useRef } from 'react'; -import styled, { useTheme } from 'styled-components'; +import React, { Component, createRef } from 'react'; +import styled, { DefaultTheme } from 'styled-components'; import { ChartTooltip } from './ChartTooltip'; import { mediumDay, xTimestampAixs } from './internal/axisUtils'; export interface ANCPriceChartProps { - data: MarketAncHistory[] | null | undefined; + data: MarketAncHistory[]; + theme: DefaultTheme; } -export function ANCPriceChart({ data }: ANCPriceChartProps) { - const theme = useTheme(); - - const canvasRef = useRef(null); - const tooltipRef = useRef(null); - const chartRef = useRef(null); - - const dataRef = useRef(data); - - useEffect(() => { - dataRef.current = data; - }, [data]); - - useEffect(() => { - if (chartRef.current) { - if (data) { - const chart = chartRef.current; - chart.data.labels = xTimestampAixs( - data.map(({ timestamp }) => timestamp), - ); - chart.data.datasets[0].data = data.map(({ anc_price }) => - big(anc_price).toNumber(), - ); - chart.update(); +export class ANCPriceChart extends Component { + private canvasRef = createRef(); + private tooltipRef = createRef(); + private chart!: Chart; + + render() { + return ( + + + +
+
+
+
+
+
+ ); + } + + componentWillUnmount() { + this.chart.destroy(); + } + + shouldComponentUpdate(nextProps: Readonly): boolean { + return ( + this.props.data !== nextProps.data || this.props.theme !== nextProps.theme + ); + } + + componentDidMount() { + this.createChart(); + } + + componentDidUpdate(prevProps: Readonly) { + if (prevProps.data !== this.props.data) { + this.chart.data.labels = xTimestampAixs( + this.props.data.map(({ timestamp }) => timestamp), + ); + this.chart.data.datasets[0].data = this.props.data.map(({ anc_price }) => + big(anc_price).toNumber(), + ); + } + + if (prevProps.theme !== this.props.theme) { + if (this.chart.options.scales?.x?.ticks) { + this.chart.options.scales.x.ticks.color = this.props.theme.dimTextColor; } - } else { - chartRef.current = new Chart(canvasRef.current!, { - type: 'line', - plugins: [ - { - id: 'custom-y-axis-draw', - afterDraw(chart) { - const ctx = chart.ctx; - ctx.save(); - ctx.globalCompositeOperation = 'destination-over'; - - const xScale = chart.scales.x; - const yScale = chart.scales.y; - - let i: number = yScale.ticks.length; - - while (--i >= 0) { - const y = yScale.getPixelForTick(i); - ctx.strokeStyle = rulerShadowColor({ - intensity: theme.intensity, - color: theme.backgroundColor, - }); - ctx.lineWidth = 1; - ctx.beginPath(); - ctx.moveTo(xScale.left, y); - ctx.lineTo(xScale.right, y); - ctx.stroke(); - ctx.strokeStyle = rulerLightColor({ - intensity: theme.intensity, - color: theme.backgroundColor, - }); - ctx.lineWidth = 1; - ctx.beginPath(); - ctx.moveTo(xScale.left, y + 1); - ctx.lineTo(xScale.right, y + 1); - ctx.stroke(); + if (this.chart.options.scales?.y?.ticks) { + this.chart.options.scales.y.ticks.color = this.props.theme.dimTextColor; + } + this.chart.data.datasets[0].borderColor = + this.props.theme.colors.positive; + } + + this.chart.update(); + } + + private createChart = () => { + this.chart = new Chart(this.canvasRef.current!, { + type: 'line', + plugins: [ + { + id: 'custom-y-axis-draw', + afterDraw: (chart) => { + const ctx = chart.ctx; + ctx.save(); + ctx.globalCompositeOperation = 'destination-over'; + + const xScale = chart.scales.x; + const yScale = chart.scales.y; + + let i: number = yScale.ticks.length; + + while (--i >= 0) { + const y = yScale.getPixelForTick(i); + ctx.strokeStyle = rulerShadowColor({ + intensity: this.props.theme.intensity, + color: this.props.theme.backgroundColor, + }); + ctx.lineWidth = 1; + ctx.beginPath(); + ctx.moveTo(xScale.left, y); + ctx.lineTo(xScale.right, y); + ctx.stroke(); + ctx.strokeStyle = rulerLightColor({ + intensity: this.props.theme.intensity, + color: this.props.theme.backgroundColor, + }); + ctx.lineWidth = 1; + ctx.beginPath(); + ctx.moveTo(xScale.left, y + 1); + ctx.lineTo(xScale.right, y + 1); + ctx.stroke(); + } + ctx.restore(); + }, + }, + ], + options: { + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + tooltip: { + enabled: false, + + external: ({ chart, tooltip }) => { + let element = this.tooltipRef.current!; + + if (tooltip.opacity === 0) { + element.style.opacity = '0'; + return; + } + + const div1 = element.querySelector('div:nth-child(1)'); + const hr = element.querySelector('hr'); + + if (div1) { + try { + const i = tooltip.dataPoints[0].dataIndex; + const isLast = i === this.props.data.length - 1; + const item = this.props.data[i]; + const price = formatUSTWithPostfixUnits(item.anc_price); + const date = isLast ? 'Now' : mediumDay(item.timestamp); + div1.innerHTML = `${price} UST ${date}`; + } catch {} } - ctx.restore(); + + if (hr) { + hr.style.top = chart.scales.y.paddingTop + 'px'; + hr.style.height = chart.scales.y.height + 'px'; + } + + element.style.opacity = '1'; + element.style.transform = `translateX(${tooltip.caretX}px)`; }, }, - ], - options: { - maintainAspectRatio: false, - plugins: { - legend: { + }, + interaction: { + intersect: false, + mode: 'index', + }, + scales: { + x: { + grid: { display: false, }, - tooltip: { - enabled: false, - - external({ chart, tooltip }) { - let element = tooltipRef.current!; - - if (tooltip.opacity === 0) { - element.style.opacity = '0'; - return; - } - - const div1 = element.querySelector('div:nth-child(1)'); - const hr = element.querySelector('hr'); - - if (div1) { - try { - const i = tooltip.dataPoints[0].dataIndex; - const isLast = i === dataRef.current!.length - 1; - const item = dataRef.current![i]; - const price = formatUSTWithPostfixUnits(item.anc_price); - const date = isLast ? 'Now' : mediumDay(item.timestamp); - div1.innerHTML = `${price} UST ${date}`; - } catch {} - } - - if (hr) { - hr.style.top = chart.scales.y.paddingTop + 'px'; - hr.style.height = chart.scales.y.height + 'px'; - } - - element.style.opacity = '1'; - element.style.transform = `translateX(${tooltip.caretX}px)`; + ticks: { + autoSkip: false, + maxRotation: 0, + font: { + size: 11, }, + color: this.props.theme.dimTextColor, }, }, - interaction: { - intersect: false, - mode: 'index', - }, - scales: { - x: { - grid: { - display: false, - }, - ticks: { - autoSkip: false, - maxRotation: 0, - font: { - size: 11, - }, - color: theme.dimTextColor, - }, + y: { + grace: '25%', + grid: { + display: false, + drawBorder: false, }, - y: { - grace: '25%', - grid: { - display: false, - drawBorder: false, - }, - ticks: { - font: { - size: 11, - }, - color: theme.dimTextColor, + ticks: { + font: { + size: 11, }, - }, - }, - elements: { - point: { - radius: 0, + color: this.props.theme.dimTextColor, }, }, }, - data: { - labels: data - ? xTimestampAixs(data.map(({ timestamp }) => timestamp)) - : [], - datasets: [ - { - data: - data?.map(({ anc_price }) => big(anc_price).toNumber()) ?? [], - borderColor: theme.colors.positive, - borderWidth: 2, - }, - ], + elements: { + point: { + radius: 0, + }, }, - }); - } - - if (process.env.NODE_ENV === 'development') { - return () => { - chartRef.current?.destroy(); - chartRef.current = null; - }; - } - }, [ - data, - theme.backgroundColor, - theme.colors.positive, - theme.dimTextColor, - theme.intensity, - ]); - - useEffect(() => { - return () => { - chartRef.current?.destroy(); - }; - }, []); - - return ( - - - -
-
-
-
-
-
- ); + }, + data: { + labels: xTimestampAixs( + this.props.data.map(({ timestamp }) => timestamp), + ), + datasets: [ + { + data: this.props.data.map(({ anc_price }) => + big(anc_price).toNumber(), + ), + borderColor: this.props.theme.colors.positive, + borderWidth: 2, + }, + ], + }, + }); + }; } const Container = styled.div` diff --git a/landing/src/pages/market/components/CollateralsChart.tsx b/landing/src/pages/market/components/CollateralsChart.tsx index 4c75a90b2..8ef1a648e 100644 --- a/landing/src/pages/market/components/CollateralsChart.tsx +++ b/landing/src/pages/market/components/CollateralsChart.tsx @@ -5,165 +5,163 @@ import { import { MarketCollateralsHistory } from '@anchor-protocol/webapp-fns'; import big from 'big.js'; import { Chart } from 'chart.js'; -import React, { useEffect, useRef } from 'react'; -import styled, { useTheme } from 'styled-components'; +import React, { Component, createRef } from 'react'; +import styled, { DefaultTheme } from 'styled-components'; import { ChartTooltip } from './ChartTooltip'; import { mediumDay, xTimestampAixs } from './internal/axisUtils'; export interface CollateralsChartProps { - data: MarketCollateralsHistory[] | null | undefined; + data: MarketCollateralsHistory[]; + theme: DefaultTheme; } -export function CollateralsChart({ data }: CollateralsChartProps) { - const theme = useTheme(); - - const canvasRef = useRef(null); - const tooltipRef = useRef(null); - const chartRef = useRef(null); - - const dataRef = useRef(data); - - useEffect(() => { - dataRef.current = data; - }, [data]); - - useEffect(() => { - if (chartRef.current) { - if (data) { - const chart = chartRef.current; - chart.data.labels = xTimestampAixs( - data.map(({ timestamp }) => timestamp), - ); - chart.data.datasets[0].data = data.map(({ total_value }) => - big(total_value).toNumber(), - ); - chart.update(); - } - } else { - chartRef.current = new Chart(canvasRef.current!, { - type: 'line', - options: { - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - tooltip: { - enabled: false, - - external: ({ chart, tooltip }) => { - let element = tooltipRef.current!; +export class CollateralsChart extends Component { + private canvasRef = createRef(); + private tooltipRef = createRef(); + private chart!: Chart; + + render() { + return ( + + + +
+
+
+
+
+
+ ); + } + + componentWillUnmount() { + this.chart.destroy(); + } + + shouldComponentUpdate(nextProps: Readonly): boolean { + return ( + this.props.data !== nextProps.data || this.props.theme !== nextProps.theme + ); + } + + componentDidMount() { + this.createChart(); + } + + componentDidUpdate(prevProps: Readonly) { + if (prevProps.data !== this.props.data) { + this.chart.data.labels = xTimestampAixs( + this.props.data.map(({ timestamp }) => timestamp), + ); + this.chart.data.datasets[0].data = this.props.data.map( + ({ total_value }) => big(total_value).toNumber(), + ); + } - if (tooltip.opacity === 0) { - element.style.opacity = '0'; - return; - } + if (prevProps.theme !== this.props.theme) { + if (this.chart.options.scales?.x?.ticks) { + this.chart.options.scales.x.ticks.color = this.props.theme.dimTextColor; + } + this.chart.data.datasets[0].borderColor = + this.props.theme.colors.positive; + } - const div1 = element.querySelector('div:nth-child(1)'); - const hr = element.querySelector('hr'); - - if (div1) { - try { - const i = tooltip.dataPoints[0].dataIndex; - const isLast = i === dataRef.current!.length - 1; - const item = dataRef.current![i]; - const price = formatUSTWithPostfixUnits( - demicrofy(item.total_value), - ); - const date = isLast ? 'Now' : mediumDay(item.timestamp); - div1.innerHTML = `${price} UST ${date}`; - } catch (error) { - console.error(error); - } + this.chart.update(); + } + + private createChart = () => { + this.chart = new Chart(this.canvasRef.current!, { + type: 'line', + options: { + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + tooltip: { + enabled: false, + + external: ({ chart, tooltip }) => { + let element = this.tooltipRef.current!; + + if (tooltip.opacity === 0) { + element.style.opacity = '0'; + return; + } + + const div1 = element.querySelector('div:nth-child(1)'); + const hr = element.querySelector('hr'); + + if (div1) { + try { + const i = tooltip.dataPoints[0].dataIndex; + const isLast = i === this.props.data.length - 1; + const item = this.props.data[i]; + const price = formatUSTWithPostfixUnits( + demicrofy(item.total_value), + ); + const date = isLast ? 'Now' : mediumDay(item.timestamp); + div1.innerHTML = `${price} UST ${date}`; + } catch (error) { + console.error(error); } + } - if (hr) { - hr.style.top = chart.scales.y.paddingTop + 'px'; - hr.style.height = chart.scales.y.height + 'px'; - } + if (hr) { + hr.style.top = chart.scales.y.paddingTop + 'px'; + hr.style.height = chart.scales.y.height + 'px'; + } - element.style.opacity = '1'; - element.style.transform = `translateX(${tooltip.caretX}px)`; - }, + element.style.opacity = '1'; + element.style.transform = `translateX(${tooltip.caretX}px)`; }, }, - interaction: { - intersect: false, - mode: 'index', - }, - scales: { - x: { - grid: { - display: false, - }, - ticks: { - autoSkip: false, - maxRotation: 0, - font: { - size: 11, - }, - color: theme.dimTextColor, - }, - }, - y: { - grace: '25%', + }, + interaction: { + intersect: false, + mode: 'index', + }, + scales: { + x: { + grid: { display: false, }, - }, - elements: { - point: { - radius: 0, + ticks: { + autoSkip: false, + maxRotation: 0, + font: { + size: 11, + }, + color: this.props.theme.dimTextColor, }, }, + y: { + grace: '25%', + display: false, + }, }, - data: { - labels: data - ? xTimestampAixs(data.map(({ timestamp }) => timestamp)) - : [], - datasets: [ - { - data: - data?.map(({ total_value }) => big(total_value).toNumber()) ?? - [], - borderColor: theme.colors.positive, - borderWidth: 2, - }, - ], + elements: { + point: { + radius: 0, + }, }, - }); - } - - if (process.env.NODE_ENV === 'development') { - return () => { - chartRef.current?.destroy(); - chartRef.current = null; - }; - } - }, [ - data, - theme.backgroundColor, - theme.colors.positive, - theme.dimTextColor, - theme.intensity, - ]); - - useEffect(() => { - return () => { - chartRef.current?.destroy(); - }; - }, []); - - return ( - - - -
-
-
-
-
-
- ); + }, + data: { + labels: xTimestampAixs( + this.props.data.map(({ timestamp }) => timestamp), + ), + datasets: [ + { + data: this.props.data?.map(({ total_value }) => + big(total_value).toNumber(), + ), + borderColor: this.props.theme.colors.positive, + borderWidth: 2, + }, + ], + }, + }); + }; } const Container = styled.div` diff --git a/landing/src/pages/market/components/StablecoinChart.tsx b/landing/src/pages/market/components/StablecoinChart.tsx index 7f2de923b..c22d94cd4 100644 --- a/landing/src/pages/market/components/StablecoinChart.tsx +++ b/landing/src/pages/market/components/StablecoinChart.tsx @@ -5,183 +5,181 @@ import { import { MarketDepositAndBorrow } from '@anchor-protocol/webapp-fns'; import big from 'big.js'; import { Chart } from 'chart.js'; -import React, { useEffect, useRef } from 'react'; -import styled, { useTheme } from 'styled-components'; +import React, { Component, createRef } from 'react'; +import styled, { DefaultTheme } from 'styled-components'; import { ChartTooltip } from './ChartTooltip'; import { mediumDay, xTimestampAixs } from './internal/axisUtils'; export interface StablecoinChartProps { - data: MarketDepositAndBorrow[] | null | undefined; + data: MarketDepositAndBorrow[]; + theme: DefaultTheme; } -export function StablecoinChart({ data }: StablecoinChartProps) { - const theme = useTheme(); - - const canvasRef = useRef(null); - const tooltipRef = useRef(null); - const chartRef = useRef(null); - - const dataRef = useRef(data); - - useEffect(() => { - dataRef.current = data; - }, [data]); - - useEffect(() => { - if (chartRef.current) { - if (data) { - const chart = chartRef.current; - chart.data.labels = xTimestampAixs( - data.map(({ timestamp }) => timestamp), - ); - chart.data.datasets[0].data = data.map(({ total_ust_deposits }) => - big(total_ust_deposits).toNumber(), - ); - chart.data.datasets[1].data = data.map(({ total_borrowed }) => - big(total_borrowed).toNumber(), - ); - chart.update(); +export class StablecoinChart extends Component { + private canvasRef = createRef(); + private tooltipRef = createRef(); + private chart!: Chart; + + render() { + return ( + + + +
+
+
+
+
+
+
+ ); + } + + componentWillUnmount() { + this.chart.destroy(); + } + + shouldComponentUpdate(nextProps: Readonly): boolean { + return ( + this.props.data !== nextProps.data || this.props.theme !== nextProps.theme + ); + } + + componentDidMount() { + this.createChart(); + } + + componentDidUpdate(prevProps: Readonly) { + if (prevProps.data !== this.props.data) { + this.chart.data.labels = xTimestampAixs( + this.props.data.map(({ timestamp }) => timestamp), + ); + this.chart.data.datasets[0].data = this.props.data.map( + ({ total_ust_deposits }) => big(total_ust_deposits).toNumber(), + ); + this.chart.data.datasets[1].data = this.props.data.map( + ({ total_borrowed }) => big(total_borrowed).toNumber(), + ); + } + + if (prevProps.theme !== this.props.theme) { + if (this.chart.options.scales?.x?.ticks) { + this.chart.options.scales.x.ticks.color = this.props.theme.dimTextColor; } - } else { - chartRef.current = new Chart(canvasRef.current!, { - type: 'line', - options: { - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - tooltip: { - enabled: false, - - external({ chart, tooltip }) { - let element = tooltipRef.current!; - - if (tooltip.opacity === 0) { - element.style.opacity = '0'; - return; - } - - const div1 = element.querySelector('div:nth-child(1)'); - const div2 = element.querySelector('div:nth-child(2)'); - const hr = element.querySelector('hr'); - - if (div1 && div2) { - try { - const i = tooltip.dataPoints[0].dataIndex; - const isLast = i === dataRef.current!.length - 1; - const item = dataRef.current![i]; - const deposits = formatUSTWithPostfixUnits( - demicrofy(item.total_ust_deposits), - ); - const borrows = formatUSTWithPostfixUnits( - demicrofy(item.total_borrowed), - ); - const date = isLast ? 'Now' : mediumDay(item.timestamp); - - div1.innerHTML = `${deposits} UST ${date}`; - div2.innerHTML = `${borrows} UST ${date}`; - } catch {} - } - - if (hr) { - hr.style.top = chart.scales.y.paddingTop + 'px'; - hr.style.height = chart.scales.y.height + 'px'; - } - - element.style.opacity = '1'; - element.style.transform = `translateX(${tooltip.caretX}px)`; - }, - }, - }, - interaction: { - intersect: false, - mode: 'index', + this.chart.data.datasets[0].borderColor = + this.props.theme.colors.positive; + this.chart.data.datasets[1].borderColor = this.props.theme.textColor; + } + + this.chart.update(); + } + + private createChart = () => { + this.chart = new Chart(this.canvasRef.current!, { + type: 'line', + options: { + maintainAspectRatio: false, + plugins: { + legend: { + display: false, }, - scales: { - x: { - grid: { - display: false, - }, - ticks: { - autoSkip: false, - maxRotation: 0, - font: { - size: 11, - }, - color: theme.dimTextColor, - }, + tooltip: { + enabled: false, + + external: ({ chart, tooltip }) => { + let element = this.tooltipRef.current!; + + if (tooltip.opacity === 0) { + element.style.opacity = '0'; + return; + } + + const div1 = element.querySelector('div:nth-child(1)'); + const div2 = element.querySelector('div:nth-child(2)'); + const hr = element.querySelector('hr'); + + if (div1 && div2) { + try { + const i = tooltip.dataPoints[0].dataIndex; + const isLast = i === this.props.data.length - 1; + const item = this.props.data[i]; + const deposits = formatUSTWithPostfixUnits( + demicrofy(item.total_ust_deposits), + ); + const borrows = formatUSTWithPostfixUnits( + demicrofy(item.total_borrowed), + ); + const date = isLast ? 'Now' : mediumDay(item.timestamp); + + div1.innerHTML = `${deposits} UST ${date}`; + div2.innerHTML = `${borrows} UST ${date}`; + } catch {} + } + + if (hr) { + hr.style.top = chart.scales.y.paddingTop + 'px'; + hr.style.height = chart.scales.y.height + 'px'; + } + + element.style.opacity = '1'; + element.style.transform = `translateX(${tooltip.caretX}px)`; }, - y: { - grace: '25%', + }, + }, + interaction: { + intersect: false, + mode: 'index', + }, + scales: { + x: { + grid: { display: false, }, - }, - elements: { - point: { - radius: 0, + ticks: { + autoSkip: false, + maxRotation: 0, + font: { + size: 11, + }, + color: this.props.theme.dimTextColor, }, }, + y: { + grace: '25%', + display: false, + }, }, - data: { - labels: data - ? xTimestampAixs(data.map(({ timestamp }) => timestamp)) - : [], - datasets: [ - { - data: - data?.map(({ total_ust_deposits }) => - big(total_ust_deposits).toNumber(), - ) ?? [], - borderColor: theme.colors.positive, - borderWidth: 2, - }, - { - data: - data?.map(({ total_borrowed }) => - big(total_borrowed).toNumber(), - ) ?? [], - borderColor: theme.textColor, - borderWidth: 2, - }, - ], + elements: { + point: { + radius: 0, + }, }, - }); - } - - if (process.env.NODE_ENV === 'development') { - return () => { - chartRef.current?.destroy(); - chartRef.current = null; - }; - } - }, [ - theme.backgroundColor, - theme.colors.positive, - theme.dimTextColor, - theme.textColor, - theme.intensity, - data, - ]); - - useEffect(() => { - return () => { - chartRef.current?.destroy(); - }; - }, []); - - return ( - - - -
-
-
-
-
-
-
- ); + }, + data: { + labels: xTimestampAixs( + this.props.data.map(({ timestamp }) => timestamp), + ), + datasets: [ + { + data: this.props.data.map(({ total_ust_deposits }) => + big(total_ust_deposits).toNumber(), + ), + borderColor: this.props.theme.colors.positive, + borderWidth: 2, + }, + { + data: this.props.data.map(({ total_borrowed }) => + big(total_borrowed).toNumber(), + ), + borderColor: this.props.theme.textColor, + borderWidth: 2, + }, + ], + }, + }); + }; } const Container = styled.div` diff --git a/landing/src/pages/market/components/TotalValueLockedDoughnutChart.tsx b/landing/src/pages/market/components/TotalValueLockedDoughnutChart.tsx index 12b2fbc62..86f6d41cf 100644 --- a/landing/src/pages/market/components/TotalValueLockedDoughnutChart.tsx +++ b/landing/src/pages/market/components/TotalValueLockedDoughnutChart.tsx @@ -1,6 +1,6 @@ import { uUST } from '@anchor-protocol/types'; import { Chart } from 'chart.js'; -import React, { useEffect, useRef } from 'react'; +import React, { Component, createRef } from 'react'; export interface TotalValueLockedDoughnutChartProps { totalDeposit: uUST; @@ -9,71 +9,86 @@ export interface TotalValueLockedDoughnutChartProps { totalCollateralsColor: string; } -export function TotalValueLockedDoughnutChart({ - totalDeposit, - totalCollaterals, - totalDepositColor, - totalCollateralsColor, -}: TotalValueLockedDoughnutChartProps) { - const canvasRef = useRef(null); - const chartRef = useRef(null); +export class TotalValueLockedDoughnutChart extends Component { + private canvasRef = createRef(); + private chart!: Chart; - useEffect(() => { - if (chartRef.current) { - const chart = chartRef.current; - chart.data.datasets[0].data = [+totalDeposit, +totalCollaterals]; - chart.data.datasets[0].backgroundColor = [ - totalDepositColor, - totalCollateralsColor, + render() { + return ; + } + + componentWillUnmount() { + this.chart.destroy(); + } + + shouldComponentUpdate( + nextProps: Readonly, + ): boolean { + return ( + this.props.totalDeposit !== nextProps.totalDeposit || + this.props.totalCollaterals !== nextProps.totalCollaterals || + this.props.totalDepositColor !== nextProps.totalDepositColor || + this.props.totalCollateralsColor !== nextProps.totalCollateralsColor + ); + } + + componentDidMount() { + this.createChart(); + } + + componentDidUpdate(prevProps: Readonly) { + if ( + this.props.totalDeposit !== prevProps.totalDeposit || + this.props.totalCollaterals !== prevProps.totalCollaterals + ) { + this.chart.data.datasets[0].data = [ + +this.props.totalDeposit, + +this.props.totalCollaterals, ]; - chart.update(); - } else { - chartRef.current = new Chart(canvasRef.current!, { - type: 'doughnut', - options: { - cutout: '80%', - radius: '90%', - plugins: { - legend: { - display: false, - }, - tooltip: { - enabled: false, - }, - }, - }, - data: { - labels: ['Total Deposit', 'Total Collateral'], - datasets: [ - { - data: [+totalDeposit, +totalCollaterals], - backgroundColor: [totalDepositColor, totalCollateralsColor], - borderWidth: 0, - hoverOffset: 0, - }, - ], - }, - }); } - if (process.env.NODE_ENV === 'development') { - return () => { - chartRef.current?.destroy(); - chartRef.current = null; - }; + if ( + this.props.totalDepositColor !== prevProps.totalDepositColor || + this.props.totalCollateralsColor !== prevProps.totalCollateralsColor + ) { + this.chart.data.datasets[0].backgroundColor = [ + this.props.totalDepositColor, + this.props.totalCollateralsColor, + ]; } - }, [ - totalCollaterals, - totalCollateralsColor, - totalDeposit, - totalDepositColor, - ]); - useEffect(() => { - return () => { - chartRef.current?.destroy(); - }; - }, []); + this.chart.update(); + } - return ; + private createChart = () => { + this.chart = new Chart(this.canvasRef.current!, { + type: 'doughnut', + options: { + cutout: '80%', + radius: '90%', + plugins: { + legend: { + display: false, + }, + tooltip: { + enabled: false, + }, + }, + }, + data: { + labels: ['Total Deposit', 'Total Collateral'], + datasets: [ + { + data: [+this.props.totalDeposit, +this.props.totalCollaterals], + backgroundColor: [ + this.props.totalDepositColor, + this.props.totalCollateralsColor, + ], + borderWidth: 0, + hoverOffset: 0, + }, + ], + }, + }); + }; } diff --git a/landing/src/pages/market/index.tsx b/landing/src/pages/market/index.tsx index 7b687dd3b..bd83634bb 100644 --- a/landing/src/pages/market/index.tsx +++ b/landing/src/pages/market/index.tsx @@ -45,6 +45,8 @@ export interface MarketProps { className?: string; } +const EMPTY_ARRAY: any[] = []; + function MarketBase({ className }: MarketProps) { const theme = useTheme(); @@ -306,7 +308,10 @@ function MarketBase({ className }: MarketProps) {
- +
@@ -407,7 +412,10 @@ function MarketBase({ className }: MarketProps) {
- +
@@ -541,7 +549,10 @@ function MarketBase({ className }: MarketProps) {
- +