@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
JavaScript
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;