Commit 3cb38237 authored by ianlapham's avatar ianlapham

format chart component

parent b44c7e7d
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
"rules": { "rules": {
"@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-function-return-type": "off",
"prettier/prettier": "error", "prettier/prettier": "error",
"@typescript-eslint/no-explicit-any": "off" "@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off"
} }
} }
import React, { useRef, useState, useEffect, useCallback, Dispatch, SetStateAction, ReactNode } from 'react' import React, { useRef, useState, useEffect, useCallback, Dispatch, SetStateAction, ReactNode } from 'react'
import { createChart, IChartApi } from 'lightweight-charts' import { createChart, IChartApi, ISeriesApi } from 'lightweight-charts'
import { darken } from 'polished' import { darken } from 'polished'
import { RowBetween } from 'components/Row' import { RowBetween } from 'components/Row'
import Card from '../Card' import Card from '../Card'
import styled from 'styled-components' import styled from 'styled-components'
import useTheme from 'hooks/useTheme' import useTheme from 'hooks/useTheme'
import { useDarkModeManager } from 'state/user/hooks'
import usePrevious from 'hooks/usePrevious'
const Wrapper = styled(Card)` const Wrapper = styled(Card)`
width: 100%; width: 100%;
...@@ -18,8 +19,6 @@ const Wrapper = styled(Card)` ...@@ -18,8 +19,6 @@ const Wrapper = styled(Card)`
} }
` `
const ChartContent = styled.div``
const DEFAULT_HEIGHT = 300 const DEFAULT_HEIGHT = 300
export type LineChartProps = { export type LineChartProps = {
...@@ -46,27 +45,22 @@ const LineChart = ({ ...@@ -46,27 +45,22 @@ const LineChart = ({
}: LineChartProps) => { }: LineChartProps) => {
const theme = useTheme() const theme = useTheme()
// reference for DOM element to create with chart const chartRef = useRef<HTMLDivElement>(null)
const chartRef = useRef(null)
// pointer to the chart object
const [chartCreated, setChart] = useState<IChartApi | undefined>() const [chartCreated, setChart] = useState<IChartApi | undefined>()
/** // for reseting value on hover exit
* @todo respond to dark mode
*/
const textColor = '#565A69'
const currenValue = data[data.length - 1].value const currenValue = data[data.length - 1].value
const isClient = typeof window === 'object'
const handleResize = useCallback(() => { const handleResize = useCallback(() => {
chartCreated && chartCreated.resize(chartRef.current.parentNode.clientWidth - 32, height) if (chartCreated && chartRef?.current?.parentElement) {
chartCreated && chartCreated.timeScale().fitContent() chartCreated.resize(chartRef.current.parentElement.clientWidth - 32, height)
chartCreated && chartCreated.timeScale().scrollToPosition(0, 0) chartCreated.timeScale().fitContent()
}, [chartCreated, height]) chartCreated.timeScale().scrollToPosition(0, false)
}
}, [chartCreated, chartRef, height])
// add event listener for resize
const isClient = typeof window === 'object'
useEffect(() => { useEffect(() => {
if (!isClient) { if (!isClient) {
return return
...@@ -75,11 +69,29 @@ const LineChart = ({ ...@@ -75,11 +69,29 @@ const LineChart = ({
return () => window.removeEventListener('resize', handleResize) return () => window.removeEventListener('resize', handleResize)
}, [isClient, chartRef, handleResize]) // Empty array ensures that effect is only run on mount and unmount }, [isClient, chartRef, handleResize]) // Empty array ensures that effect is only run on mount and unmount
const [currentTheme] = useDarkModeManager()
const textColor = theme.text2
const previousTheme = usePrevious(currentTheme)
const [activeSeries, setActiveSeries] = useState<ISeriesApi<'Area'> | undefined>(undefined)
// reset the chart if theme switches
useEffect(() => { useEffect(() => {
if (!chartCreated && data && chartRef && chartRef.current) { if (chartCreated && activeSeries && previousTheme && previousTheme !== currentTheme) {
// remove the tooltip element
chartCreated.removeSeries(activeSeries)
chartCreated.resize(0, 0)
setActiveSeries(undefined)
setChart(undefined)
}
}, [activeSeries, chartCreated, currentTheme, previousTheme])
// if chart not instantiated in canvas, create it
useEffect(() => {
if (!chartCreated && data && !!chartRef?.current?.parentElement) {
const chart = createChart(chartRef.current, { const chart = createChart(chartRef.current, {
height: height, height: height,
width: chartRef.current.parentNode.clientWidth - 32, width: chartRef.current.parentElement.clientWidth - 32,
layout: { layout: {
backgroundColor: 'transparent', backgroundColor: 'transparent',
textColor: textColor, textColor: textColor,
...@@ -131,29 +143,30 @@ const LineChart = ({ ...@@ -131,29 +143,30 @@ const LineChart = ({
priceLineVisible: false, priceLineVisible: false,
}) })
setActiveSeries(series)
series.setData(data) series.setData(data)
// update the title when hovering on the chart // update the title when hovering on the chart
chart.subscribeCrosshairMove(function (param) { chart.subscribeCrosshairMove(function (param) {
if ( if (
param === undefined || chartRef?.current &&
param.time === undefined || (param === undefined ||
(param && param.point && param.point.x < 0) || param.time === undefined ||
(param && param.point && param.point.x > chartRef.current.clientWidth) || (param && param.point && param.point.x < 0) ||
(param && param.point && param.point.y < 0) || (param && param.point && param.point.x > chartRef.current.clientWidth) ||
(param && param.point && param.point.y > height) (param && param.point && param.point.y < 0) ||
(param && param.point && param.point.y > height))
) { ) {
setValue && setValue(currenValue) setValue && setValue(currenValue)
} else { } else {
const price = param.seriesPrices.get(series) const price = parseFloat(param.seriesPrices.get(series)?.toString() ?? currenValue)
setValue && setValue(price) setValue && setValue(price)
} }
}) })
chart.timeScale().fitContent() chart.timeScale().fitContent()
setChart(chart) setChart(chart)
} }
}, [color, chartCreated, currenValue, data, height, setValue, textColor, theme.bg1]) }, [color, chartCreated, currenValue, data, height, setValue, textColor, theme])
return ( return (
<Wrapper> <Wrapper>
...@@ -161,7 +174,7 @@ const LineChart = ({ ...@@ -161,7 +174,7 @@ const LineChart = ({
{topLeft ?? null} {topLeft ?? null}
{topRight ?? null} {topRight ?? null}
</RowBetween> </RowBetween>
<ChartContent ref={chartRef} id={'test-id'} {...rest} /> <div ref={chartRef} id={'line-chart'} {...rest} />
<RowBetween> <RowBetween>
{bottomLeft ?? null} {bottomLeft ?? null}
{bottomRight ?? null} {bottomRight ?? null}
......
...@@ -19,7 +19,7 @@ export default function useAddTokenToMetamask( ...@@ -19,7 +19,7 @@ export default function useAddTokenToMetamask(
.request({ .request({
method: 'wallet_watchAsset', method: 'wallet_watchAsset',
params: { params: {
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore // eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore // need this for incorrect ethers provider type //@ts-ignore // need this for incorrect ethers provider type
type: 'ERC20', type: 'ERC20',
options: { options: {
......
...@@ -9,7 +9,6 @@ export const BodyWrapper = styled.div` ...@@ -9,7 +9,6 @@ export const BodyWrapper = styled.div`
box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.01), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04), box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.01), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04),
0px 24px 32px rgba(0, 0, 0, 0.01); 0px 24px 32px rgba(0, 0, 0, 0.01);
border-radius: 30px; border-radius: 30px;
/* padding: 1rem; */
` `
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment