import React, { useState } from 'react'; import { Container, ResponsiveWrapper, SvgWrapper } from 'app/shared/modules/chart/core'; import { convertSeriesToLine } from 'app/shared/modules/chart/line/compute/line'; import { generateStackedBars } from 'app/shared/modules/chart/bar/compute'; import { Grid } from 'app/shared/modules/chart/core/axes'; import { LineChart } from 'app/shared/modules/chart/line/LineChart'; import { Bar } from 'app/shared/modules/chart/bar/Bar'; 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 { Tooltip } from 'app/shared/modules/chart/core/tooltip/Tooltip'; import { flatten, maxBy } from 'lodash'; import { selectTceChartData } from '../../store/tceChart.selectors'; import { useDispatch, useSelector } from 'react-redux'; import { clearEarningsPageScroll, selectAggregation } from '../../store/earnings.actions'; import { TceChartTooltip } from './tceChartTooltip'; import { getScreenWidth } from 'app/shared/store/ui/uiSelectors'; import { UI } from 'app/shared/store/ui/ui.constants'; export interface Props { gridPadding?: number, margin?: { top: number, right: number, bottom: number, left: number }, tickCount?: number, } export const TceChart = ({ gridPadding = 10, tickCount = 4, margin = { top: 5, right: 0, bottom: 30, left: 40 }, }: Props) => { const [ tooltip, setTooltip ] = useState({ isVisible: false, position: {}, content: { title: '', tce: '', mode: '', benchmark: '', }, }); const [ shouldAnimate, setAnimation ] = useState(true); const showTooltip = (data) => { setTooltip({ isVisible: true, content: data.content, position: data.position, }); }; const hideTooltip = () => { setTooltip({ ...tooltip, isVisible: false, }); }; const handleLineAnimationEnd = () => { setAnimation(false); }; const dispatch = useDispatch(); const chartData = useSelector(selectTceChartData); const { barSeries, linesSeries, selectedId, } = chartData; const isLargeScreen = useSelector(getScreenWidth) >= UI.BREAK_POINTS.LG; return ( { (size) => { if (!barSeries || barSeries.length === 0) { return (
No data available.
); } const onClick = (currentBar) => { dispatch(selectAggregation(currentBar.data.id)); dispatch(clearEarningsPageScroll()); }; const calcWidth = Number(size?.width) - margin.left - margin.right - gridPadding; const calcHeight = Number(size?.height) - margin.top - margin.bottom - gridPadding; const { position, content, isVisible } = tooltip; let lineValues = flatten(linesSeries.map((c) => c.items)).map((d) => d.value); let barValues = barSeries.map((d) => d.value); let maxValue = maxBy(barValues.concat(lineValues)); const yTicksValues = computeTicksValues(maxValue, tickCount); let maxTickValue = maxBy(yTicksValues); let maxScale = maxValue > maxTickValue? maxValue : maxTickValue; const options = { barSeries, keys: [ 'value' ], minValue: 0, maxValue: maxScale, width: calcWidth, height: calcHeight, padding: 0, innerPadding: 0, }; const barWidth = 12; const barChart = generateStackedBars(options); const lineChart = convertSeriesToLine(linesSeries, barChart.xScale, barChart.yScale); const centerOffset = (calcWidth - (barChart.xScale((barSeries.length - 1).toString())! + barChart.xScale('0')!)) / 2; const horizontalTicks = computeAxisTicks({ width: calcWidth, height: calcHeight, scale: barChart.xScale, values: barChart.xScale.domain(), getLabel: (index) => barSeries[index].label, 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, getLabel: (value) => value.toLocaleString('en-US'), position: 'left', }); const tooltipOffset = { bottom: 60, left: centerOffset + gridPadding + margin.left + barWidth / 2 + 8, right: centerOffset + gridPadding + margin.right + barWidth / 2 + 20, }; const getTooltipPosition = (x, index) => isLargeScreen || index < 2 ? { left: x + tooltipOffset.left, bottom: tooltipOffset.bottom, } : { right: Number(size?.width) - x - tooltipOffset.right, bottom: tooltipOffset.bottom, }; const bars = barChart.bars.map((bar, index) => { const onEnter = () => { showTooltip({ position: getTooltipPosition(bar.x, index), content: bar.data.data.popover }); }; const onLeave = () => { hideTooltip(); }; return ( ); }); return (
{() => { const onEnterDot = (point, index) => { showTooltip({ position: getTooltipPosition(point.x, index), content: point.item.popover }); }; const onLeaveDot = () => { hideTooltip(); }; return (
{/*@ts-ignore*/} {bars}
); }}
{/*@ts-ignore*/} {() => }
); } }
); };