NEZ-784 NEZ-770 :endpoint 名字拼接后过长从中间截取一部分 ,以及新增 Diagram 图表类型

This commit is contained in:
zhangyu
2021-07-01 19:15:08 +08:00
parent b2e6175cca
commit c778cf2eb4
10 changed files with 407 additions and 195 deletions

View File

@@ -41,7 +41,7 @@
</div> </div>
<div class="mt-10 rich-text-container" v-cloak v-show="firstShow" > <div class="mt-10 rich-text-container" v-cloak v-show="firstShow" >
<div :id="'chartContainer'+chartIndex" ref="chartContainer" class="text-content" > <div :id="'chartContainer'+chartIndex" ref="chartContainer" class="text-content" >
<diagram style="height: 100%;width: 100%" :topoData="data.param.topo" :fromChart="true" :topologyIndexF="chartData.id" ref="diagram"/> <diagram style="height: 100%;width: 100%" :topoData="data.param.topo" :fromChart="true" :topologyIndexF="chartData.id" :isPanel="true" ref="diagram"/>
</div> </div>
</div> </div>
<!--全屏--> <!--全屏-->
@@ -53,7 +53,7 @@
</div> </div>
<div class="rich-text-screen-container" > <div class="rich-text-screen-container" >
<div id="chartScreenContainer" ref="chartScreenContainer" class="text-content" > <div id="chartScreenContainer" ref="chartScreenContainer" class="text-content" >
<diagram :topoData="data.param.topo" :fromChart="true" :topologyIndexF="chartData.id + '-' + 'chartIndex'"/> <diagram :topoData="data.param.topo" :fromChart="true" :isScreen="true" :topologyIndexF="chartData.id + '-' + 'chartIndex'"/>
</div> </div>
</div> </div>
<loading :ref="'localLoadingScreen'+chartIndex"></loading> <loading :ref="'localLoadingScreen'+chartIndex"></loading>

View File

