import { useEffect, useState } from 'react'; import { CLS_PREFIX, DATE_TYPES } from '../../../common/constants'; import { ColumnType, DrillDownDimensionType, FieldType, MsgDataType } from '../../../common/type'; import { isMobile } from '../../../utils/utils'; import { queryData } from '../../../service'; import MetricTrendChart from './MetricTrendChart'; import classNames from 'classnames'; import { Spin } from 'antd'; import Table from '../Table'; import DrillDownDimensions from '../../DrillDownDimensions'; import MetricInfo from './MetricInfo'; import FilterSection from '../FilterSection'; type Props = { data: MsgDataType; chartIndex: number; triggerResize?: boolean; onApplyAuth?: (model: string) => void; }; const MetricTrend: React.FC = ({ data, chartIndex, triggerResize, onApplyAuth }) => { const { entityInfo, chatContext, queryMode } = data; const { dateInfo, dimensionFilters, elementMatches } = chatContext || {}; const { dateMode, unit } = dateInfo || {}; const dateOptions = DATE_TYPES[chatContext?.dateInfo?.period] || DATE_TYPES.DAY; const [columns, setColumns] = useState([]); const [activeMetricField, setActiveMetricField] = useState(); const [dataSource, setDataSource] = useState([]); const [currentDateOption, setCurrentDateOption] = useState(); const [dimensions, setDimensions] = useState(); const [drillDownDimension, setDrillDownDimension] = useState(); const [aggregateInfoValue, setAggregateInfoValue] = useState(); const [dateModeValue, setDateModeValue] = useState(); const [loading, setLoading] = useState(false); const dateField: any = columns.find( (column: any) => column.showType === 'DATE' || column.type === 'DATE' ); const dateColumnName = dateField?.nameEn || ''; const categoryColumnName = columns.find((column: any) => column.showType === 'CATEGORY')?.nameEn || ''; const entityId = dimensionFilters?.length > 0 ? dimensionFilters[0].value : undefined; const entityName = elementMatches?.find((item: any) => item.element?.type === 'ID')?.element ?.name; const isEntityMode = (queryMode === 'ENTITY_LIST_FILTER' || queryMode === 'METRIC_ENTITY') && typeof entityId === 'string' && entityName !== undefined; useEffect(() => { const { queryColumns, queryResults, chatContext, aggregateInfo } = data; const initialDateOption = dateOptions.find((option: any) => { return dateMode === 'RECENT' && option.value === unit; })?.value; setColumns(queryColumns || []); setActiveMetricField(chatContext?.metrics?.[0]); setDataSource(queryResults); setCurrentDateOption(initialDateOption); setDimensions(chatContext?.dimensions); setDrillDownDimension(undefined); setAggregateInfoValue(aggregateInfo); setDateModeValue(chatContext?.dateInfo?.dateMode); }, [data]); useEffect(() => { if (queryMode === 'METRIC_GROUPBY') { const dimensionValue = chatContext?.dimensions?.find( dimension => dimension.type === 'DIMENSION' ); setDrillDownDimension(dimensionValue); setDimensions( chatContext?.dimensions?.filter(dimension => dimension.id !== dimensionValue?.id) ); } }, []); const onLoadData = async (value: any) => { setLoading(true); const { data } = await queryData({ ...chatContext, ...value, }); setLoading(false); if (data.code === 200) { setColumns(data.data?.queryColumns || []); setDataSource(data.data?.queryResults || []); setAggregateInfoValue(data.data?.aggregateInfo); } }; const selectDateOption = (dateOption: number) => { setCurrentDateOption(dateOption); setDateModeValue('RECENT'); onLoadData({ metrics: [activeMetricField], dimensions: drillDownDimension ? [...(dimensions || []), drillDownDimension] : undefined, dateInfo: { ...chatContext?.dateInfo, dateMode: 'RECENT', unit: dateOption, }, }); }; const onSwitchMetric = (metricField: FieldType) => { setActiveMetricField(metricField); onLoadData({ dateInfo: { ...chatContext.dateInfo, dateMode: dateModeValue, unit: currentDateOption || chatContext.dateInfo.unit, }, dimensions: drillDownDimension ? [...(dimensions || []), drillDownDimension] : undefined, metrics: [metricField], }); }; const onSelectDimension = (dimension?: DrillDownDimensionType) => { setDrillDownDimension(dimension); onLoadData({ dateInfo: { ...chatContext.dateInfo, dateMode: dateModeValue, unit: currentDateOption || chatContext.dateInfo.unit, }, metrics: [activeMetricField], dimensions: dimension === undefined ? undefined : [...(dimensions || []), dimension], }); }; const currentMetricField = columns.find((column: any) => column.showType === 'NUMBER'); if (!currentMetricField) { return null; } const prefixCls = `${CLS_PREFIX}-metric-trend`; const hasFilterSection = dimensionFilters?.length > 0; return (
{chatContext.metrics.length > 0 && (
{chatContext.metrics.slice(0, 5).map((metricField: FieldType) => { const metricFieldClass = classNames(`${prefixCls}-metric-field`, { [`${prefixCls}-metric-field-active`]: activeMetricField?.bizName === metricField.bizName && chatContext.metrics.length > 1, [`${prefixCls}-metric-field-single`]: chatContext.metrics.length === 1, }); return (
{ if (chatContext.metrics.length > 1) { onSwitchMetric(metricField); } }} > {metricField.name}
); })}
)} {(hasFilterSection || drillDownDimension) && (
(
{drillDownDimension && (
下钻维度:
{drillDownDimension.name}
)}
)
)}
{aggregateInfoValue?.metricInfos?.length > 0 && ( )}
{dateOptions.map((dateOption: { label: string; value: number }, index: number) => { const dateOptionClass = classNames(`${prefixCls}-date-option`, { [`${prefixCls}-date-active`]: dateOption.value === currentDateOption, [`${prefixCls}-date-mobile`]: isMobile, }); return ( <>
{ selectDateOption(dateOption.value); }} > {dateOption.label} {dateOption.value === currentDateOption && (
)}
{index !== dateOptions.length - 1 && (
)} ); })}
{dataSource?.length === 1 || chartIndex % 2 === 1 ? ( ) : ( )} {queryMode.includes('METRIC') && !isEntityMode && ( )} ); }; export default MetricTrend;