mirror of
https://github.com/didi/KnowStreaming.git
synced 2026-01-10 09:04:26 +08:00
fix: 图表展示 bugifx & 优化
This commit is contained in:
@@ -46,30 +46,42 @@ export const supplementaryPoints = (
|
|||||||
extraCallback?: (point: [number, 0]) => any[]
|
extraCallback?: (point: [number, 0]) => any[]
|
||||||
) => {
|
) => {
|
||||||
lines.forEach(({ data }) => {
|
lines.forEach(({ data }) => {
|
||||||
|
// 获取未补点前线条的点的个数
|
||||||
let len = data.length;
|
let len = data.length;
|
||||||
for (let i = 0; i < len; i++) {
|
// 记录当前处理到的点的下标值
|
||||||
const timestamp = data[i][0] as number;
|
let i = 0;
|
||||||
// 数组第一个点和最后一个点单独处理
|
|
||||||
|
for (; i < len; i++) {
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
let firstPointTimestamp = data[0][0] as number;
|
let firstPointTimestamp = data[0][0] as number;
|
||||||
while (firstPointTimestamp - interval > timeRange[0]) {
|
while (firstPointTimestamp - interval > timeRange[0]) {
|
||||||
const prePointTimestamp = firstPointTimestamp - interval;
|
const prevPointTimestamp = firstPointTimestamp - interval;
|
||||||
data.unshift(extraCallback ? extraCallback([prePointTimestamp, 0]) : [prePointTimestamp, 0]);
|
data.unshift(extraCallback ? extraCallback([prevPointTimestamp, 0]) : [prevPointTimestamp, 0]);
|
||||||
|
firstPointTimestamp = prevPointTimestamp;
|
||||||
len++;
|
len++;
|
||||||
i++;
|
i++;
|
||||||
firstPointTimestamp = prePointTimestamp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i === len - 1) {
|
if (i === len - 1) {
|
||||||
let lastPointTimestamp = data[len - 1][0] as number;
|
let lastPointTimestamp = data[i][0] as number;
|
||||||
while (lastPointTimestamp + interval < timeRange[1]) {
|
while (lastPointTimestamp + interval < timeRange[1]) {
|
||||||
const next = lastPointTimestamp + interval;
|
const nextPointTimestamp = lastPointTimestamp + interval;
|
||||||
data.push(extraCallback ? extraCallback([next, 0]) : [next, 0]);
|
data.push(extraCallback ? extraCallback([nextPointTimestamp, 0]) : [nextPointTimestamp, 0]);
|
||||||
lastPointTimestamp = next;
|
lastPointTimestamp = nextPointTimestamp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let timestamp = data[i][0] as number;
|
||||||
|
while (timestamp + interval < data[i + 1][0]) {
|
||||||
|
const nextPointTimestamp = timestamp + interval;
|
||||||
|
data.splice(i + 1, 0, extraCallback ? extraCallback([nextPointTimestamp, 0]) : [nextPointTimestamp, 0]);
|
||||||
|
timestamp = nextPointTimestamp;
|
||||||
|
len++;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
} else if (timestamp + interval < data[i + 1][0]) {
|
|
||||||
data.splice(i + 1, 0, extraCallback ? extraCallback([timestamp + interval, 0]) : [timestamp + interval, 0]);
|
|
||||||
len++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -135,18 +147,37 @@ export const formatChartData = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const seriesCallback = (lines: { name: string; data: [number, string | number][] }[]) => {
|
const seriesCallback = (lines: { name: string; data: [number, string | number][] }[]) => {
|
||||||
|
const len = CHART_COLOR_LIST.length;
|
||||||
// series 配置
|
// series 配置
|
||||||
return lines.map((line) => {
|
return lines.map((line, i) => {
|
||||||
return {
|
return {
|
||||||
...line,
|
...line,
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
width: 1.5,
|
width: 1.5,
|
||||||
},
|
},
|
||||||
|
connectNulls: false,
|
||||||
symbol: 'emptyCircle',
|
symbol: 'emptyCircle',
|
||||||
symbolSize: 4,
|
symbolSize: 4,
|
||||||
smooth: 0.25,
|
smooth: 0.25,
|
||||||
areaStyle: {
|
areaStyle: {
|
||||||
opacity: 0.02,
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: CHART_COLOR_LIST[i % len] + '10',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(255,255,255,0)', // 100% 处的颜色
|
||||||
|
},
|
||||||
|
],
|
||||||
|
global: false, // 缺省为 false
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -189,6 +220,7 @@ export const getDetailChartConfig = (title: string, sliderPos: readonly [number,
|
|||||||
startValue: sliderPos[0],
|
startValue: sliderPos[0],
|
||||||
endValue: sliderPos[1],
|
endValue: sliderPos[1],
|
||||||
zoomOnMouseWheel: false,
|
zoomOnMouseWheel: false,
|
||||||
|
minValueSpan: 10 * 60 * 1000,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: 0,
|
start: 0,
|
||||||
|
|||||||
@@ -63,56 +63,63 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.overview-chart-detail-drawer {
|
||||||
.chart-detail-modal-container {
|
.dcloud-spin-nested-loading > div > .dcloud-spin.dcloud-spin-spinning {
|
||||||
position: relative;
|
height: 300px;
|
||||||
.expand-icon-box {
|
}
|
||||||
position: absolute;
|
&.dcloud-drawer .dcloud-drawer-body {
|
||||||
z-index: 1000;
|
padding: 0 20px;
|
||||||
top: 14px;
|
}
|
||||||
right: 44px;
|
.detail-header {
|
||||||
width: 24px;
|
display: flex;
|
||||||
height: 24px;
|
align-items: flex-end;
|
||||||
cursor: pointer;
|
font-weight: normal;
|
||||||
font-size: 16px;
|
.title {
|
||||||
text-align: center;
|
font-family: @font-family-bold;
|
||||||
border-radius: 50%;
|
font-size: 18px;
|
||||||
transition: background-color 0.3s ease;
|
color: #495057;
|
||||||
.expand-icon {
|
letter-spacing: 0;
|
||||||
color: #adb5bc;
|
.unit {
|
||||||
line-height: 24px;
|
font-family: @font-family-bold;
|
||||||
}
|
font-size: 14px;
|
||||||
&:hover {
|
letter-spacing: 0.5px;
|
||||||
background: rgba(33, 37, 41, 0.04);
|
|
||||||
.expand-icon {
|
|
||||||
color: #74788d;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.slider-info {
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: @font-family;
|
||||||
|
color: #303a51;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.detail-title {
|
.chart-detail-modal-container {
|
||||||
display: flex;
|
position: relative;
|
||||||
justify-content: space-between;
|
overflow: hidden;
|
||||||
align-items: center;
|
.expand-icon-box {
|
||||||
.left {
|
position: absolute;
|
||||||
display: flex;
|
z-index: 1000;
|
||||||
align-items: flex-end;
|
top: 14px;
|
||||||
.title {
|
right: 44px;
|
||||||
font-family: @font-family-bold;
|
width: 24px;
|
||||||
font-size: 18px;
|
height: 24px;
|
||||||
color: #495057;
|
cursor: pointer;
|
||||||
letter-spacing: 0;
|
font-size: 16px;
|
||||||
.unit {
|
text-align: center;
|
||||||
font-family: @font-family-bold;
|
border-radius: 50%;
|
||||||
font-size: 14px;
|
transition: background-color 0.3s ease;
|
||||||
letter-spacing: 0.5px;
|
.expand-icon {
|
||||||
|
color: #adb5bc;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background: rgba(33, 37, 41, 0.04);
|
||||||
|
.expand-icon {
|
||||||
|
color: #74788d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.info {
|
}
|
||||||
margin-left: 10px;
|
.detail-table {
|
||||||
}
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.detail-table {
|
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,8 +216,8 @@ const DashboardDragChart = (props: PropsType): JSX.Element => {
|
|||||||
onChange={ksHeaderChange}
|
onChange={ksHeaderChange}
|
||||||
nodeScopeModule={{
|
nodeScopeModule={{
|
||||||
customScopeList: scopeList,
|
customScopeList: scopeList,
|
||||||
scopeName: `自定义 ${dashboardType === MetricType.Broker ? 'Broker' : 'Topic'} 范围`,
|
scopeName: dashboardType === MetricType.Broker ? 'Broker' : 'Topic',
|
||||||
showSearch: dashboardType === MetricType.Topic,
|
scopeLabel: `自定义 ${dashboardType === MetricType.Broker ? 'Broker' : 'Topic'} 范围`,
|
||||||
}}
|
}}
|
||||||
indicatorSelectModule={{
|
indicatorSelectModule={{
|
||||||
hide: false,
|
hide: false,
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ const OptionsDefault = [
|
|||||||
const NodeScope = ({ nodeScopeModule, change }: propsType) => {
|
const NodeScope = ({ nodeScopeModule, change }: propsType) => {
|
||||||
const {
|
const {
|
||||||
customScopeList: customList,
|
customScopeList: customList,
|
||||||
scopeName = '自定义节点范围',
|
scopeName = '',
|
||||||
showSearch = false,
|
scopeLabel = '自定义范围',
|
||||||
searchPlaceholder = '输入内容进行搜索',
|
searchPlaceholder = '输入内容进行搜索',
|
||||||
} = nodeScopeModule;
|
} = nodeScopeModule;
|
||||||
const [topNum, setTopNum] = useState<number>(5);
|
const [topNum, setTopNum] = useState<number>(5);
|
||||||
@@ -70,7 +70,7 @@ const NodeScope = ({ nodeScopeModule, change }: propsType) => {
|
|||||||
change(checkedListTemp, false);
|
change(checkedListTemp, false);
|
||||||
setIsTop(false);
|
setIsTop(false);
|
||||||
setTopNum(null);
|
setTopNum(null);
|
||||||
setInputValue(`已选${checkedListTemp?.length}项`);
|
setInputValue(`${checkedListTemp?.length}项`);
|
||||||
setPopVisible(false);
|
setPopVisible(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -109,7 +109,7 @@ const NodeScope = ({ nodeScopeModule, change }: propsType) => {
|
|||||||
{/* <span>时间:</span> */}
|
{/* <span>时间:</span> */}
|
||||||
<div className="flx_con">
|
<div className="flx_con">
|
||||||
<div className="flx_l">
|
<div className="flx_l">
|
||||||
<h6 className="time_title">选择top范围</h6>
|
<h6 className="time_title">选择 top 范围</h6>
|
||||||
<Radio.Group
|
<Radio.Group
|
||||||
optionType="button"
|
optionType="button"
|
||||||
buttonStyle="solid"
|
buttonStyle="solid"
|
||||||
@@ -128,7 +128,7 @@ const NodeScope = ({ nodeScopeModule, change }: propsType) => {
|
|||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</div>
|
</div>
|
||||||
<div className="flx_r">
|
<div className="flx_r">
|
||||||
<h6 className="time_title">{scopeName}</h6>
|
<h6 className="time_title">{scopeLabel}</h6>
|
||||||
<div className="custom-scope">
|
<div className="custom-scope">
|
||||||
<div className="check-row">
|
<div className="check-row">
|
||||||
<Checkbox className="check-all" indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}>
|
<Checkbox className="check-all" indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}>
|
||||||
@@ -136,9 +136,7 @@ const NodeScope = ({ nodeScopeModule, change }: propsType) => {
|
|||||||
</Checkbox>
|
</Checkbox>
|
||||||
<Input
|
<Input
|
||||||
className="search-input"
|
className="search-input"
|
||||||
suffix={
|
suffix={<IconFont type="icon-fangdajing" style={{ fontSize: '16px' }} />}
|
||||||
<IconFont type="icon-fangdajing" style={{ fontSize: '16px' }} />
|
|
||||||
}
|
|
||||||
size="small"
|
size="small"
|
||||||
placeholder={searchPlaceholder}
|
placeholder={searchPlaceholder}
|
||||||
onChange={(e) => setScopeSearchValue(e.target.value)}
|
onChange={(e) => setScopeSearchValue(e.target.value)}
|
||||||
@@ -148,7 +146,7 @@ const NodeScope = ({ nodeScopeModule, change }: propsType) => {
|
|||||||
<Checkbox.Group style={{ width: '100%' }} onChange={checkChange} value={checkedListTemp}>
|
<Checkbox.Group style={{ width: '100%' }} onChange={checkChange} value={checkedListTemp}>
|
||||||
<Row gutter={[10, 12]}>
|
<Row gutter={[10, 12]}>
|
||||||
{customList
|
{customList
|
||||||
.filter((item) => !showSearch || item.label.includes(scopeSearchValue))
|
.filter((item) => item.label.includes(scopeSearchValue))
|
||||||
.map((item) => (
|
.map((item) => (
|
||||||
<Col span={12} key={item.value}>
|
<Col span={12} key={item.value}>
|
||||||
<Checkbox value={item.value}>{item.label}</Checkbox>
|
<Checkbox value={item.value}>{item.label}</Checkbox>
|
||||||
@@ -180,6 +178,7 @@ const NodeScope = ({ nodeScopeModule, change }: propsType) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div id="d-node-scope">
|
<div id="d-node-scope">
|
||||||
|
<div className="scope-title">{scopeName}筛选:</div>
|
||||||
<Popover
|
<Popover
|
||||||
trigger={['click']}
|
trigger={['click']}
|
||||||
visible={popVisible}
|
visible={popVisible}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Tooltip, Select, IconFont, Utils, Divider } from 'knowdesign';
|
import { Tooltip, Select, IconFont, Utils, Divider, Button } from 'knowdesign';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { DRangeTime } from 'knowdesign';
|
import { DRangeTime } from 'knowdesign';
|
||||||
import IndicatorDrawer from './IndicatorDrawer';
|
import IndicatorDrawer from './IndicatorDrawer';
|
||||||
@@ -48,7 +48,7 @@ export interface IcustomScope {
|
|||||||
export interface InodeScopeModule {
|
export interface InodeScopeModule {
|
||||||
customScopeList: IcustomScope[];
|
customScopeList: IcustomScope[];
|
||||||
scopeName?: string;
|
scopeName?: string;
|
||||||
showSearch?: boolean;
|
scopeLabel?: string;
|
||||||
searchPlaceholder?: string;
|
searchPlaceholder?: string;
|
||||||
change?: () => void;
|
change?: () => void;
|
||||||
}
|
}
|
||||||
@@ -138,9 +138,13 @@ const SingleChartHeader = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const reloadRangeTime = () => {
|
const reloadRangeTime = () => {
|
||||||
const timeLen = rangeTime[1] - rangeTime[0] || 0;
|
if (isRelativeRangeTime) {
|
||||||
const curTimeStamp = moment().valueOf();
|
const timeLen = rangeTime[1] - rangeTime[0] || 0;
|
||||||
setRangeTime([curTimeStamp - timeLen, curTimeStamp]);
|
const curTimeStamp = moment().valueOf();
|
||||||
|
setRangeTime([curTimeStamp - timeLen, curTimeStamp]);
|
||||||
|
} else {
|
||||||
|
setRangeTime([...rangeTime]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const openIndicatorDrawer = () => {
|
const openIndicatorDrawer = () => {
|
||||||
@@ -174,12 +178,10 @@ const SingleChartHeader = ({
|
|||||||
{!hideGridSelect && (
|
{!hideGridSelect && (
|
||||||
<Select className="grid-select" style={{ width: 70 }} value={gridNum} options={GRID_SIZE_OPTIONS} onChange={sizeChange} />
|
<Select className="grid-select" style={{ width: 70 }} value={gridNum} options={GRID_SIZE_OPTIONS} onChange={sizeChange} />
|
||||||
)}
|
)}
|
||||||
<Divider type="vertical" style={{ height: 20, top: 0 }} />
|
{(!hideNodeScope || !hideGridSelect) && <Divider type="vertical" style={{ height: 20, top: 0 }} />}
|
||||||
<Tooltip title="点击指标筛选,可选择指标" placement="bottomRight">
|
<Button type="primary" onClick={openIndicatorDrawer}>
|
||||||
<div className="icon-box" onClick={openIndicatorDrawer}>
|
指标筛选
|
||||||
<IconFont className="icon" type="icon-shezhi1" />
|
</Button>
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,8 +3,13 @@
|
|||||||
@import '~knowdesign/es/basic/style/mixins/index';
|
@import '~knowdesign/es/basic/style/mixins/index';
|
||||||
|
|
||||||
#d-node-scope {
|
#d-node-scope {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
.scope-title {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #74788d;
|
||||||
|
}
|
||||||
.input-span {
|
.input-span {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@@ -29,10 +34,10 @@
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
&.relativeTime {
|
&.relativeTime {
|
||||||
width: 160px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
&.absoluteTime {
|
&.absoluteTime {
|
||||||
width: 300px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
|||||||
@@ -1,29 +1,19 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
export const CHART_COLOR_LIST = [
|
export const CHART_COLOR_LIST = [
|
||||||
'#657DFC',
|
'#556ee6',
|
||||||
'#A7B1EB',
|
|
||||||
'#2AC8E4',
|
|
||||||
'#9DDEEB',
|
|
||||||
'#3991FF',
|
|
||||||
'#94BEF2',
|
'#94BEF2',
|
||||||
|
'#95e7ff',
|
||||||
|
'#9DDEEB',
|
||||||
|
'#A7B1EB',
|
||||||
'#C2D0E3',
|
'#C2D0E3',
|
||||||
'#F5B6B3',
|
|
||||||
'#85C80D',
|
|
||||||
'#C9E795',
|
|
||||||
'#A76CEC',
|
|
||||||
'#CCABF1',
|
'#CCABF1',
|
||||||
'#FF9C1B',
|
|
||||||
'#F5C993',
|
|
||||||
'#FFC300',
|
|
||||||
'#F9D77B',
|
'#F9D77B',
|
||||||
'#12CA7A',
|
'#F5C993',
|
||||||
'#8BA3C4',
|
|
||||||
'#FF7066',
|
|
||||||
'#A7E6C7',
|
'#A7E6C7',
|
||||||
'#F19FC9',
|
'#F19FC9',
|
||||||
'#AEAEAE',
|
'#F5B6B3',
|
||||||
'#D1D1D1',
|
'#C9E795',
|
||||||
];
|
];
|
||||||
|
|
||||||
export const UNIT_MAP = {
|
export const UNIT_MAP = {
|
||||||
|
|||||||
@@ -38,15 +38,17 @@
|
|||||||
|
|
||||||
&-main {
|
&-main {
|
||||||
.header-chart-container {
|
.header-chart-container {
|
||||||
&-loading {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 244px;
|
height: 244px;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
.cluster-container-border();
|
.cluster-container-border();
|
||||||
|
.dcloud-spin.dcloud-spin-spinning {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 244px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { MetricType } from '@src/api';
|
|||||||
import { getDataNumberUnit, getUnit } from '@src/constants/chartConfig';
|
import { getDataNumberUnit, getUnit } from '@src/constants/chartConfig';
|
||||||
import SingleChartHeader, { KsHeaderOptions } from '@src/components/SingleChartHeader';
|
import SingleChartHeader, { KsHeaderOptions } from '@src/components/SingleChartHeader';
|
||||||
import { MAX_TIME_RANGE_WITH_SMALL_POINT_INTERVAL } from '@src/constants/common';
|
import { MAX_TIME_RANGE_WITH_SMALL_POINT_INTERVAL } from '@src/constants/common';
|
||||||
|
import RenderEmpty from '@src/components/RenderEmpty';
|
||||||
|
|
||||||
type ChartFilterOptions = Omit<KsHeaderOptions, 'gridNum'>;
|
type ChartFilterOptions = Omit<KsHeaderOptions, 'gridNum'>;
|
||||||
interface MetricInfo {
|
interface MetricInfo {
|
||||||
@@ -64,7 +65,7 @@ const DetailChart = (props: { children: JSX.Element }): JSX.Element => {
|
|||||||
const [messagesInMetricData, setMessagesInMetricData] = useState<MessagesInMetric>({
|
const [messagesInMetricData, setMessagesInMetricData] = useState<MessagesInMetric>({
|
||||||
name: 'MessagesIn',
|
name: 'MessagesIn',
|
||||||
unit: '',
|
unit: '',
|
||||||
data: [],
|
data: undefined,
|
||||||
});
|
});
|
||||||
const [curHeaderOptions, setCurHeaderOptions] = useState<ChartFilterOptions>();
|
const [curHeaderOptions, setCurHeaderOptions] = useState<ChartFilterOptions>();
|
||||||
const [defaultChartLoading, setDefaultChartLoading] = useState<boolean>(true);
|
const [defaultChartLoading, setDefaultChartLoading] = useState<boolean>(true);
|
||||||
@@ -234,17 +235,19 @@ const DetailChart = (props: { children: JSX.Element }): JSX.Element => {
|
|||||||
result.forEach((point) => ((point[1] as number) /= unitSize));
|
result.forEach((point) => ((point[1] as number) /= unitSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 补充缺少的图表点
|
if (result.length) {
|
||||||
const extraMetrics = result[0][2].map((info) => ({
|
// 补充缺少的图表点
|
||||||
...info,
|
const extraMetrics = result[0][2].map((info) => ({
|
||||||
value: 0,
|
...info,
|
||||||
}));
|
value: 0,
|
||||||
const supplementaryInterval =
|
}));
|
||||||
(curHeaderOptions.rangeTime[1] - curHeaderOptions.rangeTime[0] > MAX_TIME_RANGE_WITH_SMALL_POINT_INTERVAL ? 10 : 1) * 60 * 1000;
|
const supplementaryInterval =
|
||||||
supplementaryPoints([line], curHeaderOptions.rangeTime, supplementaryInterval, (point) => {
|
(curHeaderOptions.rangeTime[1] - curHeaderOptions.rangeTime[0] > MAX_TIME_RANGE_WITH_SMALL_POINT_INTERVAL ? 10 : 1) * 60 * 1000;
|
||||||
point.push(extraMetrics as any);
|
supplementaryPoints([line], curHeaderOptions.rangeTime, supplementaryInterval, (point) => {
|
||||||
return point;
|
point.push(extraMetrics as any);
|
||||||
});
|
return point;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setMessagesInMetricData(line);
|
setMessagesInMetricData(line);
|
||||||
setDefaultChartLoading(false);
|
setDefaultChartLoading(false);
|
||||||
@@ -299,10 +302,9 @@ const DetailChart = (props: { children: JSX.Element }): JSX.Element => {
|
|||||||
|
|
||||||
<div className="cluster-detail-container-main">
|
<div className="cluster-detail-container-main">
|
||||||
{/* MessageIn 图表 */}
|
{/* MessageIn 图表 */}
|
||||||
<div className={`header-chart-container ${!messagesInMetricData.data.length ? 'header-chart-container-loading' : ''}`}>
|
<div className="header-chart-container">
|
||||||
<Spin spinning={defaultChartLoading}>
|
<Spin spinning={defaultChartLoading}>
|
||||||
{/* TODO: 暂时通过判断是否有图表数据来修复,有时间可以查找下宽度溢出的原因 */}
|
{messagesInMetricData.data && (
|
||||||
{messagesInMetricData.data.length ? (
|
|
||||||
<>
|
<>
|
||||||
<div className="chart-box-title">
|
<div className="chart-box-title">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@@ -322,26 +324,27 @@ const DetailChart = (props: { children: JSX.Element }): JSX.Element => {
|
|||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<SingleChart
|
{messagesInMetricData.data.length ? (
|
||||||
chartKey="messagesIn"
|
<SingleChart
|
||||||
chartTypeProp="line"
|
chartKey="messagesIn"
|
||||||
showHeader={false}
|
chartTypeProp="line"
|
||||||
wrapStyle={{
|
showHeader={false}
|
||||||
width: 'auto',
|
wrapStyle={{
|
||||||
height: 210,
|
width: 'auto',
|
||||||
}}
|
height: 210,
|
||||||
connectEventName="clusterChart"
|
}}
|
||||||
eventBus={busInstance}
|
connectEventName="clusterChart"
|
||||||
propChartData={[messagesInMetricData]}
|
eventBus={busInstance}
|
||||||
{...getChartConfig({
|
propChartData={[messagesInMetricData]}
|
||||||
// metricName: `${messagesInMetricData.name}{unit|(${messagesInMetricData.unit})}`,
|
{...getChartConfig({
|
||||||
lineColor: CHART_LINE_COLORS[0],
|
lineColor: CHART_LINE_COLORS[0],
|
||||||
isDefaultMetric: true,
|
isDefaultMetric: true,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
!defaultChartLoading && <RenderEmpty message="暂无数据" height={200} />
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
|
||||||
''
|
|
||||||
)}
|
)}
|
||||||
</Spin>
|
</Spin>
|
||||||
</div>
|
</div>
|
||||||
@@ -408,7 +411,7 @@ const DetailChart = (props: { children: JSX.Element }): JSX.Element => {
|
|||||||
) : chartLoading ? (
|
) : chartLoading ? (
|
||||||
<></>
|
<></>
|
||||||
) : (
|
) : (
|
||||||
<Empty description="请先选择指标或刷新" style={{ width: '100%', height: '100%' }} />
|
<RenderEmpty message="请先选择指标或刷新" />
|
||||||
)}
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
</Spin>
|
</Spin>
|
||||||
|
|||||||
Reference in New Issue
Block a user