UNPKG

@awsui/components-react

Version:

AWS UI is a collection of [React](https://reactjs.org/) components that help create intuitive, responsive, and accessible user experiences for web applications. It is developed by Amazon Web Services (AWS). This work is available under the terms of the [A

119 lines (118 loc) 8.28 kB
import { __assign, __rest } from "tslib"; import React, { useMemo, useCallback, useState } from 'react'; import clsx from 'clsx'; import { scaleOrdinal } from 'd3-scale'; import { getBaseProps } from '../../base-component'; import { useContainerQuery } from '../../hooks/container-queries'; import { fireNonCancelableEvent } from '../../events'; import SpaceBetween from '../../../space-between'; import ChartLegend from '../chart-legend'; import Box from '../../../box'; import Filter from '../chart-filter'; import ChartStatusContainer, { getChartStatus } from '../chart-status-container'; import { parseCssVariable } from '../../utils/dom'; import { categoryPalette } from '../../styles/colors'; import { useControllable } from '../../hooks/use-controllable'; import { ChartScale } from './scales'; import ChartContainer from './chart-container'; import { chartLegendMap } from './utils'; import styles from './styles.css.js'; function MixedChart(_a) { var _b, _c; var _d = _a.height, height = _d === void 0 ? 500 : _d, _e = _a.xScaleType, xScaleType = _e === void 0 ? 'linear' : _e, _f = _a.yScaleType, yScaleType = _f === void 0 ? 'linear' : _f, controlledHighlightedSeries = _a.highlightedSeries, controlledVisibleSeries = _a.visibleSeries, _g = _a.series, externalSeries = _g === void 0 ? [] : _g, onFilterChange = _a.onFilterChange, controlledOnHighlightChange = _a.onHighlightChange, i18nStrings = _a.i18nStrings, yDomain = _a.yDomain, xTitle = _a.xTitle, yTitle = _a.yTitle, _h = _a.stackedBars, stackedBars = _h === void 0 ? false : _h, hideFilter = _a.hideFilter, additionalFilters = _a.additionalFilters, hideLegend = _a.hideLegend, legendTitle = _a.legendTitle, _j = _a.statusType, statusType = _j === void 0 ? 'finished' : _j, _k = _a.detailPopoverSize, detailPopoverSize = _k === void 0 ? 'medium' : _k, empty = _a.empty, noMatch = _a.noMatch, errorText = _a.errorText, loadingText = _a.loadingText, recoveryText = _a.recoveryText, onRecoveryClick = _a.onRecoveryClick, props = __rest(_a, ["height", "xScaleType", "yScaleType", "highlightedSeries", "visibleSeries", "series", "onFilterChange", "onHighlightChange", "i18nStrings", "yDomain", "xTitle", "yTitle", "stackedBars", "hideFilter", "additionalFilters", "hideLegend", "legendTitle", "statusType", "detailPopoverSize", "empty", "noMatch", "errorText", "loadingText", "recoveryText", "onRecoveryClick"]); var baseProps = getBaseProps(props); var _l = useContainerQuery(function (rect, prevWidth) { return prevWidth !== rect.width ? rect.width : prevWidth; }), containerWidth = _l[0], ref = _l[1]; var width = containerWidth || 500; var margins = { left: 50, top: 38, right: 0, bottom: 60 }; var innerWidth = width - margins.left - margins.right; var innerHeight = height - margins.top - margins.bottom; var series = useMemo(function () { var colors = scaleOrdinal(externalSeries.map(function (_, i) { return i; }), categoryPalette); return externalSeries.map(function (s, i) { return ({ index: i, color: parseCssVariable(s.color || colors(i)), series: s }); }); }, [externalSeries]); var _m = useControllable(controlledHighlightedSeries, controlledOnHighlightChange, null, { componentName: 'MixedChart', controlledProp: 'highlightedSeries', changeHandler: 'onHighlightChange' }), highlightedSeries = _m[0], setHighlightedSeries = _m[1]; var _o = useControllable(controlledVisibleSeries, onFilterChange, externalSeries, { componentName: 'MixedChart', controlledProp: 'visibleSeries', changeHandler: 'onFilterChange' }), externalVisibleSeries = _o[0], setExternalVisibleSeries = _o[1]; var _p = useState(null), pinnedSeries = _p[0], setPinnedSeries = _p[1]; var xDomain = (props.xDomain || []); var xScale = new ChartScale(xScaleType, xDomain, [0, innerWidth]); var yScale = new ChartScale(yScaleType, yDomain || [0, 1], [innerHeight, 0]); if (xScale.isCategorical()) { xScale.d3Scale.paddingInner(0.2); xScale.d3Scale.paddingOuter(0.05); } var visibleSeries = useMemo(function () { return series.filter(function (s) { return (externalVisibleSeries === null || externalVisibleSeries === void 0 ? void 0 : externalVisibleSeries.indexOf(s.series)) !== -1; }); }, [ series, externalVisibleSeries ]); var filterItems = series.map(function (_a) { var series = _a.series, color = _a.color; return ({ label: series.title, type: chartLegendMap[series.type], color: color, datum: series }); }); var legendItems = filterItems.filter(function (d) { return (externalVisibleSeries === null || externalVisibleSeries === void 0 ? void 0 : externalVisibleSeries.indexOf(d.datum)) !== -1; }); var highlightedLegendItem = useMemo(function () { if (!highlightedSeries) { return null; } var matches = legendItems.filter(function (item) { return item.datum === highlightedSeries; }); return matches[0] || null; }, [legendItems, highlightedSeries]); var onHighlightChange = useCallback(function (series) { setHighlightedSeries(series); fireNonCancelableEvent(controlledOnHighlightChange, { highlightedSeries: series }); }, [pinnedSeries, setHighlightedSeries, controlledOnHighlightChange]); var filterChange = useCallback(function (selectedSeries) { setExternalVisibleSeries(selectedSeries); fireNonCancelableEvent(onFilterChange, { visibleSeries: selectedSeries }); }, [setExternalVisibleSeries, onFilterChange]); var _q = getChartStatus({ externalData: externalSeries, visibleData: visibleSeries || [], statusType: statusType }), isEmpty = _q.isEmpty, isNoMatch = _q.isNoMatch, showChart = _q.showChart; var reserveLegendSpace = !showChart && !hideLegend; var reserveFilterSpace = !showChart && !isNoMatch && (!hideFilter || additionalFilters); var className = clsx(baseProps.className, styles.root); return (React.createElement("div", __assign({ ref: ref }, baseProps, { className: className }), statusType === 'finished' && (!isEmpty || isNoMatch) && (React.createElement(Box, { className: styles['filter-container'], margin: { bottom: 'l' } }, React.createElement(SpaceBetween, { size: "l", direction: "horizontal", className: clsx((_b = {}, _b[styles['has-default-filter']] = !hideFilter, _b)) }, !hideFilter && (React.createElement(Filter, { series: filterItems, onChange: filterChange, selectedSeries: externalVisibleSeries, i18nStrings: i18nStrings })), additionalFilters))), React.createElement("div", { className: clsx(styles.content, (_c = {}, _c[styles['content--reserve-filter']] = reserveFilterSpace, _c[styles['content--reserve-legend']] = reserveLegendSpace, _c)), style: { minHeight: height } }, React.createElement(ChartStatusContainer, { isEmpty: isEmpty, isNoMatch: isNoMatch, showChart: showChart, statusType: statusType, empty: empty, noMatch: noMatch, loadingText: loadingText, errorText: errorText, recoveryText: recoveryText, onRecoveryClick: onRecoveryClick }), showChart && (React.createElement(ChartContainer, { height: height, width: width, xScaleType: xScaleType, yScaleType: yScaleType, stackedBars: stackedBars, series: series, visibleSeries: visibleSeries, highlightedSeries: highlightedSeries, onHighlightChange: onHighlightChange, pinnedSeries: pinnedSeries, setPinnedSeries: setPinnedSeries, xTitle: xTitle, yTitle: yTitle, xScale: xScale, yScale: yScale }))), React.createElement(SpaceBetween, { size: "m" }, !hideLegend && !isEmpty && statusType === 'finished' && (React.createElement(ChartLegend, { series: legendItems, highlightedSeries: highlightedLegendItem, legendTitle: legendTitle, ariaLabel: i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.legendAriaLabel, onHighlightChange: onHighlightChange }))))); } export default MixedChart;