@@ -7,7 +7,7 @@
<div class="resize-box resize-box-echarts" ref="resizeBox"> <div class="resize-box resize-box-echarts" ref="resizeBox">
<div class="line-chart-block" :id="'lineChartDiv'+chartIndex" @mouseenter="mouseEnterChart" @mouseleave="mouseLeaveChart"> <div class="line-chart-block" :id="'lineChartDiv'+chartIndex" @mouseenter="mouseEnterChart" @mouseleave="mouseLeaveChart">
<loading :ref="'localLoading'+chartIndex"></loading> <loading :ref="'localLoading'+chartIndex"></loading>
<div v-if="from!=='project'" :class="{'drag-disabled': this.filter.from == $CONSTANTS.fromRoute.alertRule}" :id="'chartTitle'+chartIndex" class="clearfix chartTitle"> <div v-if="from!=='project'&&from!=='topology'" :class="{'drag-disabled': this.filter.from == $CONSTANTS.fromRoute.alertRule}" :id="'chartTitle'+chartIndex" class="clearfix chartTitle">
<el-popover <el-popover
v-if="isError" v-if="isError"
placement="top-start" placement="top-start"
@@ -65,6 +65,9 @@
</ul> </ul>
</el-dropdown> </el-dropdown>
</div> </div>
<div v-if="from==='topology'" :class="{'drag-disabled': this.filter.from == $CONSTANTS.fromRoute.alertRule}" :id="'chartTitle'+chartIndex" class="topology-chart-title">
<span class="topology-chart-title-text">{{chartData.name}}</span>
</div>
<div class="line-area" ref="lineChartArea" :id="'lineChartArea'+chartIndex" v-show="firstShow" style="width:100%;"></div> <div class="line-area" ref="lineChartArea" :id="'lineChartArea'+chartIndex" v-show="firstShow" style="width:100%;"></div>
<div class="chart-no-data" v-show="noData">No Data</div> <div class="chart-no-data" v-show="noData">No Data</div>
<template v-if="!hasLegendOptions"> <template v-if="!hasLegendOptions">
@@ -1344,6 +1347,7 @@ export default {
}, },
// 设置数据, filter区分 // 设置数据, filter区分
setData (chartItem, seriesItem, panelId, filter, legend, area, errorMsg) { setData (chartItem, seriesItem, panelId, filter, legend, area, errorMsg) {
console.log(chartItem, seriesItem, panelId, filter, legend, area, errorMsg)
legend && this.setColor(legend.length) legend && this.setColor(legend.length)
legend && legend.forEach((t, i) => { t.color = this.bgColorList[i] }) legend && legend.forEach((t, i) => { t.color = this.bgColorList[i] })
this.filter.from = filter.from this.filter.from = filter.from

View File

@@ -6,7 +6,7 @@
<div class="project-box list-page" v-loading="topologyLoading" v-has="'topo_list'"> <div class="project-box list-page" v-loading="topologyLoading" v-has="'topo_list'">
<div class="main-list"> <div class="main-list">
<div class="main-container" :class="fromOverView?'from-overview':'from-project'" style="background: #fff"> <div class="main-container" :class="fromOverView?'from-overview':'from-project'" style="background: #fff">
<div v-if="(editTopologyFlag || isPreview)&&!fromChart" class="edit-topologyLine top-tools" style="padding-left: 20px;width: calc(100% - 20px);"> <div v-if="(editTopologyFlag || isPreview)&&!fromChart" class="edit-topologyLine top-tools" style="padding-left: 20px;width: calc(100% - 20px);display: inline-block">
<!--工具栏--> <!--工具栏-->
<span v-if="!isPreview" class="project-topology-tool"> <span v-if="!isPreview" class="project-topology-tool">
<el-dropdown trigger="click" size="small" placement="bottom-start" v-has="'topo_icon_list'"> <el-dropdown trigger="click" size="small" placement="bottom-start" v-has="'topo_icon_list'">
@@ -202,11 +202,11 @@
<!--节点连线相关的 tooltip--> <!--节点连线相关的 tooltip-->
<div v-if="tooltipPosition.show&&!editTopologyFlag" <div v-if="tooltipPosition.show&&!editTopologyFlag"
ref="topoTooltip" ref="topoTooltip"
:style="{position:'absolute',top:tooltipPosition.top+'px',left:tooltipPosition.left+'px','z-index':10,height:tooltipPosition.height+'px'}" :style="{position:isScreen?'fixed' : 'absolute',top:tooltipPosition.top+'px',left:tooltipPosition.left+'px','z-index':10,height:tooltipPosition.height+'px'}"
@mouseout="tooltipOut" @mouseout="tooltipOut"
@mouseover="tooltipOver" @mouseover="tooltipOver"
> >
<topoTooltip :chartDataParent="chartData" :filterTime="filterTime"/> <topoTooltip :chartDataParent="chartData" :filterTime="filterTime" :isPanel="isPanel"/>
</div> </div>
</div> </div>
<!--endpoint--> <!--endpoint-->
@@ -517,6 +517,14 @@ export default {
fromTopologyDialog: { fromTopologyDialog: {
type: Boolean, type: Boolean,
default: false default: false
},
isPanel: {
type: Boolean,
default: false
},
isScreen: {
type: Boolean,
default: false
} }
}, },
watch: { watch: {
@@ -1138,6 +1146,7 @@ export default {
setTimeout(() => { setTimeout(() => {
this.tooltipPosition.show = true this.tooltipPosition.show = true
const ePosition = window.ePosition const ePosition = window.ePosition
console.log(ePosition)
const boxWidth = document.getElementsByClassName('page')[0].offsetWidth const boxWidth = document.getElementsByClassName('page')[0].offsetWidth
const boxHeight = document.getElementsByClassName('page')[0].offsetHeight const boxHeight = document.getElementsByClassName('page')[0].offsetHeight
this.tooltipPosition.left = ePosition.layerX + 20 this.tooltipPosition.left = ePosition.layerX + 20
@@ -1155,6 +1164,10 @@ export default {
this.tooltipPosition.top = ePosition.layerY - this.$refs.topoTooltip.offsetHeight this.tooltipPosition.top = ePosition.layerY - this.$refs.topoTooltip.offsetHeight
} }
} }
if (this.isScreen) {
this.tooltipPosition.left = ePosition.offsetX + 50
this.tooltipPosition.top = ePosition.offsetY + 80
}
}) })
}, 100) }, 100)
break break
@@ -1753,6 +1766,14 @@ export default {
return true return true
} }
}) })
item.data.expressAllArr = item.data.expressAllArr.filter((expression, i) => {
if (!expression) {
item.data.legendsAll.splice(i, 1)
return false
} else {
return true
}
})
}) })
if (this.penToolTipScale == getTopology(this.topologyIndex).data.scale) { if (this.penToolTipScale == getTopology(this.topologyIndex).data.scale) {
getTopology(this.topologyIndex).data.scale = this.oldScale getTopology(this.topologyIndex).data.scale = this.oldScale

View File

@@ -104,21 +104,17 @@
<div class="alert-label-value">{{alertLabelData && alertLabelData.module && alertLabelData.module.name ? alertLabelData.module.name : '--'}}</div> <div class="alert-label-value">{{alertLabelData && alertLabelData.module && alertLabelData.module.name ? alertLabelData.module.name : '--'}}</div>
</div> </div>
<div class="alert-label-box"> <div class="alert-label-box">
<div class="alert-label-title">Labels</div> <div class="alert-label-title">Configs</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.labels ? alertLabelData.labels : '--'}}</div> <div class="alert-label-value">{{alertLabelData && alertLabelData.configs ? alertLabelData.configs : '--'}}</div>
</div> </div>
<div class="alert-label-box"> <div class="alert-label-box">
<div class="alert-label-title">Host</div> <div class="alert-label-title">ManageIp</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.host ? alertLabelData.host : '--'}}</div> <div class="alert-label-value">{{alertLabelData && alertLabelData.asset ? alertLabelData.asset.manageIp : '--'}}</div>
</div> </div>
<div class="alert-label-box"> <div class="alert-label-box">
<div class="alert-label-title">Port</div> <div class="alert-label-title">Port</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.port ? alertLabelData.port : '--'}}</div> <div class="alert-label-value">{{alertLabelData && alertLabelData.port ? alertLabelData.port : '--'}}</div>
</div> </div>
<div class="alert-label-box">
<div class="alert-label-title">Path</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.path ? alertLabelData.path : '--'}}</div>
</div>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -1014,10 +1014,10 @@ export default {
// id: 'bar', // id: 'bar',
// name: this.$t('dashboard.panel.chartForm.typeVal.bar.label') // name: this.$t('dashboard.panel.chartForm.typeVal.bar.label')
// }, // },
{ // {
id: 'table', // id: 'table',
name: this.$t('dashboard.panel.chartForm.typeVal.table.label') // name: this.$t('dashboard.panel.chartForm.typeVal.table.label')
} // }
], ],
aggregationList: [ aggregationList: [
{ {

View File

@@ -1,10 +1,11 @@
<template> <template>
<div class="tooltip-box" style="display: flex;" v-if="(isChart||chartData.tooltipShow)&&chartData.expressArr.length"> <div class="tooltip-box" style="display: flex;" v-if="(isChart||chartData.tooltipShow)&&chartData.expressAllArr.length">
<div class="tooltip-box-chart" style="" v-if="isChart||(chartData.displayChart&&chartData.tooltipShow&&chartData.expressArr.length)"> <div class="tooltip-box-chart" style="" v-if="isChart||(chartData.displayChart&&chartData.tooltipShow&&chartData.expressAllArr.length)">
<line-chart-block v-show="isChart || chartData.type !== 'table'" <line-chart-block v-show="isChart || chartData.type !== 'table'"
:key="'inner' + chartData.id" :key="'inner' + chartData.id"
:class="isPanel? 'topology-tool-tip' : ''"
id="listContainer" id="listContainer"
:from="'project'" :from="'topology'"
:ref="chartData.type !== 'table'?'editChart' + chartData.type:'editChart'" :ref="chartData.type !== 'table'?'editChart' + chartData.type:'editChart'"
:temp-dom="tempDom" :temp-dom="tempDom"
:panel-id="-1" :panel-id="-1"
@@ -34,6 +35,10 @@ import lineChartBlock from '../../../charts/line-chart-block'
import chartTable from '../../../charts/chart-table' import chartTable from '../../../charts/chart-table'
import bus from '../../../../libs/bus' import bus from '../../../../libs/bus'
import ExpressionInfo from '../popData/expressionInfo' import ExpressionInfo from '../popData/expressionInfo'
import {fromRoute} from "@/components/common/js/constants";
import chartTempData from "@/components/charts/chartTempData";
import axios from "axios";
import chartDataFormat from "@/components/charts/chartDataFormat";
export default { export default {
name: 'topoTooltip', name: 'topoTooltip',
components: { components: {
@@ -49,6 +54,10 @@ export default {
isChart: { isChart: {
type: Boolean, type: Boolean,
default: false default: false
},
isPanel: {
type: Boolean,
default: false
} }
}, },
watch: { watch: {
@@ -70,7 +79,7 @@ export default {
panelId: 0, panelId: 0,
searchName: '', searchName: '',
start_time: bus.timeFormate(bus.getOffsetTimezoneData(-1), 'yyyy-MM-dd hh:mm:ss') start_time: bus.timeFormate(bus.getOffsetTimezoneData(-1), 'yyyy-MM-dd hh:mm:ss')
} },
} }
}, },
mounted () { mounted () {
@@ -81,13 +90,12 @@ export default {
this.tempDom.width = 250 this.tempDom.width = 250
}, },
process (item) { process (item) {
console.log(item)
const chartData = { ...this.chartDataTemp, ...item, name: item.chartTitle } const chartData = { ...this.chartDataTemp, ...item, name: item.chartTitle }
chartData.elements = [] chartData.elements = []
chartData.expressArr.forEach((item1, index) => { chartData.expressAllArr.forEach((item1, index) => {
chartData.elements.push({ chartData.elements.push({
expression: item1, expression: item1,
legend: chartData.legends[index], legend: chartData.legendsAll[index],
type: 'expert', type: 'expert',
id: index, id: index,
buildIn: null, buildIn: null,
@@ -106,9 +114,7 @@ export default {
} }
chartData.span = 12 chartData.span = 12
this.chartData = chartData this.chartData = chartData
setTimeout(() => { this.getChartData(chartData, 0)
this.getChartData(chartData, 0)
})
}, },
// 获取一个图表具体数据,图表信息图表位置index // 获取一个图表具体数据,图表信息图表位置index
getChartData (chartInfo, pos, filterType) { getChartData (chartInfo, pos, filterType) {
@@ -122,154 +128,230 @@ export default {
} }
}) })
} else { } else {
/* let startTime = '' const endTime = this.filter.end_time
let endTime = '' */ const startTime = this.filter.start_time
/* if (filterType === 'refresh') { // 刷新 const step = bus.getStep(startTime, endTime)
const now = new Date(bus.computeTimezone(new Date().getTime())) this.$nextTick(() => {
const origin = new Date(this.filter.end_time) const axiosArr = chartItem.elements.map((ele) => {
const numInterval = now.getTime() - origin.getTime() const filterItem = ele
if (numInterval >= 60000) { // 大于1分钟则start、end均往后移numInterval否则时间不变 let query = filterItem.expression
startTime = this.getNewTime(this.filter.start_time, numInterval) if ((chartInfo.type === 'line' || chartInfo.type === 'bar' || chartInfo.type === 'stackArea' || chartInfo.type === 'table') && chartInfo.param) { // 如果是这三个 默认给null
endTime = bus.timeFormate(now, 'yyyy-MM-dd hh:mm:ss') chartInfo.param.nullType = chartInfo.param.nullType || 'null'
} else { query += '&nullType=' + chartInfo.param.nullType
startTime = this.filter.start_time }
endTime = this.filter.end_time // if(chartInfo.type === 'table'&&chartInfo.param&&chartInfo.param.last == 1){
} // return this.$get('/prom/api/v1/query_range?query=' + query + "&start=" + this.$stringTimeParseToUnix(endTime) + "&end=" + this.$stringTimeParseToUnix(endTime) + '&step=' + step);
} else if (filterType === 'showFullScreen') { // 全屏时间查询 // }
startTime = this.filter.start_time if (this.from === fromRoute.chartTemp) {
endTime = this.filter.end_time return chartTempData
// this.$parent.refreshTime(startTime,endTime);全屏查询不更新panel列表的时间条件 }
} else { return this.$get('/prom/api/v1/query_range?query=' + query + '&start=' + this.$stringTimeParseToUnix(startTime) + '&end=' + this.$stringTimeParseToUnix(endTime) + '&step=' + step)
startTime = this.filter.start_time })
endTime = this.filter.end_time // 一个图表的所有element单独获取数据
} */ axios.all(axiosArr).then((res) => {
setTimeout(() => {
this.$nextTick(() => {
const res = chartItem.res
if (res.length > 0) { if (res.length > 0) {
const series = [] const series = []
let singleStatRlt = ''
const legend = [] const legend = []
const tableData = [] const tableData = []
/* let sumData = { /* let sumData = {
name: 'sum', name: 'sum',
data: [], data: [],
visible: true, visible: true,
threshold: null, threshold: null,
}; */ }; */
let errorMsg = '' let errorMsg = ''
let pieSeries
if (chartInfo.type === 'pie') {
pieSeries = {
type: 'pie',
radius: '100%',
center: ['50%', '50%'],
top: '20%',
bottom: '20%',
// roseType: 'radius',
minAngle: 10,
itemStyle: {
borderRadius: 5,
borderColor: '#fff',
borderWidth: 1
},
label: {
show: false
},
emphasis: {
label: {
show: false
}
},
data: []
}
}
if (chartInfo.type === 'bar' && chartInfo.param.statistics && chartInfo.param.statistics !== 'null') {
pieSeries = {
type: 'bar',
// roseType: 'radius',
itemStyle: {
borderRadius: 5,
borderColor: '#fff',
borderWidth: 1
},
label: {
show: false
},
emphasis: {
label: {
show: false
}
},
data: []
}
}
res.forEach((response, innerPos) => { res.forEach((response, innerPos) => {
if (response.status === 'success') { if (response.status === 'success') {
errorMsg = '' errorMsg = ''
if (response.data.result) { if (response.data.result) {
// 循环处理每个elements下获取的数据 // 循环处理每个elements下获取的数据
response.data.result.forEach((queryItem, resIndex) => { if (chartItem.type === 'singleStat') {
let seriesItem = { if (response.data.result.length === 1) {
theData: { const statistics = chartItem.param.statistics || 'null'
name: '', if (response.data.result[0].values) {
symbol: 'emptyCircle', // 去掉点 singleStatRlt = bus.getSingleStatRlt(statistics, response.data.result[0].values)
symbolSize: [2, 2],
smooth: 0.2, // 曲线变平滑
showSymbol: false,
data: [],
lineStyle: {
width: 1,
opacity: 0.9
},
animation: false,
type: chartInfo.type
},
metric_name: ''
}
if ((chartInfo.type === 'line' || chartInfo.type === 'stackArea' || chartInfo.type === 'bar') && chartInfo.param && chartInfo.param.threshold) {
seriesItem.theData.markLine = {
silent: true,
symbol: ['circle', 'circle'],
label: {
distance: this.computeDistance(chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(chartInfo.param.threshold)),
formatter: function (params) {
return chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(params.value)
}
},
lineStyle: {
color: '#d64f40',
width: 2,
type: 'dotted'
},
data: [{
yAxis: Number(chartInfo.param.threshold)
}]
} }
} else if (response.data.result.length > 1) {
singleStatRlt = this.$t('dashboard.panel.singleStatErrorTip')
} }
// 图表中每条线的名字,后半部分 } else {
let host = ''// up, response.data.result.forEach((queryItem, resIndex) => {
if (queryItem.metric.__name__) { let seriesItem = {
host = `${queryItem.metric.__name__}{`// up, theData: {
} name: '',
const tagsArr = Object.keys(queryItem.metric)// ["__name__","asset","idc","instance","job","module","project"] symbol: 'emptyCircle', // 去掉点
// 设置时间-数据格式对 symbolSize: [2, 2],
let tempArr = [] smooth: 0.2, // 曲线变平滑
let dpsArr = [] showSymbol: false,
tempArr = queryItem.values data: [],
dpsArr = Object.entries(queryItem.values)// [ ["0",[1577959830.781,"0"]], ["1",[1577959845.781,"0"]] ] lineStyle: {
dpsArr = dpsArr.map(item => { width: 1,
return [item[0], [item[1][0], Number(item[1][1])]] opacity: 0.9
}) },
// 判断是否有数据, && tagsArr.length > 0 animation: false,
if (dpsArr.length > 0 && this.$refs['editChart' + chartItem.type]) { type: chartInfo.type
tagsArr.forEach((tag, i) => { },
if (tag !== '__name__') { metric_name: ''
host += `${tag}="${queryItem.metric[tag]}",` }
if (chartInfo.type === 'stackArea') {
seriesItem.theData.type = 'line'
seriesItem.theData.stack = chartInfo.name
seriesItem.theData.areaStyle = { opacity: 0.3 }
}
if ((chartInfo.type === 'line' || chartInfo.type === 'stackArea' || chartInfo.type === 'bar') && chartInfo.param && chartInfo.param.threshold) {
seriesItem.theData.markLine = {
silent: true,
symbol: ['circle', 'circle'],
label: {
distance: this.computeDistance(chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(chartInfo.param.threshold)),
formatter (params) {
return chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(params.value)
}
},
lineStyle: {
color: '#d64f40',
width: 2,
type: 'dotted'
},
data: [{
yAxis: Number(chartInfo.param.threshold)
}]
} }
})
if (host.endsWith(',')) {
host = host.substr(0, host.length - 1)
} }
// 图表中每条线的名字,后半部分
let host = ''// up,
if (queryItem.metric.__name__) { if (queryItem.metric.__name__) {
host += '}' host = `${queryItem.metric.__name__}{`// up,
} }
if (!host || host === '') { const tagsArr = Object.keys(queryItem.metric)// ["__name__","asset","idc","instance","job","module","project"]
host = chartItem.elements[innerPos].expression // 设置时间-数据格式对
} let tempArr = []
// 处理legend别名 let dpsArr = []
let alias = this.$refs['editChart' + chartItem.type].dealLegendAlias(host, chartItem.elements[innerPos].legend) tempArr = queryItem.values
if (!alias || alias === '') { dpsArr = Object.entries(queryItem.values)// [ ["0",[1577959830.781,"0"]], ["1",[1577959845.781,"0"]] ]
alias = host dpsArr = dpsArr.map(item => {
} return [item[0], [item[1][0], Number(item[1][1])]]
legend.push({ name: host + '-' + chartItem.elements[innerPos].id + '-' + resIndex, alias: alias })
// 图表中每条线的名字,去掉最后的逗号与空格:metric名称, 标签1=a,标签2=c
seriesItem.theData.name = host + '-' + chartItem.elements[innerPos].id + '-' + resIndex
// alert(seriesItem.theData.name);
seriesItem.metric_name = seriesItem.theData.name
// 将秒改为毫秒
// alert('table=='+JSON.stringify(queryItem))
seriesItem.theData.data = tempArr.map((dpsItem, dpsIndex) => {
/* 曲线汇总暂不需要
if (sumData.data[dpsIndex]) {
const sumNum = sumData.data[dpsIndex][1] || 0;
sumData.data[dpsIndex][1] = sumNum + dpsItem[1];
} else {
sumData.data[dpsIndex] = [dpsItem[0] * 1000, dpsItem[1]];
}
*/
const tData = new Date(dpsItem[0] * 1000)
const timeTmp = bus.timeFormate(tData, 'yyyy-MM-dd hh:mm:ss')
tableData.push({ // 表格数据
// label: host.slice(host.indexOf('{') + 1,host.indexOf('}')),//label
// metric: queryItem.metric.__name__?queryItem.metric.__name__:'',//metric列
element: { element: host, alias: alias },
time: timeTmp, // 采集时间
value: dpsItem[1], // 数值
data: [dpsItem[0] * 1000, dpsItem[1]]
})
return [dpsItem[0] * 1000, dpsItem[1]]
}) })
series.push(seriesItem.theData) // 判断是否有数据, && tagsArr.length > 0
seriesItem = null if (dpsArr.length > 0 && this.$refs['editChart' + chartItem.type]) {
} tagsArr.forEach((tag, i) => {
}) if (tag !== '__name__') {
host += `${tag}="${queryItem.metric[tag]}",`
}
})
if (host.endsWith(',')) {
host = host.substr(0, host.length - 1)
}
if (queryItem.metric.__name__) {
host += '}'
}
if (!host || host === '') {
host = chartItem.elements[innerPos].expression
}
// 处理legend别名
let alias = this.$refs['editChart' + chartItem.type].dealLegendAlias(host, chartItem.elements[innerPos].legend)
if (!alias || alias === '') {
alias = host
}
legend.push({ name: host + '-' + chartItem.elements[innerPos].id + '-' + resIndex, alias: alias })
// 图表中每条线的名字,去掉最后的逗号与空格:metric名称, 标签1=a,标签2=c
seriesItem.theData.name = host + '-' + chartItem.elements[innerPos].id + '-' + resIndex
// alert(seriesItem.theData.name);
seriesItem.metric_name = seriesItem.theData.name
// 将秒改为毫秒
// alert('table=='+JSON.stringify(queryItem))
seriesItem.theData.data = tempArr.map((dpsItem, dpsIndex) => {
/* 曲线汇总暂不需要
if (sumData.data[dpsIndex]) {
const sumNum = sumData.data[dpsIndex][1] || 0;
sumData.data[dpsIndex][1] = sumNum + dpsItem[1];
} else {
sumData.data[dpsIndex] = [dpsItem[0] * 1000, dpsItem[1]];
}
*/
// let t_date = new Date(dpsItem[0] * 1000);
// let timeTmp = bus.timeFormate(t_date, 'yyyy-MM-dd hh:mm:ss');
tableData.push({ // 表格数据
// label: host.slice(host.indexOf('{') + 1,host.indexOf('}')),//label
// metric: queryItem.metric.__name__?queryItem.metric.__name__:'',//metric列
element: { element: host, alias: alias },
// time: timeTmp,//采集时间
// value: dpsItem[1],//数值
data: [dpsItem[0] * 1000, dpsItem[1]]
})
return [dpsItem[0] * 1000, dpsItem[1]]
})
if (chartInfo.type === 'pie') {
pieSeries.data.push({ value: bus.getSingleStatRlt(chartInfo.param.statistics, seriesItem.theData.data), name: host + '-' + chartItem.elements[innerPos].id + '-' + resIndex })
} else if (chartInfo.type === 'bar' && chartInfo.param.statistics && chartInfo.param.statistics !== 'null') {
pieSeries.data.push({ value: bus.getSingleStatRlt(chartInfo.param.statistics, seriesItem.theData.data), name: host + '-' + chartItem.elements[innerPos].id + '-' + resIndex })
} else {
series.push(seriesItem.theData)
seriesItem = null
}
} else if (chartItem.elements && chartItem.elements[innerPos]) {
// 无数据提示
/*
const currentInfo = chartItem.elements[innerPos];
const errorMsg = `图表 ${chartItem.title} 中 ${currentInfo.metric},${currentInfo.tags} 无数据`;
this.$message.warning({
duration: 15,
content: errorMsg,
closable: true,
});
*/
}
})
}
} }
} else { } else {
if (response.msg) { if (response.msg) {
@@ -285,7 +367,13 @@ export default {
} }
}) })
if (this.$refs['editChart' + chartItem.type]) { if (this.$refs['editChart' + chartItem.type]) {
/* const chartData = { if (chartInfo.type === 'pie') {
series.push(pieSeries)
}
if (chartInfo.type === 'bar' && chartInfo.param.statistics && chartInfo.param.statistics !== 'null') {
series.push(pieSeries)
}
const chartData = {
chartItem: chartItem, chartItem: chartItem,
series: series, series: series,
singleStatRlt: singleStatRlt, singleStatRlt: singleStatRlt,
@@ -295,30 +383,73 @@ export default {
filter: this.filter, filter: this.filter,
filterType: filterType, filterType: filterType,
errorMsg: errorMsg errorMsg: errorMsg
} */ }
if (chartItem.type === 'table') { // 表格 if (chartItem.type === 'table') { // 表格
this.$refs['editChart' + chartItem.type].setData(chartItem, tableData, this.filter.panelId, this.filter, '', errorMsg) if (filterType === 'showFullScreen') { // 全屏查询
} else if (chartItem.type === 'line' || chartItem.type === 'bar' || chartItem.type === 'stackArea' || chartItem.type === 4) { this.$refs['editChart' + chartItem.type].setData(chartItem, tableData,
this.filter.panelId, this.filter, filterType, errorMsg)
} else {
this.$refs['editChart' + chartItem.type].setData(chartItem, tableData,
this.filter.panelId, this.filter, '', errorMsg)
}
} else if (chartItem.type === 'line' || chartItem.type === 'bar' || chartItem.type === 'stackArea' || chartItem.type === 4 || chartItem.type == 'pie') {
if (series.length && chartItem.type === 4) { // 曲线汇总 if (series.length && chartItem.type === 4) { // 曲线汇总
// series.push(sumData);//后续需要 // series.push(sumData);//后续需要
} }
this.$refs['editChart' + chartItem.type].setData(chartItem, series, this.filter.panelId, this.filter, legend, '', errorMsg) if (filterType === 'showFullScreen') { // 全屏查询
this.$refs['editChart' + chartItem.type].setData(chartItem, series,
this.filter.panelId, this.filter, legend, filterType, errorMsg)
} else {
this.$refs['editChart' + chartItem.type].setData(chartItem, series,
this.filter.panelId, this.filter, legend, '', errorMsg)
}
} else if (chartItem.type === 'singleStat') {
if (filterType === 'showFullScreen') { // 全屏查询
this.$refs['editChart' + chartItem.type].setData(chartItem, singleStatRlt,
this.filter.panelId, this.filter, filterType, errorMsg)
} else {
this.$refs['editChart' + chartItem.type].setData(chartItem, singleStatRlt,
this.filter.panelId, this.filter, '', errorMsg)
}
} }
} }
} else { } else {
const type = chartItem.type const type = chartItem.type
if (this.$refs['editChart' + chartItem.type]) { if (this.$refs['editChart' + chartItem.type]) {
if (type === 'table') { if (type === 'table') {
this.$refs['editChart' + chartItem.type].setData(chartItem, [], this.filter.panelId, if (filterType === 'showFullScreen') { // table的全屏查询
this.filter, filterType) this.$refs['editChart' + chartItem.type].setData(chartItem, [], this.filter.panelId,
} else if (type === 'line' || type === 'bar' || type === 'stackArea' || chartItem.type === 4) { this.filter, filterType)
this.$refs['editChart' + chartItem.type].setData(chartItem, [], this.filter.panelId, } else {
this.filter, filterType) this.$refs['editChart' + chartItem.type].setData(chartItem, [], this.filter.panelId,
this.filter)
}
} else if (type === 'line' || type === 'bar' || type === 'stackArea' || chartItem.type === 4 || chartItem.type === 'pie') {
if (filterType === 'showFullScreen') { // table的全屏查询
this.$refs['editChart' + chartItem.type].setData(chartItem, [], this.filter.panelId,
this.filter, filterType)
} else {
this.$refs['editChart' + chartItem.type].setData(chartItem, [], this.filter.panelId,
this.filter)
}
} else if (chartItem.type === 'singleStat') {
if (filterType === 'showFullScreen') { // 全屏查询
this.$refs['editChart' + chartItem.type].setData(chartItem, '',
this.filter.panelId, this.filter, filterType)
} else {
this.$refs['editChart' + chartItem.type].setData(chartItem, '',
this.filter.panelId, this.filter)
}
} }
} }
} }
}).catch((error) => {
if (error) {
this.$message.error(error.toString())
console.error(error)
}
}) })
}, 100) })
} }
} }
} }
@@ -351,5 +482,18 @@ export default {
max-width: 300px; max-width: 300px;
} }
} }
/deep/ .topology-chart-title{
text-align: left;
width: 100%;
line-height: 20px;
height: 24px;
padding: 5px 10px 0 10px;
box-sizing: border-box;
}
.topology-tool-tip /deep/ .topology-chart-title{
margin-top: -23px;
}
.topology-tool-tip /deep/ .line-area{
margin-top: -15px;
}
</style> </style>

