[improvement](webapp) optimize drill down dimensions (#84)

This commit is contained in:
williamhliu
2023-09-13 15:05:23 +08:00
committed by GitHub
parent c8b5c0f3a3
commit c38507d50c
18 changed files with 322 additions and 380 deletions

View File

@@ -2,12 +2,14 @@ import Bar from './Bar';
import MetricCard from './MetricCard';
import MetricTrend from './MetricTrend';
import Table from './Table';
import { ColumnType, DrillDownDimensionType, MsgDataType } from '../../common/type';
import { ColumnType, DrillDownDimensionType, FieldType, MsgDataType } from '../../common/type';
import { useEffect, useState } from 'react';
import { queryData } from '../../service';
import classNames from 'classnames';
import { PREFIX_CLS } from '../../common/constants';
import Text from './Text';
import DrillDownDimensions from '../DrillDownDimensions';
import MetricOptions from '../MetricOptions';
type Props = {
data: MsgDataType;
@@ -16,14 +18,18 @@ type Props = {
};
const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
const { queryColumns, queryResults, chatContext, queryMode } = data;
const { queryColumns, queryResults, chatContext, queryMode } = data || {};
const { dimensionFilters, elementMatches } = chatContext || {};
const [columns, setColumns] = useState<ColumnType[]>();
const [referenceColumn, setReferenceColumn] = useState<ColumnType>();
const [dataSource, setDataSource] = useState<any[]>(queryResults);
const [drillDownDimension, setDrillDownDimension] = useState<DrillDownDimensionType>();
const [loading, setLoading] = useState(false);
const [defaultMetricField, setDefaultMetricField] = useState<FieldType>();
const [activeMetricField, setActiveMetricField] = useState<FieldType>();
const [dateModeValue, setDateModeValue] = useState<any>();
const [currentDateOption, setCurrentDateOption] = useState<number>();
const prefixCls = `${PREFIX_CLS}-chat-msg`;
@@ -36,7 +42,11 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
useEffect(() => {
updateColummns(queryColumns);
setDataSource(queryResults);
}, [queryColumns, queryResults]);
setDefaultMetricField(chatContext?.metrics?.[0]);
setActiveMetricField(chatContext?.metrics?.[0]);
setDateModeValue(chatContext?.dateInfo?.dateMode);
setCurrentDateOption(chatContext?.dateInfo?.unit);
}, [data]);
if (!queryColumns || !queryResults || !columns) {
return null;
@@ -69,6 +79,52 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
queryMode === 'ENTITY_DIMENSION' ||
(categoryField.length === 1 && metricFields.length === 0));
const getMsgContent = () => {
if (isText) {
return <Text columns={columns} referenceColumn={referenceColumn} dataSource={dataSource} />;
}
if (isMetricCard) {
return (
<MetricCard
data={{ ...data, queryColumns: columns, queryResults: dataSource }}
loading={loading}
/>
);
}
if (isTable) {
return <Table data={{ ...data, queryColumns: columns, queryResults: dataSource }} />;
}
if (dateField && metricFields.length > 0) {
if (!dataSource.every(item => item[dateField.nameEn] === dataSource[0][dateField.nameEn])) {
return (
<MetricTrend
data={{
...data,
queryColumns: columns,
queryResults: dataSource,
}}
loading={loading}
chartIndex={chartIndex}
triggerResize={triggerResize}
activeMetricField={activeMetricField}
currentDateOption={currentDateOption}
onSelectDateOption={selectDateOption}
/>
);
}
}
if (categoryField?.length > 0 && metricFields?.length > 0) {
return (
<Bar
data={{ ...data, queryColumns: columns, queryResults: dataSource }}
triggerResize={triggerResize}
loading={loading}
/>
);
}
return <Table data={{ ...data, queryColumns: columns, queryResults: dataSource }} />;
};
const onLoadData = async (value: any) => {
setLoading(true);
const { data } = await queryData({
@@ -85,58 +141,94 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
const onSelectDimension = (dimension?: DrillDownDimensionType) => {
setDrillDownDimension(dimension);
onLoadData({
dimensions:
dimension === undefined ? undefined : [...(chatContext.dimensions || []), dimension],
dateInfo: {
...chatContext.dateInfo,
dateMode: dateModeValue,
unit: currentDateOption || chatContext.dateInfo.unit,
},
dimensions: dimension
? [...(chatContext.dimensions || []), dimension]
: chatContext.dimensions,
metrics: [activeMetricField || defaultMetricField],
});
};
const getMsgContent = () => {
if (isText) {
return <Text columns={columns} referenceColumn={referenceColumn} dataSource={dataSource} />;
}
if (isMetricCard) {
return (
<MetricCard
data={{ ...data, queryColumns: columns, queryResults: dataSource }}
loading={loading}
drillDownDimension={drillDownDimension}
onSelectDimension={onSelectDimension}
/>
);
}
if (isTable) {
return <Table data={{ ...data, queryColumns: columns, queryResults: dataSource }} />;
}
if (dateField && metricFields.length > 0) {
if (!dataSource.every(item => item[dateField.nameEn] === dataSource[0][dateField.nameEn])) {
return (
<MetricTrend
data={{ ...data, queryColumns: columns, queryResults: dataSource }}
chartIndex={chartIndex}
triggerResize={triggerResize}
/>
);
}
}
if (categoryField?.length > 0 && metricFields?.length > 0) {
return (
<Bar
data={{ ...data, queryColumns: columns, queryResults: dataSource }}
triggerResize={triggerResize}
loading={loading}
drillDownDimension={drillDownDimension}
onSelectDimension={onSelectDimension}
/>
);
}
return <Table data={{ ...data, queryColumns: columns, queryResults: dataSource }} />;
const onSwitchMetric = (metricField?: FieldType) => {
setActiveMetricField(metricField);
onLoadData({
dateInfo: {
...chatContext.dateInfo,
dateMode: dateModeValue,
unit: currentDateOption || chatContext.dateInfo.unit,
},
dimensions: drillDownDimension
? [...(chatContext.dimensions || []), drillDownDimension]
: chatContext.dimensions,
metrics: [metricField || defaultMetricField],
});
};
const selectDateOption = (dateOption: number) => {
setCurrentDateOption(dateOption);
setDateModeValue('RECENT');
onLoadData({
metrics: [activeMetricField || defaultMetricField],
dimensions: drillDownDimension
? [...(chatContext.dimensions || []), drillDownDimension]
: chatContext.dimensions,
dateInfo: {
...chatContext?.dateInfo,
dateMode: 'RECENT',
unit: dateOption,
},
});
};
const chartMsgClass = classNames({ [prefixCls]: !isTable });
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;
const existDrillDownDimension = queryMode.includes('METRIC') && !isText && !isEntityMode;
const isMultipleMetric = existDrillDownDimension && chatContext?.metrics?.length > 1;
return (
<div className={chartMsgClass}>
{dataSource?.length === 0 ? <div></div> : getMsgContent()}
{dataSource?.length === 0 ? (
<div></div>
) : (
<div>
{getMsgContent()}
{(isMultipleMetric || existDrillDownDimension) && (
<div className={`${prefixCls}-bottom-tools`}>
{isMultipleMetric && (
<MetricOptions
metrics={chatContext.metrics}
defaultMetric={defaultMetricField}
currentMetric={activeMetricField}
onSelectMetric={onSwitchMetric}
/>
)}
{existDrillDownDimension && (
<DrillDownDimensions
modelId={chatContext.modelId}
drillDownDimension={drillDownDimension}
originDimensions={chatContext.dimensions}
dimensionFilters={chatContext.dimensionFilters}
onSelectDimension={onSelectDimension}
/>
)}
</div>
)}
</div>
)}
</div>
);
};