add start of chart component
This commit is contained in:
parent
4d612dc2a2
commit
b05c4c111c
@ -129,6 +129,7 @@
|
||||
},
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@uniswap/default-token-list": "^2.0.0"
|
||||
"@uniswap/default-token-list": "^2.0.0",
|
||||
"lightweight-charts": "^3.3.0"
|
||||
}
|
||||
}
|
||||
|
104
src/components/LineChart/LineChart.stories.tsx
Normal file
104
src/components/LineChart/LineChart.stories.tsx
Normal file
@ -0,0 +1,104 @@
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import React from 'react'
|
||||
import Component, { LineChartProps } from './'
|
||||
import { dummyData } from './data'
|
||||
// import Row, { RowFixed } from 'components/Row'
|
||||
import styled from 'styled-components'
|
||||
// import { AutoColumn } from 'components/Column'
|
||||
// import { TYPE } from 'theme'
|
||||
// import DoubleCurrencyLogo from 'components/DoubleLogo'
|
||||
// import { MKR } from 'constants'
|
||||
// import { ETHER } from '@uniswap/sdk'
|
||||
// import LineChart from '.'
|
||||
|
||||
const wrapperCss = styled.main`
|
||||
font-size: 2em;
|
||||
margin: 3em;
|
||||
max-width: 300px;
|
||||
`
|
||||
export default {
|
||||
title: 'Charts',
|
||||
argTypes: {
|
||||
disabled: { control: { type: 'boolean' } },
|
||||
onClick: { action: 'clicked' }
|
||||
},
|
||||
decorators: [
|
||||
(Component: Story) => (
|
||||
<div css={wrapperCss}>
|
||||
<Component />
|
||||
</div>
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
const Template: Story<LineChartProps> = args => <Component {...args}>{args.children}</Component>
|
||||
|
||||
const Wrapper = styled.div`
|
||||
margin: 1em 2em;
|
||||
max-width: 500px;
|
||||
& > * {
|
||||
font-size: 1em;
|
||||
}
|
||||
`
|
||||
|
||||
export const Basic = Template.bind({})
|
||||
Basic.args = { data: dummyData }
|
||||
Basic.decorators = [
|
||||
(Story: any) => {
|
||||
return (
|
||||
<Wrapper>
|
||||
<Story />
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
]
|
||||
|
||||
// const Full = () => {
|
||||
// const [value, setValue] = useState<number | undefined>(dummyData[dummyData.length - 1].value)
|
||||
|
||||
// const dummyUSDPrice = 410 // used for conversion
|
||||
|
||||
// const TopLeftContent = () => (
|
||||
// <AutoColumn gap="md">
|
||||
// <RowFixed align="center">
|
||||
// <DoubleCurrencyLogo currency0={MKR} currency1={ETHER} size={20} />{' '}
|
||||
// <TYPE.main fontSize="20px" color="white" ml="10px">
|
||||
// ETH / MKR
|
||||
// </TYPE.main>
|
||||
// </RowFixed>
|
||||
// <Row>
|
||||
// <TYPE.main fontSize="20px" color="white">
|
||||
// {value} MKR
|
||||
// </TYPE.main>
|
||||
// <TYPE.main color="#565A69" fontSize="20px" ml="10px">
|
||||
// ($
|
||||
// {value
|
||||
// ? (value * dummyUSDPrice).toLocaleString('USD', {
|
||||
// currency: 'USD',
|
||||
// minimumFractionDigits: 2
|
||||
// })
|
||||
// : null}{' '}
|
||||
// )
|
||||
// </TYPE.main>
|
||||
// </Row>
|
||||
// </AutoColumn>
|
||||
// )
|
||||
|
||||
// return (
|
||||
// <Wrapper>
|
||||
// <LineChart data={dummyData} setValue={setValue} topLeft={<TopLeftContent />} />
|
||||
// </Wrapper>
|
||||
// )
|
||||
// }
|
||||
|
||||
// export const FullVersion = Template.bind(() => <LineChart data={dummyData} />)
|
||||
// Full.args = { data: dummyData }
|
||||
// Full.decorators = [
|
||||
// (Story: any) => {
|
||||
// return (
|
||||
// <Wrapper>
|
||||
// <LineChart data={dummyData} />
|
||||
// </Wrapper>
|
||||
// )
|
||||
// }
|
||||
// ]
|
152
src/components/LineChart/data.ts
Normal file
152
src/components/LineChart/data.ts
Normal file
@ -0,0 +1,152 @@
|
||||
export const dummyData = [
|
||||
{ time: '2018-10-19', value: 35.98 },
|
||||
{ time: '2018-10-22', value: 35.75 },
|
||||
{ time: '2018-10-23', value: 35.65 },
|
||||
{ time: '2018-10-24', value: 34.12 },
|
||||
{ time: '2018-10-25', value: 35.84 },
|
||||
{ time: '2018-10-26', value: 35.24 },
|
||||
{ time: '2018-10-29', value: 35.99 },
|
||||
{ time: '2018-10-30', value: 37.71 },
|
||||
{ time: '2018-10-31', value: 38.14 },
|
||||
{ time: '2018-11-01', value: 37.95 },
|
||||
{ time: '2018-11-02', value: 37.66 },
|
||||
{ time: '2018-11-05', value: 38.02 },
|
||||
{ time: '2018-11-06', value: 37.73 },
|
||||
{ time: '2018-11-07', value: 38.3 },
|
||||
{ time: '2018-11-08', value: 38.3 },
|
||||
{ time: '2018-11-09', value: 38.34 },
|
||||
{ time: '2018-11-12', value: 38.0 },
|
||||
{ time: '2018-11-13', value: 37.72 },
|
||||
{ time: '2018-11-14', value: 38.29 },
|
||||
{ time: '2018-11-15', value: 38.49 },
|
||||
{ time: '2018-11-16', value: 38.59 },
|
||||
{ time: '2018-11-19', value: 38.18 },
|
||||
{ time: '2018-11-20', value: 36.76 },
|
||||
{ time: '2018-11-21', value: 37.51 },
|
||||
{ time: '2018-11-23', value: 37.39 },
|
||||
{ time: '2018-11-26', value: 37.77 },
|
||||
{ time: '2018-11-27', value: 38.36 },
|
||||
{ time: '2018-11-28', value: 39.06 },
|
||||
{ time: '2018-11-29', value: 39.42 },
|
||||
{ time: '2018-11-30', value: 39.01 },
|
||||
{ time: '2018-12-03', value: 39.15 },
|
||||
{ time: '2018-12-04', value: 37.69 },
|
||||
{ time: '2018-12-06', value: 37.88 },
|
||||
{ time: '2018-12-07', value: 37.41 },
|
||||
{ time: '2018-12-10', value: 37.35 },
|
||||
{ time: '2018-12-11', value: 36.84 },
|
||||
{ time: '2018-12-12', value: 36.98 },
|
||||
{ time: '2018-12-13', value: 36.76 },
|
||||
{ time: '2018-12-14', value: 36.34 },
|
||||
{ time: '2018-12-17', value: 36.21 },
|
||||
{ time: '2018-12-18', value: 35.65 },
|
||||
{ time: '2018-12-19', value: 35.19 },
|
||||
{ time: '2018-12-20', value: 34.62 },
|
||||
{ time: '2018-12-21', value: 33.75 },
|
||||
{ time: '2018-12-24', value: 33.07 },
|
||||
{ time: '2018-12-26', value: 34.14 },
|
||||
{ time: '2018-12-27', value: 34.47 },
|
||||
{ time: '2018-12-28', value: 34.35 },
|
||||
{ time: '2018-12-31', value: 34.05 },
|
||||
{ time: '2019-01-02', value: 34.37 },
|
||||
{ time: '2019-01-03', value: 34.64 },
|
||||
{ time: '2019-01-04', value: 35.81 },
|
||||
{ time: '2019-01-07', value: 35.43 },
|
||||
{ time: '2019-01-08', value: 35.72 },
|
||||
{ time: '2019-01-09', value: 36.06 },
|
||||
{ time: '2019-01-10', value: 35.82 },
|
||||
{ time: '2019-01-11', value: 35.63 },
|
||||
{ time: '2019-01-14', value: 35.77 },
|
||||
{ time: '2019-01-15', value: 35.83 },
|
||||
{ time: '2019-01-16', value: 35.9 },
|
||||
{ time: '2019-01-17', value: 35.91 },
|
||||
{ time: '2019-01-18', value: 36.21 },
|
||||
{ time: '2019-01-22', value: 34.97 },
|
||||
{ time: '2019-01-23', value: 36.89 },
|
||||
{ time: '2019-01-24', value: 36.24 },
|
||||
{ time: '2019-01-25', value: 35.78 },
|
||||
{ time: '2019-01-28', value: 35.37 },
|
||||
{ time: '2019-01-29', value: 36.08 },
|
||||
{ time: '2019-01-30', value: 35.43 },
|
||||
{ time: '2019-01-31', value: 36.57 },
|
||||
{ time: '2019-02-01', value: 36.79 },
|
||||
{ time: '2019-02-04', value: 36.77 },
|
||||
{ time: '2019-02-05', value: 37.15 },
|
||||
{ time: '2019-02-06', value: 37.17 },
|
||||
{ time: '2019-02-07', value: 37.68 },
|
||||
{ time: '2019-02-08', value: 37.6 },
|
||||
{ time: '2019-02-11', value: 37.0 },
|
||||
{ time: '2019-02-12', value: 37.24 },
|
||||
{ time: '2019-02-13', value: 37.03 },
|
||||
{ time: '2019-02-14', value: 37.26 },
|
||||
{ time: '2019-02-15', value: 37.77 },
|
||||
{ time: '2019-02-19', value: 37.55 },
|
||||
{ time: '2019-02-20', value: 37.79 },
|
||||
{ time: '2019-02-21', value: 38.47 },
|
||||
{ time: '2019-02-22', value: 38.61 },
|
||||
{ time: '2019-02-25', value: 38.57 },
|
||||
{ time: '2019-02-26', value: 38.8 },
|
||||
{ time: '2019-02-27', value: 38.53 },
|
||||
{ time: '2019-02-28', value: 38.67 },
|
||||
{ time: '2019-03-01', value: 39.1 },
|
||||
{ time: '2019-03-04', value: 38.73 },
|
||||
{ time: '2019-03-05', value: 38.72 },
|
||||
{ time: '2019-03-06', value: 38.61 },
|
||||
{ time: '2019-03-07', value: 38.38 },
|
||||
{ time: '2019-03-08', value: 38.19 },
|
||||
{ time: '2019-03-11', value: 39.17 },
|
||||
{ time: '2019-03-12', value: 39.49 },
|
||||
{ time: '2019-03-13', value: 39.56 },
|
||||
{ time: '2019-03-14', value: 39.87 },
|
||||
{ time: '2019-03-15', value: 40.47 },
|
||||
{ time: '2019-03-18', value: 39.92 },
|
||||
{ time: '2019-03-19', value: 39.78 },
|
||||
{ time: '2019-03-20', value: 39.47 },
|
||||
{ time: '2019-03-21', value: 40.05 },
|
||||
{ time: '2019-03-22', value: 39.46 },
|
||||
{ time: '2019-03-25', value: 39.18 },
|
||||
{ time: '2019-03-26', value: 39.63 },
|
||||
{ time: '2019-03-27', value: 40.21 },
|
||||
{ time: '2019-03-28', value: 40.42 },
|
||||
{ time: '2019-03-29', value: 39.98 },
|
||||
{ time: '2019-04-01', value: 40.31 },
|
||||
{ time: '2019-04-02', value: 40.02 },
|
||||
{ time: '2019-04-03', value: 40.27 },
|
||||
{ time: '2019-04-04', value: 40.41 },
|
||||
{ time: '2019-04-05', value: 40.42 },
|
||||
{ time: '2019-04-08', value: 40.71 },
|
||||
{ time: '2019-04-09', value: 41.04 },
|
||||
{ time: '2019-04-10', value: 41.08 },
|
||||
{ time: '2019-04-11', value: 41.04 },
|
||||
{ time: '2019-04-12', value: 41.3 },
|
||||
{ time: '2019-04-15', value: 41.78 },
|
||||
{ time: '2019-04-16', value: 41.97 },
|
||||
{ time: '2019-04-17', value: 42.57 },
|
||||
{ time: '2019-04-18', value: 42.43 },
|
||||
{ time: '2019-04-22', value: 42.0 },
|
||||
{ time: '2019-04-23', value: 41.99 },
|
||||
{ time: '2019-04-24', value: 41.85 },
|
||||
{ time: '2019-04-25', value: 42.93 },
|
||||
{ time: '2019-04-26', value: 43.08 },
|
||||
{ time: '2019-04-29', value: 43.45 },
|
||||
{ time: '2019-04-30', value: 43.53 },
|
||||
{ time: '2019-05-01', value: 43.42 },
|
||||
{ time: '2019-05-02', value: 42.65 },
|
||||
{ time: '2019-05-03', value: 43.29 },
|
||||
{ time: '2019-05-06', value: 43.3 },
|
||||
{ time: '2019-05-07', value: 42.76 },
|
||||
{ time: '2019-05-08', value: 42.55 },
|
||||
{ time: '2019-05-09', value: 42.92 },
|
||||
{ time: '2019-05-10', value: 43.15 },
|
||||
{ time: '2019-05-13', value: 42.28 },
|
||||
{ time: '2019-05-14', value: 42.91 },
|
||||
{ time: '2019-05-15', value: 42.49 },
|
||||
{ time: '2019-05-16', value: 43.19 },
|
||||
{ time: '2019-05-17', value: 43.54 },
|
||||
{ time: '2019-05-20', value: 42.78 },
|
||||
{ time: '2019-05-21', value: 43.29 },
|
||||
{ time: '2019-05-22', value: 43.3 },
|
||||
{ time: '2019-05-23', value: 42.73 },
|
||||
{ time: '2019-05-24', value: 42.67 },
|
||||
{ time: '2019-05-28', value: 42.75 }
|
||||
]
|
173
src/components/LineChart/index.tsx
Normal file
173
src/components/LineChart/index.tsx
Normal file
@ -0,0 +1,173 @@
|
||||
import React, { useRef, useState, useEffect, useCallback, Dispatch, SetStateAction, ReactNode } from 'react'
|
||||
import { createChart, IChartApi } from 'lightweight-charts'
|
||||
import { darken } from 'polished'
|
||||
import { RowBetween } from 'components/Row'
|
||||
import Card from '../Card'
|
||||
|
||||
import styled from 'styled-components'
|
||||
import useTheme from 'hooks/useTheme'
|
||||
|
||||
const Wrapper = styled(Card)`
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
background-color: ${({ theme }) => theme.bg1}
|
||||
flex-direction: column;
|
||||
> * {
|
||||
font-size: 1rem;
|
||||
}
|
||||
`
|
||||
|
||||
const ChartContent = styled.div``
|
||||
|
||||
const DEFAULT_HEIGHT = 300
|
||||
|
||||
export type LineChartProps = {
|
||||
data: any[]
|
||||
color?: string | undefined
|
||||
height?: number | undefined
|
||||
setValue?: Dispatch<SetStateAction<number | undefined>> // used for value on hover
|
||||
topLeft?: ReactNode | undefined
|
||||
topRight?: ReactNode | undefined
|
||||
bottomLeft?: ReactNode | undefined
|
||||
bottomRight?: ReactNode | undefined
|
||||
} & React.HTMLAttributes<HTMLDivElement>
|
||||
|
||||
const LineChart = ({
|
||||
data,
|
||||
color = '#56B2A4',
|
||||
setValue,
|
||||
topLeft,
|
||||
topRight,
|
||||
bottomLeft,
|
||||
bottomRight,
|
||||
height = DEFAULT_HEIGHT,
|
||||
...rest
|
||||
}: LineChartProps) => {
|
||||
const theme = useTheme()
|
||||
|
||||
// reference for DOM element to create with chart
|
||||
const chartRef = useRef(null)
|
||||
|
||||
// pointer to the chart object
|
||||
const [chartCreated, setChart] = useState<IChartApi | undefined>()
|
||||
|
||||
/**
|
||||
* @todo respond to dark mode
|
||||
*/
|
||||
const textColor = '#565A69'
|
||||
|
||||
const currenValue = data[data.length - 1].value
|
||||
|
||||
const isClient = typeof window === 'object'
|
||||
|
||||
const handleResize = useCallback(() => {
|
||||
chartCreated && chartCreated.resize(chartRef.current.parentNode.clientWidth - 32, height)
|
||||
chartCreated && chartCreated.timeScale().fitContent()
|
||||
chartCreated && chartCreated.timeScale().scrollToPosition(0, 0)
|
||||
}, [chartCreated, height])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isClient) {
|
||||
return
|
||||
}
|
||||
window.addEventListener('resize', handleResize)
|
||||
return () => window.removeEventListener('resize', handleResize)
|
||||
}, [isClient, chartRef, handleResize]) // Empty array ensures that effect is only run on mount and unmount
|
||||
|
||||
useEffect(() => {
|
||||
if (!chartCreated && data && chartRef && chartRef.current) {
|
||||
const chart = createChart(chartRef.current, {
|
||||
height: height,
|
||||
width: chartRef.current.parentNode.clientWidth - 32,
|
||||
layout: {
|
||||
backgroundColor: 'transparent',
|
||||
textColor: textColor
|
||||
},
|
||||
rightPriceScale: {
|
||||
scaleMargins: {
|
||||
top: 0.1,
|
||||
bottom: 0.1
|
||||
},
|
||||
borderVisible: false
|
||||
},
|
||||
timeScale: {
|
||||
borderVisible: false
|
||||
},
|
||||
watermark: {
|
||||
color: 'rgba(0, 0, 0, 0)'
|
||||
},
|
||||
grid: {
|
||||
horzLines: {
|
||||
visible: false
|
||||
},
|
||||
vertLines: {
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
crosshair: {
|
||||
horzLine: {
|
||||
visible: true,
|
||||
style: 3,
|
||||
width: 1,
|
||||
color: '#505050',
|
||||
labelBackgroundColor: color
|
||||
},
|
||||
vertLine: {
|
||||
visible: true,
|
||||
style: 3,
|
||||
width: 1,
|
||||
color: '#505050',
|
||||
labelBackgroundColor: color
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const series = chart.addAreaSeries({
|
||||
lineColor: color,
|
||||
topColor: darken(0.4, color),
|
||||
bottomColor: theme.bg1,
|
||||
lineWidth: 2,
|
||||
priceLineVisible: false
|
||||
})
|
||||
|
||||
series.setData(data)
|
||||
|
||||
// update the title when hovering on the chart
|
||||
chart.subscribeCrosshairMove(function(param) {
|
||||
if (
|
||||
param === undefined ||
|
||||
param.time === undefined ||
|
||||
(param && param.point && param.point.x < 0) ||
|
||||
(param && param.point && param.point.x > chartRef.current.clientWidth) ||
|
||||
(param && param.point && param.point.y < 0) ||
|
||||
(param && param.point && param.point.y > height)
|
||||
) {
|
||||
setValue && setValue(currenValue)
|
||||
} else {
|
||||
const price = param.seriesPrices.get(series)
|
||||
setValue && setValue(price)
|
||||
}
|
||||
})
|
||||
|
||||
chart.timeScale().fitContent()
|
||||
setChart(chart)
|
||||
}
|
||||
}, [chartCreated, currenValue, data, height, setValue, textColor, theme.bg1])
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<RowBetween>
|
||||
{topLeft ?? null}
|
||||
{topRight ?? null}
|
||||
</RowBetween>
|
||||
<ChartContent ref={chartRef} id={'test-id'} {...rest} />
|
||||
<RowBetween>
|
||||
{bottomLeft ?? null}
|
||||
{bottomRight ?? null}
|
||||
</RowBetween>
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default LineChart
|
12
yarn.lock
12
yarn.lock
@ -10202,6 +10202,11 @@ fake-merkle-patricia-tree@^1.0.1:
|
||||
dependencies:
|
||||
checkpoint-store "^1.1.0"
|
||||
|
||||
fancy-canvas@0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/fancy-canvas/-/fancy-canvas-0.2.2.tgz#33fd4976724169a1eda5015f515a2a1302d1ec91"
|
||||
integrity sha512-50qi8xA0QkHbjmb8h7XQ6k2fvD7y/yMfiUw9YTarJ7rWrq6o5/3CCXPouYk+XSLASvvxtjyiQLRBFt3qkE3oyA==
|
||||
|
||||
fast-deep-equal@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
|
||||
@ -13331,6 +13336,13 @@ levn@^0.3.0, levn@~0.3.0:
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
|
||||
lightweight-charts@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lightweight-charts/-/lightweight-charts-3.3.0.tgz#cbaafe8977ac342d45e847e12eb5c7b36007358a"
|
||||
integrity sha512-W5jeBrXcHG8eHnIQ0L2CB9TLkrrsjNPlQq5SICPO8PnJ3dJ8jZkLCAwemZ7Ym7ZGCfKCz6ow1EPbyzNYxblnkw==
|
||||
dependencies:
|
||||
fancy-canvas "0.2.2"
|
||||
|
||||
lines-and-columns@^1.1.6:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
||||
|
Loading…
Reference in New Issue
Block a user