UNPKG

@spaced-out/ui-design-system

Version:
159 lines (142 loc) 3.65 kB
// @flow strict import * as React from 'react'; //$FlowFixMe[untyped-import] import Highcharts from 'highcharts'; //$FlowFixMe[untyped-import] import HighchartsReact from 'highcharts-react-official'; import type { ChartOptions, Drilldown, LegendOptionsType, SeriesOptionsType, } from '../../../types/charts'; import { getDataVizColor, getDonutChartOptions, mergeChartUserOptions, } from '../../../utils/charts'; import classify from '../../../utils/classify'; import { type ChartWrapperClassNames, type ExportOptionType, ChartWrapper, } from '../ChartWrapper'; import typographyCss from '../../../styles/typography.module.css'; import css from './DonutChart.module.css'; export type ClassNames = $ReadOnly<{ ...ChartWrapperClassNames, highChart?: string, subtitleClassNames?: SubtitleClassNames, }>; export type SubtitleClassNames = { wrapper?: string, text?: string, subtext?: string, }; export type DonutChartProps = { ...ChartOptions, isLoading?: boolean, classNames?: ClassNames, cardTitle?: React.Node, customExportOptions?: Array<ExportOptionType> | null, headerActions?: React.Node, centerText?: string, centerSubtext?: string, series: Array<SeriesOptionsType>, drilldown?: Drilldown, legend?: LegendOptionsType, hasEmptyData?: boolean, emptyText?: React.Node, ... }; export const DonutChart = ({ isLoading, classNames, cardTitle, customExportOptions, headerActions, series, drilldown, legend, centerText, centerSubtext, hasEmptyData, emptyText, ...userOptions }: DonutChartProps): React.Node => { const chartRef = React.useRef(); const {highChart, subtitleClassNames, ...wrapperClassNames} = classNames || {}; const defaultCenterHTML = `<span class=${classify( css.subtitleWrap, subtitleClassNames?.wrapper, )}> <span class="${classify( typographyCss.jumboMedium, css.subtitleText, subtitleClassNames?.text, )}"> ${centerText ? centerText : ''} </span> <span class="${classify( typographyCss.bodySmall, css.subtitleSubtext, subtitleClassNames?.subtext, )}"> ${centerSubtext ? centerSubtext : ''} </span> <span>`; const donutChartSeries = series.map((seriesItem) => ({ ...seriesItem, data: seriesItem.data.map((dataItem, index) => ({ ...dataItem, color: getDataVizColor(index), })), })); const addColorToDrilldownSeries = (series) => series?.map((seriesItem) => ({ ...seriesItem, data: seriesItem.data.map((dataItem, index) => ({ ...dataItem, color: getDataVizColor(index), })), })); const donutDrilldown = drilldown ? { ...drilldown, series: addColorToDrilldownSeries(drilldown.series), breadcrumbs: {floating: false}, } : {}; const defaultLineChartOptions = getDonutChartOptions({ legend, defaultCenterHTML, }); //$FlowFixMe[cannot-spread-inexact] const chartOptions = mergeChartUserOptions(defaultLineChartOptions, { series: donutChartSeries, drilldown: donutDrilldown, ...userOptions, }); return ( <ChartWrapper isLoading={isLoading} title={cardTitle} ref={chartRef} customExportOptions={customExportOptions} headerActions={headerActions} classNames={wrapperClassNames} hasEmptyData={hasEmptyData} emptyText={emptyText} > <HighchartsReact highcharts={Highcharts} containerProps={{ className: classify(css.donutChartContainer, highChart), }} ref={chartRef} options={chartOptions} /> </ChartWrapper> ); };