import React, { useState } from 'react'; import { Container, SvgWrapper } from 'app/shared/modules/chart/core'; import { generateStackedBars } from 'app/shared/modules/chart/bar/compute'; import { Grid } from 'app/shared/modules/chart/core/axes'; import { Axis } from 'app/shared/modules/chart/core/axes/Axis'; import { computeAxisTicks, computeTicksValues } from 'app/shared/modules/chart/core/axes/compute/cartesian'; import { Group } from 'app/shared/modules/chart/core/containers/Group'; import { maxBy, round } from 'lodash'; import { FillableBar } from 'app/shared/modules/chart/bar/FillableBar'; import { useDispatch, useSelector } from 'react-redux'; import { dashboardSetCurrentPoolKeyFigures } from 'app/modules/dashboard/store/dashboard.actions'; import { getDashboardChartData } from 'app/modules/dashboard/store/dashboard.selectors'; import { getScreenWidth } from 'app/shared/store/ui/uiSelectors'; import { Spacings } from 'app/shared/types/common.types'; import { UI } from 'app/shared/store/ui/ui.constants'; import { Tooltip } from 'app/shared/modules/chart/core/tooltip/Tooltip'; import moneyPipe from 'app/shared/pipes/money.pipe'; import { DashboardChartTooltip } from './dashboardChartTooltip'; import datePipe from 'app/shared/pipes/date.pipe'; export interface Props { width: number; height: number; margin?: Spacings; gridPadding?: number; tickCount?: number; paddingRight?: number; } const DashboardChart = ({ margin = { top: 10, right: 15, bottom: 30, left: 40 }, gridPadding = 16, tickCount = 4, paddingRight = 16, width, height, }: Props) => { const chartData = useSelector(getDashboardChartData); const { maxValue, barSeries, selectedId } = chartData; const isLargeScreen = useSelector(getScreenWidth) >= UI.BREAK_POINTS.LG; const [ tooltip, setTooltip ] = useState({ isVisible: false, content: { date: '', earnings: '', fixed: null, isSelected: false, }, position: {}, }); const showTooltip = (data) => { setTooltip({ isVisible: true, content: data.tooltipContent, position: data.tooltipPosition, }); }; const hideTooltip = () => { setTooltip({ ...tooltip, isVisible: false, }); }; const calcWidth = width - margin.left - margin.right - gridPadding; const calcHeight = height - margin.top - margin.bottom - gridPadding; const xScaleStartOffset = 10; const yAxisTextOffset = 3; const barWidth = 16; const yTicksValues = computeTicksValues(maxValue, tickCount); const maxTickValue = maxBy(yTicksValues); const maxScale = maxValue > maxTickValue? maxValue : maxTickValue; const options = { barSeries, keys: [ 'value' ], minValue: 0, maxValue: maxScale, width: calcWidth, height: calcHeight, padding: 0, innerPadding: 0, }; const barChart = generateStackedBars(options); const centerOffset = (calcWidth - ((barChart.xScale((barSeries.length - 1).toString()) ?? 0) + (barChart.xScale('0') ?? 0))) / 2 - xScaleStartOffset; const horizontalTicks = computeAxisTicks({ width: calcWidth, height: calcHeight, scale: barChart.xScale, values: barChart.xScale.domain(), getLabel: (index) => barSeries[index].label.toString(), getSubLabel: (index) => barSeries[index].subLabel, position: 'bottom', isSelected: (value) => barSeries[value].id === selectedId, }); const verticalTicks = computeAxisTicks({ width: calcWidth, height: calcHeight, scale: barChart.yScale, values: yTicksValues, position: 'left', }); const tooltipOffset = { bottom: 60, left: centerOffset + gridPadding + margin.left + barWidth / 2 + 8, right: centerOffset + gridPadding + margin.right + barWidth / 2, }; const bars = barChart.bars.map((bar, index) => { const roundedFilledHeight = round(bar.height * round(bar.data.data.filledRatio / 100, 2)); bar.filledHeight = roundedFilledHeight !== null && roundedFilledHeight !== undefined ? roundedFilledHeight : bar.height; const onEnter = () => { const tooltipPosition = isLargeScreen || index < 1 ? { left: bar.x + tooltipOffset.left, bottom: tooltipOffset.bottom, } : { right: width - bar.x - tooltipOffset.right, bottom: tooltipOffset.bottom, }; const tooltipContent = { date: datePipe.formatShortMonthWithYear(bar.data.data.date), earnings: moneyPipe.format(bar.data.value), fixed: bar.data.data.filledRatio === 100 || bar.data.data.filledRatio === null ? null : `${bar.data.data.filledRatio}% fixed`, isSelected: bar.data.data.id === selectedId, }; showTooltip({ tooltipPosition, tooltipContent }); }; const onLeave = () => { hideTooltip(); }; const dispatch = useDispatch(); return ( dispatch(dashboardSetCurrentPoolKeyFigures(data.data.id))} {...bar} selected={bar.data.data.id === selectedId} animate onEnter={onEnter} onLeave={onLeave} width={barWidth} /> ); }); return (
{() => (
{/*@ts-ignore*/} {bars} USD /DAY
)}
{/* @ts-ignore*/} {() => }
); }; export { DashboardChart };