mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-12 12:37:55 +00:00
[improvement](webapp) optimize drill down dimensions (#84)
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user