View File

@@ -6,9 +6,9 @@
<div class="project-box list-page" v-loading="topologyLoading" v-has="'topo_list'"> <div class="project-box list-page" v-loading="topologyLoading" v-has="'topo_list'">
<div class="main-list"> <div class="main-list">
<div class="main-container" :class="fromOverView?'from-overview':'from-project'"> <div class="main-container" :class="fromOverView?'from-overview':'from-project'">
<div v-if="editTopologyFlag" class="edit-topologyLine top-tools" style="padding-left: 20px;width: calc(100% - 20px);"> <div v-if="(editTopologyFlag || isPreview)&&!fromChart" class="edit-topologyLine top-tools" style="padding-left: 20px;width: calc(100% - 20px);display: inline-block">
<!--工具栏--> <!--工具栏-->
<span class="project-topology-tool"> <span v-if="!isPreview" class="project-topology-tool">
<el-dropdown trigger="click" size="small" placement="bottom-start" v-has="'topo_icon_list'"> <el-dropdown trigger="click" size="small" placement="bottom-start" v-has="'topo_icon_list'">
<span class="el-dropdown-title"><i class="iconfont icon-cube"></i> <i <span class="el-dropdown-title"><i class="iconfont icon-cube"></i> <i
class="nz-icon nz-icon-arrow-down"></i></span> class="nz-icon nz-icon-arrow-down"></i></span>
@@ -99,10 +99,15 @@
</span> </span>
<span class="float-right"> <span class="float-right">
<button @click="previewTopology" class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new" <button @click="previewTopology" v-if="!isPreview" class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new"
style="margin-right: 20px" style="margin-right: 20px"
> >
{{$t('project.topology.preview')}} {{$t('project.topology.preview')}}
</button>
<button @click="previewExit" v-if="isPreview" class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new"
style="margin-right: 20px"
>
{{$t('project.topology.previewExit')}}
</button> </button>
<button @click="saveTopology" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" <button @click="saveTopology" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new"
:disabled="prevent_opt.save" :disabled="prevent_opt.save"
@@ -115,7 +120,7 @@
</button> </button>
</span> </span>
</div> </div>
<div v-if="!editTopologyFlag&&!fromOverView" class="top-tools" style="padding-left: 10px"> <div v-if="(!editTopologyFlag&&!fromOverView) && !isPreview" class="top-tools" style="padding-left: 10px">
<div>{{topologyInfo.name}}</div> <div>{{topologyInfo.name}}</div>
<div v-if="!editTopologyFlag&&!fromPrev&&!fromOverView" class="top-tool-right"> <div v-if="!editTopologyFlag&&!fromPrev&&!fromOverView" class="top-tool-right">
<pick-time <pick-time
@@ -498,7 +503,9 @@ export default {
unit: '' unit: ''
}, },
unitArr: [], unitArr: [],
topoScreenState: '' // 记录编辑前的 $store.ShowTopoScreen 结束编辑后返回 topoScreenState: '', // 记录编辑前的 $store.ShowTopoScreen 结束编辑后返回
isPreview: false,
previewData: ''
} }
}, },
components: { components: {
@@ -531,6 +538,10 @@ export default {
type: Boolean, type: Boolean,
default: false default: false
}, },
fromChart: {
type: Boolean,
default: false
},
topoPrevDataS: { topoPrevDataS: {
} }
@@ -775,6 +786,9 @@ export default {
} }
this.$get('monitor/project/topo', { projectId: this.obj.id }).then(res => { this.$get('monitor/project/topo', { projectId: this.obj.id }).then(res => {
let data = res.data.topo let data = res.data.topo
if (this.isPreview) {
data = this.previewData
}
// data = JSON.parse(localStorage.getItem('topoData')) // data = JSON.parse(localStorage.getItem('topoData'))
if (!res.data.topo || !data.pens) { if (!res.data.topo || !data.pens) {
data = { data = {
@@ -1840,6 +1854,8 @@ export default {
}, },
// 保存 // 保存
saveTopology () { saveTopology () {
this.previewData = ''
this.isPreview = false
const topologyData = getTopology(this.topologyIndex).pureData() const topologyData = getTopology(this.topologyIndex).pureData()
// console.log(JSON.stringify(topologyData)) // console.log(JSON.stringify(topologyData))
let flag = true let flag = true
@@ -1930,6 +1946,8 @@ export default {
}, },
// 取消 // 取消
cancelTopology () { cancelTopology () {
this.isPreview = false
this.previewData = ''
this.editTopologyFlag = false this.editTopologyFlag = false
this.$nextTick(() => { this.$nextTick(() => {
getTopology(this.topologyIndex).lock(1) getTopology(this.topologyIndex).lock(1)
@@ -1941,14 +1959,46 @@ export default {
}, },
// 预览 // 预览
previewTopology () { previewTopology () {
const data = JSON.parse(JSON.stringify(getTopology(this.topologyIndex).data)) const topologyData = getTopology(this.topologyIndex).pureData()
data.pens.forEach((item) => { this.previewData = topologyData
this.isPreview = true
this.editTopologyFlag = false
topologyData.rule = false
topologyData.grid = false
topologyData.gridSize = 10
topologyData.pens.forEach(item => {
item.animatePlay = item.data.animatePlay item.animatePlay = item.data.animatePlay
item.data.animateType = item.animateType
if (item.type === 0 && JSON.stringify(item.data.imageId)) {
item.image = ''
item.animateFrames = []
item.animateReady = null
delete item.img
delete item.lastImage
}
item.data.expressArr = item.data.expressArr.filter((expression, i) => {
if (!expression) {
item.data.legends.splice(i, 1)
return false
} else {
return true
}
})
}) })
this.topoPrevData = JSON.parse(JSON.stringify(data)) if (this.penToolTipScale == getTopology(this.topologyIndex).data.scale) {
this.topoPrevData.rule = false getTopology(this.topologyIndex).data.scale = this.oldScale
this.topoPrevData.grid = false }
this.previewShow = true this.$nextTick(() => {
this.previewData = topologyData
getTopology(this.topologyIndex).lock(1)
const domRect = document.getElementById('topology-canvas' + this.topologyIndexF).getBoundingClientRect()
getTopology(this.topologyIndex).canvasPos = domRect
this.reload()
})
},
previewExit () { // 继续编辑
this.isPreview = false
this.editTopology()
}, },
// 联动 project // 联动 project

View File

@@ -628,6 +628,11 @@ export default {
if (res.code === 200) { if (res.code === 200) {
res.data.list.forEach((item, index) => { res.data.list.forEach((item, index) => {
const obj = item const obj = item
if (obj.name.length > 64) {
const length = obj.name.length - 64
const lastIndex = obj.name.lastIndexOf('-')
obj.name = obj.name.substring(0, 64 - length) + obj.name.substring(lastIndex)
}
obj.configs = JSON.parse(obj.configs) obj.configs = JSON.parse(obj.configs)
obj.labelModule = [] obj.labelModule = []
if (obj.configs.labels !== '{}' && obj.configs.labels) { if (obj.configs.labels !== '{}' && obj.configs.labels) {

View File

@@ -64,8 +64,7 @@
</el-table-column> </el-table-column>
<el-table-column <el-table-column
:resizable="false" :resizable="false"
:width="operationWidth" :width="operationWidth">
fixed="right">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div> <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items"> <div slot-scope="scope" class="table-operation-items">
<button class="table-operation-item" @click="changeProjectTopo(scope.row)"><i class="nz-icon nz-icon-view1"></i></button> <button class="table-operation-item" @click="changeProjectTopo(scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
@@ -102,32 +101,25 @@ export default {
label: this.$t('project.project.project'), label: this.$t('project.project.project'),
prop: 'name', prop: 'name',
show: true, show: true,
minWidth: 150,
sortable: 'custom' sortable: 'custom'
}, { }, {
label: this.$t('project.module.module'), label: this.$t('project.module.module'),
prop: 'moduleNum', prop: 'moduleNum',
show: true, show: true,
width: 150, width: 100,
sortable: 'custom' sortable: 'custom'
}, { }, {
label: this.$t('project.endpoint.endpoint'), label: this.$t('project.endpoint.endpoint'),
prop: 'endpointNum', prop: 'endpointNum',
show: true, show: true,
width: 150, width: 120,
sortable: 'custom' sortable: 'custom'
}, { }, {
label: this.$t('project.endpoint.alerts'), label: this.$t('project.endpoint.alerts'),
prop: 'alertNum', prop: 'alertNum',
show: true, show: true,
width: 150, width: 100,
sortable: 'custom' sortable: 'custom'
},
{
label: this.$t('overall.remark'),
prop: 'remark',
show: false,
minWidth: 150
} }
] ]
} }

View File

@@ -154,7 +154,7 @@
width: 100vw; width: 100vw;
top: 0; top: 0;
left: 0; left: 0;
z-index: 1; z-index: 11;
} }
.topology-mc{ .topology-mc{
width: 100%; width: 100%;