mirror of
https://github.com/tencentmusic/supersonic.git
synced 2026-01-23 20:14:10 +08:00
Compare commits
9 Commits
608b675759
...
8d34dcd5dd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d34dcd5dd | ||
|
|
06fb6ba744 | ||
|
|
9ffdba956e | ||
|
|
fa65b6eff7 | ||
|
|
0ab44c0866 | ||
|
|
449fdf180f | ||
|
|
d275a145d5 | ||
|
|
c8f690c1c2 | ||
|
|
38af6e3a28 |
@@ -88,10 +88,10 @@ public class WebServiceQuery extends PluginSemanticQuery {
|
||||
restTemplate = ContextUtils.getBean(RestTemplate.class);
|
||||
try {
|
||||
responseEntity =
|
||||
restTemplate.exchange(requestUrl, HttpMethod.POST, entity, Object.class);
|
||||
restTemplate.exchange(requestUrl, HttpMethod.POST, entity, String.class);
|
||||
objectResponse = responseEntity.getBody();
|
||||
log.info("objectResponse:{}", objectResponse);
|
||||
Map<String, Object> response = JsonUtil.objectToMap(objectResponse);
|
||||
Map<String, Object> response = JSON.parseObject(objectResponse.toString());
|
||||
webServiceResponse.setResult(response);
|
||||
} catch (Exception e) {
|
||||
log.info("Exception:{}", e.getMessage());
|
||||
|
||||
@@ -19,7 +19,7 @@ public class ParseContext {
|
||||
}
|
||||
|
||||
public boolean enableNL2SQL() {
|
||||
return Objects.nonNull(agent) && agent.containsDatasetTool();
|
||||
return Objects.nonNull(agent) && agent.containsDatasetTool()&&response.getSelectedParses().size() == 0;
|
||||
}
|
||||
|
||||
public boolean enableLLM() {
|
||||
|
||||
@@ -1,18 +1,3 @@
|
||||
export const THEME_COLOR_LIST = [
|
||||
'#3369FF',
|
||||
'#36D2B8',
|
||||
'#DB8D76',
|
||||
'#47B359',
|
||||
'#8545E6',
|
||||
'#E0B18B',
|
||||
'#7258F3',
|
||||
'#0095FF',
|
||||
'#52CC8F',
|
||||
'#6675FF',
|
||||
'#CC516E',
|
||||
'#5CA9E6',
|
||||
];
|
||||
|
||||
export enum SemanticTypeEnum {
|
||||
MODEL = 'MODEL',
|
||||
DIMENSION = 'DIMENSION',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CHART_BLUE_COLOR, CHART_SECONDARY_COLOR, PREFIX_CLS } from '../../../common/constants';
|
||||
import { MsgDataType } from '../../../common/type';
|
||||
import {
|
||||
formatByDecimalPlaces,
|
||||
formatByDataFormatType,
|
||||
getChartLightenColor,
|
||||
getFormattedValue,
|
||||
} from '../../../utils/utils';
|
||||
@@ -94,7 +94,7 @@ const BarChart: React.FC<Props> = ({
|
||||
return value === 0
|
||||
? 0
|
||||
: metricField.dataFormatType === 'percent'
|
||||
? `${formatByDecimalPlaces(metricField.dataFormat?.needMultiply100 ? +value * 100 : value, metricField.dataFormat?.decimalPlaces || 2)}%`
|
||||
? formatByDataFormatType(value, metricField.dataFormatType, metricField.dataFormat)
|
||||
: getFormattedValue(value);
|
||||
},
|
||||
},
|
||||
@@ -115,10 +115,7 @@ const BarChart: React.FC<Props> = ({
|
||||
? '-'
|
||||
: metricField.dataFormatType === 'percent' ||
|
||||
metricField.dataFormatType === 'decimal'
|
||||
? `${formatByDecimalPlaces(
|
||||
metricField.dataFormat?.needMultiply100 ? +item.value * 100 : item.value,
|
||||
metricField.dataFormat?.decimalPlaces || 2
|
||||
)}${metricField.dataFormatType === 'percent' ? '%' : ''}`
|
||||
? formatByDataFormatType(item.value, metricField.dataFormatType, metricField.dataFormat)
|
||||
: getFormattedValue(item.value)
|
||||
}</span></div>`
|
||||
)
|
||||
@@ -151,7 +148,7 @@ const BarChart: React.FC<Props> = ({
|
||||
return value === 0
|
||||
? 0
|
||||
: metricField.dataFormatType === 'percent'
|
||||
? `${formatByDecimalPlaces(metricField.dataFormat?.needMultiply100 ? +value * 100 : value, metricField.dataFormat?.decimalPlaces || 2)}%`
|
||||
? formatByDataFormatType(value, metricField.dataFormatType, metricField.dataFormat)
|
||||
: getFormattedValue(value);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PREFIX_CLS } from '../../../common/constants';
|
||||
import { formatByDecimalPlaces, formatMetric, formatNumberWithCN } from '../../../utils/utils';
|
||||
import { formatByDataFormatType, formatMetric, formatNumberWithCN } from '../../../utils/utils';
|
||||
import ApplyAuth from '../ApplyAuth';
|
||||
import { MsgDataType } from '../../../common/type';
|
||||
import PeriodCompareItem from './PeriodCompareItem';
|
||||
@@ -52,10 +52,7 @@ const MetricCard: React.FC<Props> = ({ data, question, loading, onApplyAuth }) =
|
||||
{typeof value === 'string' && isNaN(+value)
|
||||
? value
|
||||
: dataFormatType === 'percent' || dataFormatType === 'decimal'
|
||||
? `${formatByDecimalPlaces(
|
||||
dataFormat?.needMultiply100 ? +value * 100 : value,
|
||||
dataFormat?.decimalPlaces || 2
|
||||
)}${dataFormatType === 'percent' ? '%' : ''}`
|
||||
? formatByDataFormatType(value, dataFormatType, dataFormat)
|
||||
: isNumber
|
||||
? formatMetric(value) || '-'
|
||||
: formatNumberWithCN(+value)}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PREFIX_CLS } from '../../../common/constants';
|
||||
import { formatByDecimalPlaces, formatMetric, formatNumberWithCN } from '../../../utils/utils';
|
||||
import { formatByDataFormatType, formatMetric, formatNumberWithCN } from '../../../utils/utils';
|
||||
import { AggregateInfoType, ColumnType } from '../../../common/type';
|
||||
import PeriodCompareItem from '../MetricCard/PeriodCompareItem';
|
||||
import { SwapOutlined } from '@ant-design/icons';
|
||||
@@ -29,10 +29,7 @@ const MetricInfo: React.FC<Props> = ({ aggregateInfo, currentMetricField }) => {
|
||||
<div style={{ display: 'flex', alignItems: 'flex-end' }}>
|
||||
<div className={`${prefixCls}-indicator-value`}>
|
||||
{dataFormatType === 'percent' || dataFormatType === 'decimal'
|
||||
? `${formatByDecimalPlaces(
|
||||
dataFormat?.needMultiply100 ? +value * 100 : value,
|
||||
dataFormat?.decimalPlaces || 2
|
||||
)}${dataFormatType === 'percent' ? '%' : ''}`
|
||||
? formatByDataFormatType(value, dataFormatType, dataFormat)
|
||||
: isNumber
|
||||
? formatMetric(value)
|
||||
: formatNumberWithCN(+value)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CHART_SECONDARY_COLOR, CLS_PREFIX, THEME_COLOR_LIST } from '../../../common/constants';
|
||||
import {
|
||||
formatByDecimalPlaces,
|
||||
formatByDataFormatType,
|
||||
getFormattedValue,
|
||||
getMinMaxDate,
|
||||
groupByColumn,
|
||||
@@ -134,7 +134,7 @@ const MetricTrendChart: React.FC<Props> = ({
|
||||
return value === 0
|
||||
? 0
|
||||
: metricField.dataFormatType === 'percent'
|
||||
? `${formatByDecimalPlaces(value, metricField.dataFormat?.decimalPlaces || 2)}%`
|
||||
? formatByDataFormatType(value, metricField.dataFormatType, metricField.dataFormat)
|
||||
: getFormattedValue(value);
|
||||
},
|
||||
},
|
||||
@@ -156,10 +156,7 @@ const MetricTrendChart: React.FC<Props> = ({
|
||||
? '-'
|
||||
: metricField.dataFormatType === 'percent' ||
|
||||
metricField.dataFormatType === 'decimal'
|
||||
? `${formatByDecimalPlaces(
|
||||
item.value,
|
||||
metricField.dataFormat?.decimalPlaces || 2
|
||||
)}${metricField.dataFormatType === 'percent' ? '%' : ''}`
|
||||
? formatByDataFormatType(item.value, metricField.dataFormatType, metricField.dataFormat)
|
||||
: getFormattedValue(item.value)
|
||||
}</span></div>`
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { PREFIX_CLS, THEME_COLOR_LIST } from '../../../common/constants';
|
||||
import { MsgDataType } from '../../../common/type';
|
||||
import { formatByDecimalPlaces, getFormattedValue } from '../../../utils/utils';
|
||||
import { formatByDataFormatType, getFormattedValue } from '../../../utils/utils';
|
||||
import type { ECharts } from 'echarts';
|
||||
import * as echarts from 'echarts';
|
||||
import { useEffect, useRef } from 'react';
|
||||
@@ -55,10 +55,7 @@ const PieChart: React.FC<Props> = ({
|
||||
const value = params.value;
|
||||
return `${params.name}: ${
|
||||
metricField.dataFormatType === 'percent'
|
||||
? `${formatByDecimalPlaces(
|
||||
metricField.dataFormat?.needMultiply100 ? +value * 100 : value,
|
||||
metricField.dataFormat?.decimalPlaces || 2
|
||||
)}%`
|
||||
? formatByDataFormatType(value, metricField.dataFormatType, metricField.dataFormat)
|
||||
: getFormattedValue(value)
|
||||
}`;
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { formatByDecimalPlaces, formatByThousandSeperator } from '../../../utils/utils';
|
||||
import { formatByDataFormatType, formatByThousandSeperator } from '../../../utils/utils';
|
||||
import { Table as AntTable } from 'antd';
|
||||
import { MsgDataType } from '../../../common/type';
|
||||
import { CLS_PREFIX } from '../../../common/constants';
|
||||
@@ -42,10 +42,7 @@ const Table: React.FC<Props> = ({ data, size, loading, question, onApplyAuth })
|
||||
<div className={`${prefixCls}-formatted-value`}>
|
||||
{`${
|
||||
value
|
||||
? formatByDecimalPlaces(
|
||||
dataFormat?.needMultiply100 ? +value * 100 : value,
|
||||
dataFormat?.decimalPlaces || 2
|
||||
)
|
||||
? formatByDataFormatType(value, dataFormatType, dataFormat)
|
||||
: 0
|
||||
}%`}
|
||||
</div>
|
||||
|
||||
@@ -52,14 +52,14 @@ const ChatMsg: React.FC<Props> = ({
|
||||
|
||||
const prefixCls = `${PREFIX_CLS}-chat-msg`;
|
||||
|
||||
const updateColummns = (queryColumnsValue: ColumnType[]) => {
|
||||
const updateColumns = (queryColumnsValue: ColumnType[]) => {
|
||||
const referenceColumn = queryColumnsValue.find(item => item.showType === 'more');
|
||||
setReferenceColumn(referenceColumn);
|
||||
setColumns(queryColumnsValue.filter(item => item.showType !== 'more'));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
updateColummns(queryColumns);
|
||||
updateColumns(queryColumns);
|
||||
setDataSource(queryResults);
|
||||
setDefaultMetricField(chatContext?.metrics?.[0]);
|
||||
setActiveMetricField(chatContext?.metrics?.[0]);
|
||||
@@ -115,26 +115,45 @@ const ChatMsg: React.FC<Props> = ({
|
||||
metricFields.length > 0 &&
|
||||
categoryField.length <= 1 &&
|
||||
!(metricFields.length > 1 && categoryField.length > 0) &&
|
||||
!dataSource.every(item => item[dateField.bizName] === dataSource[0][dateField.bizName]);
|
||||
dataSource.some(item => item[dateField.bizName] !== dataSource[0][dateField.bizName]);
|
||||
|
||||
if (isMetricTrend) {
|
||||
return MsgContentTypeEnum.METRIC_TREND;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Pie Chart:
|
||||
* 1. There should be at least one category field.
|
||||
* 2. There should be exactly one metric field.
|
||||
* 3. All metric values should be non-negative.
|
||||
* 4. limit the number of data points based on device type:
|
||||
* - For mobile devices, limit to 5 data points.
|
||||
* - For desktop devices, limit to 10 data points.
|
||||
*/
|
||||
const isMetricPie =
|
||||
categoryField.length > 0 &&
|
||||
metricFields?.length === 1 &&
|
||||
(isMobile ? dataSource?.length <= 5 : dataSource?.length <= 10) &&
|
||||
dataSource.every(item => item[metricFields[0].bizName] > 0);
|
||||
dataSource.every(item => item[metricFields[0].bizName] >= 0);
|
||||
|
||||
if (isMetricPie) {
|
||||
return MsgContentTypeEnum.METRIC_PIE;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Bar Chart:
|
||||
* 1. There should be at least one category field.
|
||||
* 2. There should be exactly one metric field.
|
||||
* 3. The number of data points should be limited based on device type:
|
||||
* - For mobile devices, limit to 5 data points.
|
||||
* - For desktop devices, limit to 50 data points.
|
||||
* 4. All metric values should be finite numbers.
|
||||
*/
|
||||
const isMetricBar =
|
||||
categoryField?.length > 0 &&
|
||||
metricFields?.length === 1 &&
|
||||
(isMobile ? dataSource?.length <= 5 : dataSource?.length <= 50);
|
||||
(isMobile ? dataSource?.length <= 5 : dataSource?.length <= 50) &&
|
||||
dataSource.every(item => isFinite(Number(item[metricFields[0].bizName])));
|
||||
|
||||
if (isMetricBar) {
|
||||
return MsgContentTypeEnum.METRIC_BAR;
|
||||
@@ -226,9 +245,6 @@ const ChatMsg: React.FC<Props> = ({
|
||||
);
|
||||
case MsgContentTypeEnum.METRIC_PIE:
|
||||
const categoryField = columns.find(item => item.showType === 'CATEGORY');
|
||||
if (!categoryField) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Pie
|
||||
data={{ ...data, queryColumns: columns, queryResults: dataSource }}
|
||||
@@ -236,7 +252,7 @@ const ChatMsg: React.FC<Props> = ({
|
||||
triggerResize={triggerResize}
|
||||
loading={loading}
|
||||
metricField={metricFields[0]}
|
||||
categoryField={categoryField}
|
||||
categoryField={categoryField!}
|
||||
/>
|
||||
);
|
||||
case MsgContentTypeEnum.MARKDOWN:
|
||||
@@ -266,7 +282,7 @@ const ChatMsg: React.FC<Props> = ({
|
||||
});
|
||||
setLoading(false);
|
||||
if (res.code === 200) {
|
||||
updateColummns(res.data?.queryColumns || []);
|
||||
updateColumns(res.data?.queryColumns || []);
|
||||
setDataSource(res.data?.queryResults || []);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import moment, { Moment } from 'moment';
|
||||
import { NumericUnit } from '../common/constants';
|
||||
import { isString } from 'lodash';
|
||||
import { ColumnType } from '../common/type';
|
||||
|
||||
export function formatByDataFormatType(value: number | string, type: ColumnType['dataFormatType'], dataFormat: Partial<ColumnType['dataFormat']> = {}) {
|
||||
return `${formatByDecimalPlaces(dataFormat?.needMultiply100 ? +value * 100 : value, dataFormat?.decimalPlaces || 2)}${type === 'percent' ? '%' : ''}`;
|
||||
}
|
||||
|
||||
export function formatByDecimalPlaces(value: number | string, decimalPlaces: number) {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
|
||||
Reference in New Issue
Block a user