Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DiDi
nightingale
提交
0769b025
N
nightingale
项目概览
DiDi
/
nightingale
12 个月 前同步成功
通知
46
Star
7053
Fork
1161
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
N
nightingale
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0769b025
编写于
4月 14, 2020
作者:
J
jsers
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: Charts support time comparisons
上级
500afafd
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
335 addition
and
30 deletion
+335
-30
web/src/components/Graph/Graph/Legend.tsx
web/src/components/Graph/Graph/Legend.tsx
+18
-6
web/src/components/Graph/Graph/index.tsx
web/src/components/Graph/Graph/index.tsx
+6
-0
web/src/components/Graph/GraphConfig/Comparison.tsx
web/src/components/Graph/GraphConfig/Comparison.tsx
+206
-0
web/src/components/Graph/GraphConfig/GraphConfigForm.tsx
web/src/components/Graph/GraphConfig/GraphConfigForm.tsx
+37
-0
web/src/components/Graph/GraphConfig/GraphConfigInner.tsx
web/src/components/Graph/GraphConfig/GraphConfigInner.tsx
+31
-16
web/src/components/Graph/config.tsx
web/src/components/Graph/config.tsx
+7
-1
web/src/components/Graph/util/getTooltipsContent.tsx
web/src/components/Graph/util/getTooltipsContent.tsx
+23
-5
web/src/components/Graph/util/normalizeEndpointCounters.tsx
web/src/components/Graph/util/normalizeEndpointCounters.tsx
+3
-1
web/src/components/Graph/util/normalizeSeries.tsx
web/src/components/Graph/util/normalizeSeries.tsx
+2
-1
web/src/locales/en.ts
web/src/locales/en.ts
+1
-0
web/src/locales/zh.ts
web/src/locales/zh.ts
+1
-0
未找到文件。
web/src/components/Graph/Graph/Legend.tsx
浏览文件 @
0769b025
...
...
@@ -3,6 +3,7 @@ import { Table, Input, Button, Modal } from 'antd';
import
{
ColumnProps
,
TableRowSelection
}
from
'
antd/es/table
'
;
import
Color
from
'
color
'
;
import
_
from
'
lodash
'
;
import
{
injectIntl
}
from
'
react-intl
'
;
import
clipboard
from
'
@common/clipboard
'
;
import
ContextMenu
from
'
@cpts/ContextMenu
'
;
import
{
SerieInterface
,
PointInterface
}
from
'
../interface
'
;
...
...
@@ -35,7 +36,7 @@ interface LegendDataItem extends SerieInterface {
last
:
number
|
null
,
}
export
default
class
Legend
extends
Component
<
Props
,
State
>
{
class
Legend
extends
Component
<
Props
,
State
>
{
static
defaultProps
=
{
style
:
{},
series
:
[],
...
...
@@ -125,7 +126,7 @@ export default class Legend extends Component<Props, State> {
}
render
()
{
const
{
onSelectedChange
}
=
this
.
props
;
const
{
comparisonOptions
,
onSelectedChange
}
=
this
.
props
;
const
{
searchText
,
selectedKeys
,
highlightedKeys
}
=
this
.
state
;
const
counterSelectedKeys
=
highlightedKeys
;
const
data
=
this
.
filterData
();
...
...
@@ -148,7 +149,7 @@ export default class Legend extends Component<Props, State> {
filterDropdownVisible
:
this
.
state
.
filterDropdownVisible
,
onFilterDropdownVisibleChange
:
(
visible
:
boolean
)
=>
this
.
setState
({
filterDropdownVisible
:
visible
}),
render
:
(
text
,
record
)
=>
{
const
legendName
=
getLengendName
(
record
);
const
legendName
=
getLengendName
(
record
,
comparisonOptions
,
this
.
props
.
intl
);
return
(
<
span
title
=
{
text
}
...
...
@@ -258,12 +259,13 @@ export default class Legend extends Component<Props, State> {
export
function
normalizeLegendData
(
series
:
SerieInterface
[]
=
[])
{
const
tableData
=
_
.
map
(
series
,
(
serie
)
=>
{
const
{
id
,
metric
,
tags
,
data
}
=
serie
;
const
{
id
,
metric
,
tags
,
data
,
comparison
}
=
serie
;
const
{
last
,
avg
,
max
,
min
,
sum
}
=
getLegendNums
(
data
);
return
{
id
,
metric
,
tags
,
comparison
,
last
,
avg
,
max
,
...
...
@@ -348,9 +350,17 @@ function getLegendNums(points: PointInterface[]) {
return
{
last
,
avg
,
max
,
min
,
sum
};
}
function
getLengendName
(
serie
:
SerieInterface
)
{
const
{
tags
}
=
serie
;
function
getLengendName
(
serie
:
SerieInterface
,
comparisonOptions
:
any
,
intl
:
any
)
{
const
{
tags
,
comparison
}
=
serie
;
let
lname
=
tags
;
// display comparison
if
(
comparison
&&
typeof
comparison
===
'
number
'
)
{
const
currentComparison
=
_
.
find
(
comparisonOptions
,
{
value
:
`
${
comparison
}
000`
});
if
(
currentComparison
&&
currentComparison
.
label
)
{
const
postfix
=
intl
.
locale
===
'
en
'
?
currentComparison
.
labelEn
:
`环比
${
currentComparison
.
label
}
`
;
lname
+=
`
${
postfix
}
`
;
}
}
// shorten name
if
(
lname
.
length
>
80
)
{
const
leftStr
=
lname
.
substr
(
0
,
40
);
...
...
@@ -369,3 +379,5 @@ function isEqualSeries(series: SerieInterface[], nextSeries: SerieInterface[]) {
});
return
_
.
isEqual
(
pureSeries
,
pureNextSeries
);
}
export
default
injectIntl
(
Legend
);
web/src/components/Graph/Graph/index.tsx
浏览文件 @
0769b025
...
...
@@ -93,6 +93,7 @@ export default class Graph extends Component<Props, State> {
||
aggrFuncChanged
||
aggrGroupChanged
||
consolFuncChanged
||
!
_
.
isEqual
(
nextData
.
comparison
,
thisData
.
comparison
)
)
{
const
isFetchCounter
=
selectedNsChanged
||
selectedMetricChanged
||
selectedTagkvChanged
;
this
.
fetchData
(
nextProps
.
data
,
isFetchCounter
,
(
series
:
SerieInterface
[])
=>
{
...
...
@@ -256,6 +257,8 @@ export default class Graph extends Component<Props, State> {
return
util
.
getTooltipsContent
({
points
,
chartWidth
:
this
.
graphWrapEle
.
offsetWidth
-
40
,
comparison
:
graphConfig
.
comparison
,
isComparison
:
!!
_
.
get
(
graphConfig
.
comparison
,
'
length
'
),
});
},
},
...
...
@@ -292,6 +295,8 @@ export default class Graph extends Component<Props, State> {
return
util
.
getTooltipsContent
({
points
,
chartWidth
:
this
.
graphWrapEle
.
offsetWidth
-
40
,
comparison
:
graphConfig
.
comparison
,
isComparison
:
!!
_
.
get
(
graphConfig
.
comparison
,
'
length
'
),
});
},
},
...
...
@@ -391,6 +396,7 @@ export default class Graph extends Component<Props, State> {
style
=
{
{
display
:
graphConfig
.
legend
?
'
block
'
:
'
none
'
}
}
series
=
{
this
.
getZoomedSeries
()
}
onSelectedChange
=
{
this
.
handleLegendRowSelectedChange
}
comparisonOptions
=
{
graphConfig
.
comparisonOptions
}
/>
</
div
>
);
...
...
web/src/components/Graph/GraphConfig/Comparison.tsx
0 → 100644
浏览文件 @
0769b025
import
React
,
{
Component
}
from
'
react
'
;
import
_
from
'
lodash
'
;
import
moment
from
'
moment
'
;
import
{
Icon
,
Button
,
Select
,
Popover
,
Input
,
InputNumber
}
from
'
antd
'
;
import
{
CheckboxChangeEvent
}
from
'
antd/lib/checkbox
'
;
import
{
injectIntl
}
from
'
react-intl
'
;
interface
Props
{
size
:
'
small
'
|
'
default
'
|
'
large
'
|
undefined
,
comparison
:
string
[],
relativeTimeComparison
:
boolean
,
comparisonOptions
:
any
[],
graphConfig
:
any
,
onChange
:
(
values
:
any
)
=>
void
,
}
interface
State
{
customValue
?:
number
,
customType
:
string
,
errorText
:
string
,
}
const
Option
=
Select
.
Option
;
const
customTypeOptions
=
[
{
value
:
'
hour
'
,
label
:
'
小时
'
,
labelEn
:
'
hour
'
,
ms
:
3600000
,
},
{
value
:
'
day
'
,
label
:
'
天
'
,
labelEn
:
'
day
'
,
ms
:
86400000
,
},
];
class
Comparison
extends
Component
<
Props
,
State
>
{
static
defaultProps
=
{
size
:
'
small
'
,
comparison
:
[],
relativeTimeComparison
:
false
,
comparisonOptions
:
[],
graphConfig
:
null
,
onChange
:
_
.
noop
,
};
constructor
(
props
:
Props
)
{
super
(
props
);
this
.
state
=
{
customValue
:
undefined
,
// 自定义环比值(不带单位)
customType
:
'
hour
'
,
// 自定义环比值单位 hour | day
errorText
:
''
,
// 错误提示文本
};
}
refresh
=
()
=>
{
const
{
graphConfig
}
=
this
.
props
;
if
(
graphConfig
)
{
const
now
=
moment
();
const
start
=
(
Number
(
now
.
format
(
'
x
'
))
-
Number
(
graphConfig
.
end
))
+
Number
(
graphConfig
.
start
)
+
''
;
const
end
=
now
.
format
(
'
x
'
);
return
{
now
:
end
,
start
,
end
};
}
return
{};
}
handleComparisonChange
=
(
value
:
string
[])
=>
{
const
{
onChange
,
relativeTimeComparison
,
comparisonOptions
}
=
this
.
props
;
onChange
({
...
this
.
refresh
(),
comparison
:
value
,
relativeTimeComparison
,
comparisonOptions
,
});
}
handleRelativeTimeComparisonChange
=
(
e
:
CheckboxChangeEvent
)
=>
{
const
{
onChange
,
comparison
,
comparisonOptions
}
=
this
.
props
;
onChange
({
...
this
.
refresh
(),
comparison
,
relativeTimeComparison
:
e
.
target
.
checked
,
comparisonOptions
,
});
}
handleCustomValueChange
=
(
value
:
number
|
undefined
)
=>
{
if
(
value
)
{
this
.
setState
({
customValue
:
value
,
errorText
:
''
,
});
}
else
{
this
.
setState
({
customValue
:
value
,
errorText
:
'
Custom value is required
'
,
});
}
}
handleCustomTypeChange
=
(
value
:
string
)
=>
{
this
.
setState
({
customType
:
value
});
}
handleCustomBtnClick
=
()
=>
{
const
{
onChange
,
comparison
,
relativeTimeComparison
,
comparisonOptions
}
=
this
.
props
;
const
{
customValue
,
customType
}
=
this
.
state
;
const
currentCustomTypeObj
=
_
.
find
(
customTypeOptions
,
{
value
:
customType
});
if
(
!
customValue
||
!
currentCustomTypeObj
)
{
this
.
setState
({
errorText
:
'
Custom value is required
'
,
});
}
else
{
this
.
setState
({
errorText
:
''
,
},
()
=>
{
const
ms
=
currentCustomTypeObj
.
ms
*
customValue
;
const
comparisonOptionsClone
=
_
.
cloneDeep
(
comparisonOptions
);
const
comparisonClone
=
_
.
cloneDeep
(
comparison
);
comparisonClone
.
push
(
_
.
toString
(
ms
));
comparisonOptionsClone
.
push
({
label
:
`
${
customValue
}${
currentCustomTypeObj
.
label
}
`
,
value
:
_
.
toString
(
ms
),
});
const
newComparisonOptions
=
_
.
unionBy
(
comparisonOptionsClone
,
'
value
'
);
onChange
({
...
this
.
refresh
(),
comparison
:
comparisonClone
,
relativeTimeComparison
,
comparisonOptions
:
newComparisonOptions
,
});
});
}
}
render
()
{
const
{
size
,
comparison
,
comparisonOptions
}
=
this
.
props
;
const
{
customValue
,
customType
,
errorText
}
=
this
.
state
;
console
.
log
(
this
.
props
.
intl
.
locale
);
const
addonUid
=
_
.
uniqueId
(
'
inputNumber-addon-
'
);
return
(
<
div
className
=
"graph-config-inner-comparison"
>
<
Select
mode
=
"multiple"
dropdownMatchSelectWidth
=
{
false
}
size
=
{
size
}
style
=
{
{
minWidth
:
80
,
width
:
'
auto
'
,
verticalAlign
:
'
middle
'
}
}
value
=
{
comparison
}
onChange
=
{
this
.
handleComparisonChange
}
>
{
_
.
map
(
comparisonOptions
,
o
=>
{
return
(
<
Option
key
=
{
o
.
value
}
value
=
{
o
.
value
}
>
{
this
.
props
.
intl
.
locale
===
'
en
'
?
o
.
labelEn
:
o
.
label
}
</
Option
>
);
})
}
</
Select
>
<
Popover
placement
=
"bottom"
title
=
"Enter a custom value"
trigger
=
"click"
content
=
{
<
div
>
<
div
style
=
{
{
display
:
'
inline-block
'
,
width
:
160
,
marginRight
:
10
,
verticalAlign
:
'
top
'
}
}
>
<
Input
.
Group
className
=
"ant-select-wrapper"
size
=
"default"
>
<
InputNumber
value
=
{
customValue
}
onChange
=
{
this
.
handleCustomValueChange
}
/>
<
span
className
=
"ant-input-group-addon"
id
=
{
addonUid
}
>
<
Select
style
=
{
{
width
:
70
}
}
getPopupContainer
=
{
()
=>
document
.
getElementById
(
addonUid
)
as
HTMLElement
}
value
=
{
customType
}
onChange
=
{
this
.
handleCustomTypeChange
}
>
{
_
.
map
(
customTypeOptions
,
item
=>
(
<
Option
key
=
{
item
.
value
}
>
{
this
.
props
.
intl
.
locale
===
'
en
'
?
item
.
labelEn
:
item
.
label
}
</
Option
>
))
}
</
Select
>
</
span
>
</
Input
.
Group
>
</
div
>
<
Button
onClick
=
{
this
.
handleCustomBtnClick
}
>
{
this
.
props
.
intl
.
locale
===
'
en
'
?
'
ok
'
:
'
确认
'
}
</
Button
>
<
p
style
=
{
{
color
:
'
#f50
'
}
}
>
{
errorText
}
</
p
>
</
div
>
}
>
<
span
className
=
"ant-input-group-addon select-addon"
style
=
{
{
padding
:
size
===
'
default
'
?
7
:
5
,
left
:
size
===
'
default
'
?
-
5
:
-
3
,
height
:
size
===
'
default
'
?
32
:
24
,
lineHeight
:
size
===
'
default
'
?
'
18px
'
:
'
10px
'
,
}
}
>
<
Icon
type
=
"plus-circle-o"
/>
</
span
>
</
Popover
>
</
div
>
);
}
}
export
default
injectIntl
(
Comparison
);
web/src/components/Graph/GraphConfig/GraphConfigForm.tsx
浏览文件 @
0769b025
...
...
@@ -9,6 +9,7 @@ import { normalizeTreeData, renderTreeNodes } from '@cpts/Layout/utils';
import
request
from
'
@common/request
'
;
import
api
from
'
@common/api
'
;
import
Tagkv
from
'
./Tagkv
'
;
import
Comparison
from
'
./Comparison
'
;
import
*
as
config
from
'
../config
'
;
import
{
getTimeLabelVal
}
from
'
../util
'
;
import
hasDtag
from
'
../util/hasDtag
'
;
...
...
@@ -213,6 +214,18 @@ export default class GraphConfigForm extends Component<Props, State> {
}
}
handleCommonFieldChange
=
(
changedObj
)
=>
{
const
newChangedObj
=
{};
_
.
each
(
changedObj
,
(
val
,
key
)
=>
{
newChangedObj
[
key
]
=
{
$set
:
val
,
};
});
this
.
setState
(
update
(
this
.
state
,
{
graphConfig
:
newChangedObj
,
}));
}
handleNsChange
=
async
(
selectedNid
:
number
[],
currentMetricObj
:
MetricInterface
)
=>
{
try
{
this
.
setLoading
(
true
);
...
...
@@ -835,6 +848,30 @@ export default class GraphConfigForm extends Component<Props, State> {
]
:
false
}
</
FormItem
>
<
FormItem
labelCol
=
{
{
span
:
3
}
}
wrapperCol
=
{
{
span
:
21
}
}
label
=
{
<
FormattedMessage
id
=
"graph.config.comparison"
/>
}
style
=
{
{
marginBottom
:
0
}
}
>
<
Comparison
size
=
"default"
comparison
=
{
graphConfig
.
comparison
}
relativeTimeComparison
=
{
graphConfig
.
relativeTimeComparison
}
comparisonOptions
=
{
graphConfig
.
comparisonOptions
}
graphConfig
=
{
graphConfig
}
onChange
=
{
(
values
)
=>
{
this
.
handleCommonFieldChange
({
start
:
values
.
start
,
end
:
values
.
end
,
now
:
values
.
now
,
comparison
:
values
.
comparison
,
relativeTimeComparison
:
values
.
relativeTimeComparison
,
comparisonOptions
:
values
.
comparisonOptions
,
});
}
}
/>
</
FormItem
>
{
this
.
renderMetrics
()
}
<
FormItem
labelCol
=
{
{
span
:
3
}
}
...
...
web/src/components/Graph/GraphConfig/GraphConfigInner.tsx
浏览文件 @
0769b025
...
...
@@ -7,6 +7,7 @@ import { Icon, Button, Select, Checkbox, Tooltip, DatePicker } from 'antd';
import
*
as
config
from
'
../config
'
;
import
*
as
util
from
'
../util
'
;
import
Tagkv
from
'
./Tagkv
'
;
import
Comparison
from
'
./Comparison
'
;
import
{
GraphDataInterface
,
GraphDataChangeFunc
}
from
'
../interface
'
;
interface
Props
{
...
...
@@ -77,6 +78,18 @@ export default class GraphConfigInner extends Component<Props> {
});
}
handleComparisonChange
=
(
values
:
any
)
=>
{
const
{
data
,
onChange
}
=
this
.
props
;
onChange
(
'
update
'
,
data
.
id
,
{
start
:
values
.
start
,
end
:
values
.
end
,
now
:
values
.
now
,
comparison
:
values
.
comparison
,
relativeTimeComparison
:
values
.
relativeTimeComparison
,
comparisonOptions
:
values
.
comparisonOptions
,
});
}
handleconsolFuncChange
=
(
val
:
string
)
=>
{
const
{
data
,
onChange
}
=
this
.
props
;
onChange
(
'
update
'
,
data
.
id
,
{
...
...
@@ -178,7 +191,7 @@ export default class GraphConfigInner extends Component<Props> {
render
()
{
const
{
data
,
onChange
}
=
this
.
props
;
const
{
now
,
start
,
end
}
=
data
;
const
{
now
,
start
,
end
,
comparison
}
=
data
;
const
timeLabel
=
now
===
end
?
util
.
getTimeLabelVal
(
start
,
end
,
'
label
'
)
:
'
其他
'
;
const
timeVal
=
now
===
end
?
util
.
getTimeLabelVal
(
start
,
end
,
'
value
'
)
:
'
custom
'
;
const
datePickerStartVal
=
moment
(
Number
(
start
)).
format
(
config
.
timeFormatMap
.
moment
);
...
...
@@ -284,21 +297,23 @@ export default class GraphConfigInner extends Component<Props> {
</
Select
>
</
div
>
:
null
}
{
/* <div className="graph-config-inner-item">
采样函数:
<Select
allowClear
size="small"
style={{ width: 85 }}
placeholder="无"
value={_.get(data.metrics, '[0].consolFunc')}
onChange={this.handleconsolFuncChange}
>
<Option value="AVERAGE">均值</Option>
<Option value="MAX">最大值</Option>
<Option value="MIN">最小值</Option>
</Select>
</div> */
}
<
div
className
=
"graph-config-inner-item"
>
<
FormattedMessage
id
=
"graph.config.comparison"
/>
:
<
Comparison
comparison
=
{
comparison
}
relativeTimeComparison
=
{
data
.
relativeTimeComparison
}
comparisonOptions
=
{
data
.
comparisonOptions
}
graphConfig
=
{
data
}
onChange
=
{
this
.
handleComparisonChange
}
/>
<
input
style
=
{
{
position
:
'
fixed
'
,
left
:
-
10000
,
}
}
id
=
{
`hiddenInput
${
data
.
id
}
`
}
/>
</
div
>
<
div
className
=
"graph-config-inner-item"
>
<
Checkbox
checked
=
{
!!
data
.
legend
}
onChange
=
{
this
.
legendChange
}
>
Legend
...
...
web/src/components/Graph/config.tsx
浏览文件 @
0769b025
...
...
@@ -2,21 +2,26 @@ import PropTypes from 'prop-types';
import
moment
from
'
moment
'
;
const
now
=
moment
();
export
const
comparison
=
[
export
const
comparison
Options
=
[
{
label
:
'
1小时
'
,
labelEn
:
'
1 hour
'
,
value
:
'
3600000
'
,
},
{
label
:
'
2小时
'
,
labelEn
:
'
2 hours
'
,
value
:
'
7200000
'
,
},
{
label
:
'
1天
'
,
labelEn
:
'
1 day
'
,
value
:
'
86400000
'
,
},
{
label
:
'
2天
'
,
labelEn
:
'
2 days
'
,
value
:
'
172800000
'
,
},
{
label
:
'
7天
'
,
labelEn
:
'
7 days
'
,
value
:
'
604800000
'
,
},
];
...
...
@@ -74,6 +79,7 @@ export const graphDefaultConfig = {
now
:
now
.
clone
().
format
(
'
x
'
),
start
:
now
.
clone
().
subtract
(
3600000
,
'
ms
'
).
format
(
'
x
'
),
end
:
now
.
clone
().
format
(
'
x
'
),
comparisonOptions
,
threshold
:
undefined
,
legend
:
false
,
shared
:
false
,
...
...
web/src/components/Graph/util/getTooltipsContent.tsx
浏览文件 @
0769b025
...
...
@@ -32,20 +32,38 @@ export default function getTooltipsContent(activeTooltipData: ActiveTooltipData)
tooltipContent
+=
getHeaderStr
(
activeTooltipData
);
_
.
each
(
sortedPoints
,
(
point
)
=>
{
tooltipContent
+=
singlePoint
(
point
);
tooltipContent
+=
singlePoint
(
point
,
activeTooltipData
);
});
return
`<div style="table-layout: fixed;max-width:
${
chartWidth
}
px;word-wrap: break-word;white-space: normal;">
${
tooltipContent
}
</div>`
;
}
function
singlePoint
(
pointData
=
{}
as
PointInterface
)
{
const
{
color
,
filledNull
,
serieOptions
=
{}
}
=
pointData
;
const
{
tags
}
=
serieOptions
as
any
;
function
singlePoint
(
pointData
=
{},
activeTooltipData
)
{
const
{
color
,
filledNull
,
serieOptions
=
{},
timestamp
}
=
pointData
;
const
{
comparison
:
comparisons
,
isComparison
}
=
activeTooltipData
;
const
{
tags
}
=
serieOptions
;
const
value
=
numeral
(
pointData
.
value
).
format
(
'
0,0[.]000
'
);
let
name
=
tags
;
// 对比情况下 name 特殊处理
if
(
isComparison
)
{
const
mDate
=
serieOptions
.
comparison
&&
typeof
serieOptions
.
comparison
===
'
number
'
?
moment
(
timestamp
).
subtract
(
serieOptions
.
comparison
,
'
seconds
'
)
:
moment
(
timestamp
);
const
isAllDayLevelComparison
=
_
.
every
(
comparisons
,
(
o
)
=>
{
return
_
.
isInteger
(
Number
(
o
)
/
86400000
);
});
if
(
isAllDayLevelComparison
)
{
const
dateStr
=
mDate
.
format
(
'
YYYY-MM-DD
'
);
name
=
`
${
dateStr
}
`
;
}
else
{
const
dateStr
=
mDate
.
format
(
fmt
);
name
=
`
${
dateStr
}
${
name
}
`
;
}
}
return
(
`<span style="color:
${
color
}
">● </span>
${
_
.
escape
(
tags
)
}
:<strong>
${
value
}${
filledNull
?
'
(空值填补,仅限看图使用)
'
:
''
}
</strong><br />`
${
name
}
:<strong>
${
value
}${
filledNull
?
'
(空值填补,仅限看图使用)
'
:
''
}
</strong><br />`
);
}
...
...
web/src/components/Graph/util/normalizeEndpointCounters.tsx
浏览文件 @
0769b025
...
...
@@ -5,7 +5,7 @@ export function transformMsToS(ts: string) {
return
Number
(
ts
.
substring
(
0
,
ts
.
length
-
3
));
}
export
function
processComparison
(
comparison
:
number
[])
{
export
function
processComparison
(
comparison
:
string
[])
{
const
newComparison
=
[
0
];
_
.
each
(
comparison
,
(
o
)
=>
{
newComparison
.
push
(
transformMsToS
(
String
(
o
)));
...
...
@@ -14,6 +14,7 @@ export function processComparison(comparison: number[]) {
}
export
default
function
normalizeEndpointCounters
(
graphConfig
:
GraphDataInterface
,
counterList
:
CounterInterface
[])
{
const
newComparison
=
processComparison
(
graphConfig
.
comparison
);
const
firstMetric
=
_
.
get
(
graphConfig
,
'
metrics[0]
'
,
{});
const
{
aggrFunc
,
aggrGroup
:
groupKey
,
consolFunc
}
=
firstMetric
;
const
start
=
transformMsToS
(
_
.
toString
(
graphConfig
.
start
));
...
...
@@ -27,6 +28,7 @@ export default function normalizeEndpointCounters(graphConfig: GraphDataInterfac
aggrFunc
,
groupKey
,
consolFunc
,
comparisons
:
newComparison
,
};
});
...
...
web/src/components/Graph/util/normalizeSeries.tsx
浏览文件 @
0769b025
...
...
@@ -5,7 +5,7 @@ import { SerieInterface } from '../interface';
export
default
function
normalizeSeries
(
data
:
any
[])
{
const
series
=
[]
as
SerieInterface
[];
_
.
each
(
_
.
sortBy
(
data
,
[
'
counter
'
,
'
endpoint
'
]),
(
o
,
i
)
=>
{
const
{
endpoint
}
=
o
;
const
{
endpoint
,
comparison
}
=
o
;
const
color
=
getSerieColor
(
o
,
i
);
const
separatorIdx
=
o
.
counter
.
indexOf
(
'
/
'
);
...
...
@@ -23,6 +23,7 @@ export default function normalizeSeries(data: any[]) {
lineWidth
:
2
,
color
,
oldColor
:
color
,
comparison
,
}
as
SerieInterface
;
series
.
push
(
serie
);
});
...
...
web/src/locales/en.ts
浏览文件 @
0769b025
...
...
@@ -260,6 +260,7 @@ export default {
'
graph.config.aggr.max
'
:
'
max
'
,
'
graph.config.aggr.min
'
:
'
min
'
,
'
graph.config.aggr.group
'
:
'
groupBy
'
,
'
graph.config.comparison
'
:
'
comparison
'
,
'
graph.config.series
'
:
'
series
'
,
'
graph.config.series.unit
'
:
'
pcs
'
,
'
graph.config.cate
'
:
'
cate
'
,
...
...
web/src/locales/zh.ts
浏览文件 @
0769b025
...
...
@@ -261,6 +261,7 @@ export default {
'
graph.config.aggr.max
'
:
'
最大值
'
,
'
graph.config.aggr.min
'
:
'
最小值
'
,
'
graph.config.aggr.group
'
:
'
聚合维度
'
,
'
graph.config.comparison
'
:
'
环比
'
,
'
graph.config.series
'
:
'
曲线
'
,
'
graph.config.series.unit
'
:
'
条
'
,
'
graph.config.cate
'
:
'
分类
'
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录