import { ValueStatus } from "mendix" ; import { useEffect , useMemo , useState } from "react" ; import { ensure } from "@mendix/pluggable-widgets-tools" ; import Big from "big.js" ; import { compareAsc } from "date-fns" ; import { PieChartContainerProps } from "../../typings/PieChartProps" ; import { ChartProps } from "@mendix/shared-charts/dist/components/Chart" ; import { executeAction } from "@mendix/piw-utils-internal" ; type PieChartDataSeriesHooks = Pick < PieChartContainerProps , "chartFormat" | "customSeriesOptions" | "seriesColorAttribute" | "seriesDataSource" | "seriesName" | "seriesSortAttribute" | "seriesSortOrder" | "seriesValueAttribute" | "onClickAction" | "tooltipHoverText" > ; type LocalPieChartData = { itemName : string | undefined ; itemValue : number | undefined ; itemColor : string | undefined ; itemSortValue : string | boolean | Date | Big | undefined ; itemHoverText : string | undefined ; } ; export const usePieChartDataSeries = ( { chartFormat , customSeriesOptions , seriesColorAttribute , seriesDataSource , seriesName , seriesSortAttribute , seriesSortOrder , seriesValueAttribute , onClickAction , tooltipHoverText } ) : ChartProps [ "data" ] => { const [ pieChartData , setPieChartData ] = useState < LocalPieChartData [ ] > ( [ ] ) ; useEffect ( ( ) => { if ( seriesDataSource . status === ValueStatus . Available && seriesDataSource . items ) { const dataSourceItems = seriesDataSource . items . map ( dataSourceItem => ( { itemName : seriesName . get ( dataSourceItem ) . value , itemValue : ensure ( seriesValueAttribute ) . get ( dataSourceItem ) . value ?. toNumber ( ) , itemColor : seriesColorAttribute ?. get ( dataSourceItem ) . value , itemSortValue : seriesSortAttribute ?. get ( dataSourceItem ) . value , itemHoverText : tooltipHoverText ?. get ( dataSourceItem ) . value } ) ) ; if ( seriesSortAttribute ) { dataSourceItems . sort ( seriesSortAttributeCompareFn ) ; if ( seriesSortOrder === "desc" ) { dataSourceItems . reverse ( ) ; } } setPieChartData ( dataSourceItems ) ; } } , [ seriesColorAttribute , seriesDataSource , seriesName , seriesSortAttribute , seriesSortOrder , seriesValueAttribute , tooltipHoverText ] ) ; const onClick = useMemo ( ( ) => ( onClickAction ? ( ) => executeAction ( onClickAction ) : undefined ) , [ onClickAction ] ) ; return useMemo < ChartProps [ "data" ] > ( ( ) => [ { customSeriesOptions , hole : chartFormat === "pie" ? 0 : 0.4 , labels : pieChartData . map ( ( { itemName } ) => itemName ?? null ) , values : pieChartData . map ( ( { itemValue } ) => itemValue ?? 0 ) , marker : { colors : pieChartData . map ( ( { itemColor } ) => itemColor ) } , hovertext : pieChartData . map ( ( { itemHoverText } ) => itemHoverText ?? "" ) , hoverinfo : pieChartData . some ( ( { itemHoverText } ) => itemHoverText !== undefined && itemHoverText !== "" ) ? "text" : "none" , onClick } ] , [ customSeriesOptions , chartFormat , pieChartData , onClick ] ) ; } ; function seriesSortAttributeCompareFn ( { itemSortValue : firstItemSortValue } , { itemSortValue : secondItemSortValue } ) { if ( firstItemSortValue === undefined || secondItemSortValue === undefined ) { if ( firstItemSortValue === secondItemSortValue ) { return 0 ; } return firstItemSortValue === undefined ? 1 : - 1 ; } if ( typeof firstItemSortValue !== typeof secondItemSortValue ) { return 0 ; } if ( typeof firstItemSortValue === "string" || typeof secondItemSortValue === "string" || typeof firstItemSortValue === "boolean" || typeof secondItemSortValue === "boolean" ) { return firstItemSortValue . toString ( ) . localeCompare ( secondItemSortValue . toString ( ) ) ; } if ( firstItemSortValue instanceof Date || secondItemSortValue instanceof Date ) { return compareAsc ( firstItemSortValue , secondItemSortValue ) ; } return firstItemSortValue . minus ( secondItemSortValue ) . toNumber ( ) ; }