This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nezha-nezha-fronted/nezha-fronted/src/components/page/dashboard/chartMetric.vue
hanyuxia 0530d0c9cf feat:新增功能
1.panel图表的创建
2.panel图表的展示
3.create+增加了创建panel菜单
2020-01-03 17:17:09 +08:00

419 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<style scoped>
.without-bottom {
margin-bottom: 0;
}
.ivu-select-dropdown {
max-height: 100px;
}
.error-info-text {
position: absolute;
top: 100%;
left: 0;
line-height: 1;
padding-top: 6px;
color: #ed3f14;
white-space: nowrap;
word-wrap: normal;
}
.error-text {
color: #ed3f14;
line-height: 1.5;
}
.nz-btn-style-higher{
line-height: 22px;
}
.li-list-part {
width: 90%;
height: 130px;
border: 1px solid #cfcfcf;
overflow-y: auto;
}
.li-list-part-label-val-list {
width: 100%;
height: 165px;
border: 1px solid #cfcfcf;
overflow-y: auto;
margin-top: -10px;/*21*/
border: 0px;
}
.no-list-style{
list-style: none;
}
.li-cursor{
cursor: pointer;
}
.activeColor {
background-color: #409EFF;
}
.metric-title-label{
margin-bottom:8px;
}
.metric-title-position{
margin-bottom:-5px;
}
.metric-title-row-position{
margin-top:-10px;
}
</style>
<template>
<el-form :model="elementInfo" ref="elementInfo">
<el-row>
<el-col span="16">
{{$t('dashboard.panel.chartForm.metric')}}
</el-col>
<el-col span="8">
<div class="nz-btn-group float-left" v-show="tableShow == 2">
<button @click="clickTabelShow(1,'normal')" class="nz-btn nz-btn-size-small nz-btn-style-light float-left">
<span>{{$t('dashboard.metric.normal')}}</span>
</button>
<button @click="" class="nz-btn nz-btn-size-small nz-btn-disabled nz-btn-style-normal float-left">
<span>{{$t('dashboard.metric.expert')}}</span>
</button>
</div>
<div class="nz-btn-group float-left" v-show="tableShow == 1">
<button @click="" class="nz-btn nz-btn-size-small nz-btn-disabled nz-btn-style-normal float-left">
<span>{{$t('dashboard.metric.normal')}}</span>
</button>
<button @click="clickTabelShow(2,'expert')" class="nz-btn nz-btn-size-small nz-btn-style-light float-left">
<span>{{$t('dashboard.metric.expert')}}</span>
</button>
</div>
</el-col>
</el-row>
<el-row v-show="tableShow == 2">
<el-col span="22">
<el-form-item prop="expression" ><!--expression和metric的验证只能有一个不能同时存在:rules="{ required: true, type: 'string', message: '', trigger: 'change' }"-->
<el-input size="mini" type="textarea" maxlength="1024" show-word-limit v-model="elementInfo.expression" :placeholder="this.$t('dashboard.metric.expertTip')" ></el-input>
</el-form-item>
</el-col>
<el-col span="2">
&nbsp;&nbsp;<button type="button" v-if="countTotal > 1" @click="deleteTarget" class="nz-btn nz-btn-size-normal nz-btn-style-light nz-btn-style-square nz-btn-style-higher"><span class="top-tool-btn-txt"><i class="el-icon-close"></i></span></button>
</el-col>
</el-row>
<el-row v-show="tableShow == 1">
<el-col span="22">
<el-form-item :label-width="80" prop="metric" ><!--:rules="{ required: true, type: 'string', message: '', trigger: 'change' }"-->
<el-select ref="metricSelect" placeholder="" popper-class="" size="small" v-model="elementInfo.metric" @change="selectMetric">
<el-option v-for="(item, index) in metricShowList.arr" :key="item.metric + index"
:value="item.metric">{{item.metric}}</el-option>
</el-select>
<span v-if="metricShowList.text" class="error-info-text">{{metricShowList.text}}</span>
</el-form-item>
</el-col>
<el-col span="2">
&nbsp;&nbsp;<button type="button" v-if="countTotal > 1" @click="deleteTarget" class="nz-btn nz-btn-size-normal nz-btn-style-light nz-btn-style-square nz-btn-style-higher"><span class="top-tool-btn-txt"><i class="el-icon-close"></i></span></button>
</el-col>
</el-row>
<el-row v-if="elementInfo.metric" v-show="tableShow == 1"><!--v-if="elementInfo.tagList.length > 0"-->
<el-col span="12">
<div class="metric-title-label">{{elementInfo.metric}}</div>
<div class="li-list-part">
<ul class="no-list-style">
<li class="li-cursor" v-if="!item.isSelect"
v-for="(item,index) in elementInfo.tagList"
@click="getLidata(index,item)"
:key="index">
<div>
<span >{{ item.name }}</span>
</div>
</li>
</ul>
</div>
</el-col>
<el-col span="12">
<div class="li-list-part-label-val-list" >
<el-form-item class="metric-title-position" v-for="(item, index) in elementInfo.selectedTagList" :key="index" :label="item.name" :label-width="100" :ref="'tagItem' + index" :prop="'tagList.' + index + '.value'" >
<el-row class="metric-title-row-position" >
<!--多选列表 -->
<el-col span="20" >
<el-select v-model="item.value" ref="tagSelect" size="small"
placeholder=""
collapse-tags
multiple>
<el-option v-for="(op, j) in elementInfo.selectedTagList[index].list" :key="op + j" :value="op">{{op}}</el-option>
</el-select>
</el-col>
<el-col span="4" >
&nbsp;&nbsp;<button type="button" @click="deleteMetricLabel(item,index)" class="nz-btn nz-btn-size-normal nz-btn-style-light nz-btn-style-square nz-btn-style-higher"><span class="top-tool-btn-txt"><i class="el-icon-close"></i></span></button>
</el-col>
</el-row>
</el-form-item>
</div>
</el-col>
</el-row>
</el-form>
</template>
<script>
import bus from '../../../libs/bus';
export default {
name: 'chartTag',
props: {
// 序号
pointer: {
type: Number,
default: 0,
},
// metric列表
metricList: {
type: Array,
default: () => [],
},
countTotal: {
type: Number,
default: 1,
},
},
components: {
//multipleSelect
},
data() {
return {
tableShow: 1, // 1.normal; 2.expert
// 指标信息
elementInfo: {
metric: '',//当前选中的metric名称
type:'normal',
// name: '',
tagList: [], // 标签列表
selectedTagList:[],//已选中的标签列表
expression:''
},
metricLoading: false,
keydataList: [], // tag标签键列表
target: null, // 获取到的数据
tagSet: null, // 根据你metric获取的tags信息
setDataFlag: false, // true时为获取数据,编辑状态
vendorCount: '',
};
},
watch: {},
beforeDestroy() {},
methods: {
// 删除该选项,第一步,传递要删除的参数
deleteTarget() {
this.$emit('on-delete-target', this.pointer);
},
// 第二步,on-delete-target回调保存数据
subSave() {
bus.chartAddInfo.metricTarget[this.pointer] = this.elementInfo;
this.$emit('sub-save-ok');
},
// 第三步,将数据重新赋值,sub-save-ok回调
setSubdata(index) {
if (index === this.pointer) {
this.elementInfo.metric = bus.chartAddInfo.metricTarget[this.pointer].metric;
// 当该项metric为空时重置一下
if (!this.elementInfo.metric && this.$refs.metricSelect) {
this.$refs.metricSelect.reset();
}
this.elementInfo.tagList = bus.chartAddInfo.metricTarget[this.pointer].tagList;
}
},
// (最后整体保存添加的图标的时候执行)保存, chartdata点击确认后保存本身数据并返回给chartdata
saveTarget(pointer) {
if (this.pointer === pointer) {
this.$refs.elementInfo.validate((valid) => {
if (valid) {//根据设置的rules进行验证验证通过则返回继续进行保存每个el-form-item都需要验证
this.$emit('on-add-target-success', this.elementInfo, pointer);
}
});
}
},
// 选择metric
selectMetric() {
if (this.elementInfo.metric) {//选择了metric则设置tagList否则设置为空
this.getSuggestTags(this.elementInfo.metric);
} else {
this.elementInfo.tagList = [];
}
},
// 选择主机
/*
selectHost(arr, index) {
this.elementInfo.tagList[index].value = arr;
if (this.$refs.elementInfo && this.$refs[`tagItem${index}`]) {
this.$refs.elementInfo.validateField(`tagList.${index}.value`);
}
},
*/
/*
selectTag(index) {//多选列表改变时的操作:为了* 的操作,此处不需要
const arr = this.elementInfo.tagList[index].value;
if (arr.length > 0 && arr.indexOf('*') > -1) {
this.elementInfo.tagList[index].value = ['*'];
}
},
*/
// 获取tags列表
getSuggestTags(metric) {
this.$get('metric/labelName?metric='+metric).then(response => {
this.elementInfo.selectedTagList = [];
this.elementInfo.tagList = [];
if (response.code === 200) {
if(response.data.list){
//this.elementInfo.tagList = response.data.list;
response.data.list.forEach((item) => {
const tagObj = {
name: item.name,
isSelect:false//当前元素是否被选中,默认都未选中
};
this.elementInfo.tagList.push(tagObj);
});
}else{
response.data.forEach((item) => {
const tagObj = {
name: item.name,
isSelect:false //当前元素是否被选中,默认都未选中
};
this.elementInfo.tagList.push(tagObj);
});
}
//this.elementInfo.tagList = response.data.list;
}else {
this.elementInfo.tagList = [];
}
});
},
getStyles(width) {
return `width: ${width}px;`;
},
filterMethod(value, option) {
return option.toUpperCase().indexOf(value.toUpperCase()) !== -1;
},
// 编辑已有图表状态时,先填充数据
setMdata(data) {
this.setDataFlag = true;
this.target = Object.assign({}, data);
this.elementInfo.metric = data.metric;
this.selectMetric(); // 获取tag
// this.proTags(data.tags);
},
clearHistory() {
this.elementInfo.metric = '';
this.setDataFlag = false;
if (this.$refs.elementInfo) {
this.$refs.elementInfo.resetFields();//???
}
if (this.$refs.metricSelect) {
this.$refs.metricSelect.reset();
}
this.elementInfo.tagList = [];
},
// 获取文本宽度
getWidth(str) {
const sensor = document.createElement('pre');
sensor.innerHTML = str;
sensor.style.display = 'inline-block';
sensor.style.width = 'auto';
sensor.style.visibility = 'hidden';
sensor.style.height = 0;
sensor.style.position = 'relative';
sensor.style['z-index'] = -10;
document.body.appendChild(sensor);
const width = sensor.offsetWidth;
document.body.removeChild(sensor);
const widthL = width > 180 ? width : 180;
return widthL;
},
// 将tag添加到相应框内
proTags(data) {
const dou = data.indexOf(',');
// 只有一组tag
if (dou === -1) {
const set = data.split('=');
const tagValueArr = set[1].indexOf('|') > -1 ? set[1].split('|') : [set[1]];
const tagIndex = this.elementInfo.tagList.findIndex(t => t.name === set[0]);
if (tagIndex > -1) {
this.elementInfo.tagList[tagIndex].value = tagValueArr;
}
} else { // 多组tag
const mid = data.split(','); // ['key=v1','key=v2|v3',....]
mid.forEach((item) => {
const setInner = item.split('=');
const innerValueArr = setInner[1].indexOf('|') > -1 ?
setInner[1].split('|') : [setInner[1]];
const tagIndex = this.elementInfo.tagList.findIndex(t => t.name === setInner[0]);
if (tagIndex > -1) {
this.elementInfo.tagList[tagIndex].value = innerValueArr;
}
});
}
},
//metricLabelName单击事件
getLidata(index, item) {
if(!item.isSelect){
this.vendorCount = index;
//查询metricLabel名称对应的LabelValue
this.$get('metric/labelVal?metric='+this.elementInfo.metric+"&name="+item.name).then(response => {
const tagObj = {
name: item.name,//选中的metricLabel名称
list:[],//metricLabel名称对应的LabelValue
value:[]//最终选择的值
};
//this.elementInfo.selectedTagList = [];
if (response.code === 200) {
if(response.data.list){
response.data.list.forEach((item) => {
tagObj.list.push(item.value)
});
this.elementInfo.selectedTagList.push(tagObj);
}else{
response.data.forEach((item) => {
tagObj.list.push(item.value)
});
this.elementInfo.selectedTagList.push(tagObj);
}
}else {
this.elementInfo.selectedTagList.push(tagObj);
}
});
item.isSelect = true;
}
},
//删除MetricLabel时需要将tagList中的isSelect设置为false并删除elementInfo.selectedTagList里对应的元素
deleteMetricLabel(item,index) {
this.elementInfo.tagList.forEach((tagItem) => {
if(tagItem.name===item.name){
tagItem.isSelect = false;
}
});
this.elementInfo.selectedTagList.splice(index,1);
//this.$emit('on-delete-target', this.pointer);
},
clickTabelShow(val,type){
this.tableShow = val;
this.elementInfo.type = type;
if(val===2){
this.elementInfo.metric='';
}
if(val===1){
this.elementInfo.expression='';
}
}
},
computed: {
metricShowList() {
const obj = {
arr: [...this.metricList],
text: '',
};
return obj;
},
},
mounted() {
bus.$on('clear_history', () => {
this.clearHistory();
});
},
};
</script>