import _ from 'lodash'; import i18next from 'i18next'; import { ThemeProvider } from 'styled-components'; import moment from 'moment'; import PropTypes from 'prop-types'; import React from 'react'; import { getMaxValue } from './utils/transform'; import iconEmptyState from '../images/icon-inpulse-no-data.svg'; import { StockGraphProps } from './interfaces'; import Tooltip from '../Tooltip'; import YAxis from './components/YAxis'; import ComponentLoader from './components/ComponentLoader'; import { GraphContainer, TitleCloseRow, TitleContainer, Title, Subtitle, GraphContent, LegendTitle, LegendContainer, LegendContent, LegendBox, EmptyGraph, DisplayIconNoData, NoDataInfo, } from './styledComponents'; import GraphDisplayComponent from './GraphDisplayComponent'; /* The purpose of this function is to format the overlappedStocks to add them up. We do that so the associated graph bars are on top of each other vertically and not all at the same place over each other. For example if we have this: overlappedStocks = [ { value: 20, color: red, }, { value: 30, color: blue, }, { value: 10, color: yellow, }, ] In this case we want the blue to be displayed with a height of 20px, the red with a height of 30px on top of the blue and the yellow with a height of 10px on top of the red. We need to take the previous bars height into consideration if we don't want them to overlap so the red will be 20px, the blue 50px (20 + 30) and le yellow 60px (20 + 30 + 10) */ const formatData = (data) => { return data.map((item) => { const formattedStock = item.y.stock.map((currentStock) => { if ( !currentStock.overlappedStocks || !currentStock.overlappedStocks.length ) { return currentStock; } const { overlappedStocks } = currentStock.overlappedStocks.reduce( (acc, { value, color }) => { acc.total += value; acc.overlappedStocks.push({ value: acc.total, color }); return acc; }, { overlappedStocks: [], total: 0 } ); return { overlappedStocks, value: currentStock.value }; }); return { ...item, y: { ...item.y, stock: formattedStock } }; }); }; const StockGraph = (props: StockGraphProps): JSX.Element => { const { data, configuration, isLoading, unit, currentDate, hasNoInventoryStockOfEntity, singleBarGraph, theme, graphEmptyStateLabel, hideUnit, timezone, } = props; let maxHeight = 0; let heightYAxis = 0; const formattedData = formatData(data); if (formattedData && formattedData.length) { maxHeight = Math.ceil(getMaxValue(formattedData) / 10) * 10 + 10; // to take the text value into account heightYAxis = maxHeight === 0 ? 4 : Math.round(maxHeight / 4) * 4; } return ( <> e.stopPropagation()}> {/* Title */} {!isLoading && formattedData && formattedData.length > 0 && !!configuration && ( {configuration.title} {configuration.tooltiptext && (
)}
{configuration.subtitle && ( {configuration.subtitle} )}
)} {/* StockGraph Container */} {/* show component loader */} {isLoading && } {/* show empty state "node data" */} {!isLoading && formattedData && formattedData.length === 0 && ( {graphEmptyStateLabel || i18next.t( !hasNoInventoryStockOfEntity ? 'COMPONENT_GRAPH_STOCK_LABEL_NO_DATA' : 'COMPONENT_GRAPH_STOCK_HAS_NO_INVENTORY_STOCK_FOR_ENTITY' )} )} {/* show graphs component */} {!isLoading && formattedData && formattedData.length > 0 && ( <>
{_.map(formattedData, (item, index) => { const itemValue = item.y.stock.map((stock) => { if ( !!stock.overlappedStocks && stock.overlappedStocks.length ) { return Math.max( ...stock.overlappedStocks.map(({ value }) => value) ); } return stock.value; }); const isSelectedDay = moment(item.x).format('MM-DD') === moment(currentDate).format('MM-DD'); const maxTooltipHeight = Math.max(...itemValue); const roundedMaxTooltipHeight = Math.round(maxTooltipHeight * 100) / 100; const columnHeight = maxTooltipHeight ? (roundedMaxTooltipHeight / maxHeight) * 100 : 0; return ( ); })}
)} {/* Legend Container */} {!isLoading && configuration && configuration.legends && formattedData && formattedData.length > 0 && ( {_.map(configuration.legends, (legend, index) => ( {legend.name} ))} )} ); }; StockGraph.propTypes = { hasNoInventoryStockOfEntity: PropTypes.bool, singleBarGraph: PropTypes.bool, graphEmptyStateLabel: PropTypes.string.isRequired, hideUnit: PropTypes.bool, }; StockGraph.defaultProps = { hasNoInventoryStockOfEntity: false, singleBarGraph: false, hideUnit: false, }; export default StockGraph;