feat: 暂存topo改版

This commit is contained in:
zhangyu
2023-02-20 14:25:09 +08:00
parent 766aadfa66
commit 1d8fcb18ff
15 changed files with 853 additions and 127 deletions

View File

@@ -13,7 +13,7 @@
} }
.form-row-item{ .form-row-item{
vertical-align: top; vertical-align: top;
width: calc(50% - 15px); width: calc(50% - 3px);
display: inline-block; display: inline-block;
box-sizing: border-box; box-sizing: border-box;
padding: 0 5px; padding: 0 5px;
@@ -48,4 +48,14 @@
.form-row-content{ .form-row-content{
margin-bottom: 5px; margin-bottom: 5px;
} }
.right-box__container.pens-data{
overflow: unset;
overflow-y: unset;
}
.right-box__container .chart-config .thresholds-item .mapping-display-input input{
padding-left: 15px;
}
.right-box__container .el-form{
padding-top: 0;
}
} }

View File

@@ -2,32 +2,31 @@ export default {
data () { data () {
return { return {
topoData: {}, topoData: {},
querysArray: {}, querysArray: [],
meta2dType: '', meta2dType: '',
timeType: 1, timeType: 1
} }
}, },
mounted () { watch: {
if (this.meta2dType === 'project') { currentProject: {
setTimeout(() => { handler (n) {
const res = { this.reload()
topo: {}, }
elements: [], },
timeType: 4 chart: {}
},
methods: {
reload () {
this.$get('monitor/project/topo', { projectId: this.currentProject.id }).then(res => {
if (res.data && res.data.topo) {
this.topoData = res.data.topo.topo || {}
this.querysArray = res.data.topo.elements || []
this.timeType = res.data.topo.timeType || 1
} else {
this.topoData = {}
this.querysArray = []
this.timeType = 1
} }
this.topoData = res.topo
this.querysArray = res.elements
})
} else {
setTimeout(() => {
const res = {
topo: {},
elements: [],
timeType: 4
}
this.topoData = res.topo
this.querysArray = res.elements
this.timeType = res.timeType || 1
}) })
} }
} }

View File

@@ -19,7 +19,8 @@ export default {
return { return {
selectPens: [], selectPens: [],
editFlag: false, editFlag: false,
prevFlag: false prevFlag: false,
meta2dLoading: true
} }
}, },
mounted () { mounted () {
@@ -37,7 +38,6 @@ export default {
// meta2d.registerCanvasDraw(chartsPens()) // meta2d.registerCanvasDraw(chartsPens())
/* 画布绑定事件 */ /* 画布绑定事件 */
meta2d.beforeAddPens = (pens) => { // 添加画笔前 meta2d.beforeAddPens = (pens) => { // 添加画笔前
console.log(pens)
if (pens.length === 1) { if (pens.length === 1) {
if (!pens[0].type) { if (!pens[0].type) {
this.nodeInit(pens[0]) this.nodeInit(pens[0])
@@ -57,25 +57,37 @@ export default {
// meta2d.on('add', this.appPen) // 添加新画笔· // meta2d.on('add', this.appPen) // 添加新画笔·
meta2d.on('click', this.topoClick) // click画笔· meta2d.on('click', this.topoClick) // click画笔·
setTopology(this.meta2dId, meta2d) setTopology(this.meta2dId, meta2d)
console.log(getTopology(this.meta2dId)) },
this.clacTopoData(this.topoData).then((data) => { reload () {
console.log(data) const endTime = new Date().getTime()
meta2d.open(data) const startTime = endTime - 60 * 5 * 1000
meta2d.centerView() this.getQueryValues(this.querysArray, startTime, endTime).then((arr) => {
meta2d.lock(1) this.clacTopoData(this.topoData, arr).then((data) => {
console.log(data)
getTopology(this.meta2dId).resize()
getTopology(this.meta2dId).open(data)
getTopology(this.meta2dId).centerView()
getTopology(this.meta2dId).lock(1)
})
}) })
}, },
clacTopoData (data) { // 主要处理 属性为原始属性 处理动画属性对原始属性的影响 clacTopoData (data, queryValues) { // 主要处理 属性为原始属性 处理动画属性对原始属性的影响
return new Promise(resolve => { return new Promise(resolve => {
if (!data.pens) { if (!data.pens) {
data.pens = [] data.pens = []
} }
data.pens.forEach(pen => {
if (pen.isNz) {
if (pen.data.legend) {
}
} else {
// 处理加载数据
}
})
resolve(data) resolve(data)
}) })
}, },
calcNode (node) { // 处理节点数据
node = { ...node, ...node.data.params }
},
nodeInit (pen) { // 初始化节点参数 nodeInit (pen) { // 初始化节点参数
pen.data = { pen.data = {
params: { // 用于编辑时 重置为节点初始状态 params: { // 用于编辑时 重置为节点初始状态
@@ -87,7 +99,7 @@ export default {
imageId: '', imageId: '',
valueMapping: [], valueMapping: [],
legend: '', legend: '',
statistics: '', statistic: '',
enable: { enable: {
valueMapping: true, valueMapping: true,
tooltip: true tooltip: true
@@ -100,6 +112,7 @@ export default {
legends: [] // {legend: '' , alias} legends: [] // {legend: '' , alias}
} }
} }
pen.isNz = true
pen.background = '#22222200' pen.background = '#22222200'
pen.textAlign = 'center' pen.textAlign = 'center'
pen.textBaseline = 'middle' pen.textBaseline = 'middle'
@@ -115,7 +128,10 @@ export default {
pen.lineWidth = 1 pen.lineWidth = 1
pen.lineDash = [] pen.lineDash = []
pen.borderRadius = 0 pen.borderRadius = 0
console.log(pen) pen.paddingTop = 5
pen.paddingBottom = 5
pen.paddingLeft = 5
pen.paddingRight = 5
}, },
lineInit (pen) { // 初始化连线参数 lineInit (pen) { // 初始化连线参数
pen.data = { pen.data = {
@@ -123,8 +139,16 @@ export default {
animateColor: '#FA901CFF', animateColor: '#FA901CFF',
borderColor: '#22222200', borderColor: '#22222200',
color: '#222222FF' color: '#222222FF'
} },
valueMapping: [],
legend: '',
statistic: '',
enable: {
valueMapping: true,
tooltip: true
},
} }
pen.disableInput = true
pen.lineAnimateType = 0 pen.lineAnimateType = 0
pen.animateSpan = 1 pen.animateSpan = 1
pen.animateReverse = false pen.animateReverse = false
@@ -137,13 +161,12 @@ export default {
pen.borderType = 0 pen.borderType = 0
pen.lineWidth = 1 pen.lineWidth = 1
pen.lineDash = [] pen.lineDash = []
pen.isNz = true
}, },
pensActive (pens, e) { // 选中节点 pensActive (pens, e) { // 选中节点
console.log(pens, 'active', e)
this.selectPens = pens this.selectPens = pens
}, },
topoClick (params, e) { // 点击节点 topoClick (params, e) { // 点击节点
console.log(this.$refs.meta2dProps)
if (!params.pen && this.$refs.meta2dProps) { if (!params.pen && this.$refs.meta2dProps) {
this.$refs.meta2dProps.activeName = 'canvas' this.$refs.meta2dProps.activeName = 'canvas'
this.selectPens = [] this.selectPens = []
@@ -156,7 +179,6 @@ export default {
// console.log(pens) // console.log(pens)
}, },
updatePens (pen, key) { // 更新对应的节点 updatePens (pen, key) { // 更新对应的节点
console.log(pen, key, 'update')
// meta2d.setValue({ id: pen.id, text: 'new text' }, { render: false }); // meta2d.setValue({ id: pen.id, text: 'new text' }, { render: false });
const obj = { id: pen.id } const obj = { id: pen.id }
obj[key] = pen[key] obj[key] = pen[key]
@@ -165,13 +187,18 @@ export default {
} }
getTopology(this.meta2dId).setValue(obj) getTopology(this.meta2dId).setValue(obj)
if (key === 'lineAnimateType') { if (key === 'lineAnimateType') {
console.log('lineAnimateType', 'start')
if (!pen[key]) { if (!pen[key]) {
getTopology(this.meta2dId).stopAnimate(pen.id) getTopology(this.meta2dId).stopAnimate(pen.id)
return return
} }
getTopology(this.meta2dId).startAnimate(pen.id) getTopology(this.meta2dId).startAnimate(pen.id)
} }
},
exitEdit (isRefresh) {
this.editFlag = false
if (isRefresh) {
this.$emit('reload')
}
} }
} }
} }

View File

@@ -0,0 +1,27 @@
const meta2dStore = {
state: {
queryValues: []
},
mutations: {
setQueryValues (state, arr) {
state.queryValues = arr
},
delQueryValues (state, obj) {
delete state.queryValues[obj.key]
}
},
getters: {
getQueryValues (state) {
return state.queryValues
}
},
actions: {
dispatchSetQueryValues (store, arr) {
store.commit('setQueryValues', arr)
},
dispatchDelQueryValues (store, arr) {
store.commit('delQueryValues', arr)
}
}
}
export default meta2dStore

View File

@@ -1,14 +1,134 @@
import { getTopology, setTopology, dealImg, topologyImg } from '@/components/common/js/common' import { getTopology, setTopology, dealImg, topologyImg } from '@/components/common/js/common'
import bus from '@/libs/bus'
import axios from 'axios'
export default { export default {
methods: { methods: {
topoResize (id) { topoResize (id) {
getTopology(id).resize() getTopology(id).resize()
}, },
initEdit (id) { initEdit (id) {
console.log(getTopology(id))
getTopology(id).lock(0) getTopology(id).lock(0)
getTopology(id).centerView()
getTopology(id).stopAnimate(getTopology(id).data.pens) getTopology(id).stopAnimate(getTopology(id).data.pens)
console.log(getTopology(id).data.pens)
if (getTopology(id).data.pens) {
getTopology(id).data.pens.forEach(item => {
this.calcNode(item)
})
}
getTopology(id).render()
getTopology(id).centerView()
},
calcNode (node) { // 处理节点数据
node = { ...node, ...node.data.params }
getTopology(this.meta2dId)._setValue(node)
},
getQueryValues (elements, startTime, endTime) {
this.meta2dLoading = true
return new Promise(resolve => {
const step = bus.getStep(startTime, endTime)
endTime = parseInt(endTime / 1000)
startTime = parseInt(startTime / 1000)
const urlPre = '/prom'
console.log(endTime, startTime)
elements = elements.filter(item => item.state && item.expression)
const requests = elements.map((element) => {
// query_range
let query = `${urlPre}/api/v1/query_range?start=${startTime}&end=${endTime}&step=${step}`
query += `&nullType=${'null'}`
if (element.filter) {
query += `&filter=${element.filter}`
}
query += `&query=${encodeURIComponent(element.expression)}`
return this.$get(query)
})
axios.all(requests).then((res) => {
console.log(res)
const arr = []
res.forEach((request, index) => {
arr.push({
type: 'title',
name: elements[index].name
})
if (request.code === 200 && request.status === 'success') {
request.data.result.forEach((r, rindex) => {
let legend = ''
if (!r.metric) {
r.metric = {}
}
if (r.metric.__name__) {
legend += `${r.metric.__name__}{`
}
const tagKeysArr = Object.keys(r.metric)
tagKeysArr.forEach(tagKey => {
if (tagKey !== '__name__' && tagKey !== 'legend' && tagKey !== 'values' && tagKey !== '$value') {
legend += `${tagKey}="${r.metric[tagKey]}",`
}
})
if (legend.endsWith(',')) {
legend = legend.substr(0, legend.length - 1)
}
if (r.metric.__name__) {
legend += '}'
}
if (!legend && elements) {
legend = elements[index].expression
}
const obj = {
type: 'item',
id: rindex + elements[index].name + JSON.stringify(r.metric),
name: this.handleLegendAlias(legend, elements[index].legend, r.metric),
values: r.values
}
arr.push(obj)
})
}
})
this.meta2dLoading = false
this.$store.dispatch('dispatchSetQueryValues', arr)
resolve(arr)
})
})
},
handleLegendAlias (legend, aliasExpression, params) {
const self = this
const myParams = JSON.parse(JSON.stringify(params))
myParams.$labels = JSON.parse(JSON.stringify(params))
myParams.$value = myParams.value
if (/\{\{.+\}\}/.test(aliasExpression)) {
const labelValue = aliasExpression.replace(/(\{\{.+?\}\})/g, function (i) {
const label = i.substr(i.indexOf('{{') + 2, i.indexOf('}}') - i.indexOf('{{') - 2)
if (!legend) {
return label
}
let value = null
if (params && self.$loadsh.get(myParams, label)) {
value = self.$loadsh.get(myParams, label)
}
if (label) {
const reg = new RegExp(label + '=".+?"', 'g')
if (reg.test(legend)) {
const ans = legend.match(reg)
let find = ''
ans.forEach(item => {
const index = legend.indexOf(item)
if (legend[index - 1] !== '_') {
find = item
}
})
value = find.substr(find.indexOf('"') + 1, find.lastIndexOf('"') - find.indexOf('"') - 1)
}
}
return value || ''
})
return labelValue
} else {
if (!aliasExpression) {
return legend
// let result =legend.substr(legend.indexOf('"') + 1,legend.lastIndexOf('"') - legend.indexOf('"') - 1);
// return result
}
return aliasExpression
}
} }
} }
} }

View File

@@ -1,12 +1,76 @@
<template> <template>
<div> <div class="pens-data">
canvas <div class="form-row-box">
<!-- backGround -->
<div class="form-row-title">
BackGround
<i class="nz-icon nz-icon-arrow-down" @click="updateShow('backGround')"/>
</div>
<div v-show="canvasProps.backGround" class="form-row-content">
</div>
<div class="form-row-title">
Elements
</div>
<div class="form-row-content">
<div class="form-row-item form-row-item-full">
<draggable
v-model="elements"
:scroll-sensitivity="150"
:options="{
dragClass:'drag-valueMapping-class',
fallbackClass:'fallback-class',
forceFallback:true,
ghostClass:'chart-ghost',
chosenClass:'choose-class',
scroll:true,
animation: 150,
}">
<div v-for="item in elements" :key="item.id">
<div class="pen-tools" style="background: #999;margin-bottom: 10px;border-radius: 2px;display: flex;justify-content: space-between;padding: 3px 10px" @click="penActive(item)">
<i v-if="item.type !== 1" class="nz-icon nz-icon-zhengfangxing" />
<i v-else class="nz-icon nz-icon-compare" />
<span>
123123123
</span>
</div>
</div>
</draggable>
</div>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import { getTopology } from '@/components/common/js/common'
import draggable from 'vuedraggable'
export default { export default {
name: 'meta2dCanvas' name: 'meta2dCanvas',
props: {
canvasProps: {},
meta2dId: {}
},
components: {
draggable
},
data () {
return {
elements: []
}
},
mounted () {
this.elements = getTopology(this.meta2dId).store.data.pens
},
methods: {
updateShow (key) {
this.canvasProps[key] = !this.canvasProps[key]
},
penActive (item) {
console.log(item.id)
getTopology(this.meta2dId).active(item)
}
}
} }
</script> </script>

View File

@@ -138,6 +138,10 @@ const rz = {
export default { export default {
name: 'meta2dData', name: 'meta2dData',
mixins: [promqlInputMixin, rz], mixins: [promqlInputMixin, rz],
props: {
querysArray: {},
timeType: {}
},
components: { components: {
draggable, draggable,
promqlInput promqlInput
@@ -197,11 +201,6 @@ export default {
} else if (!this.expressionName[index]) { } else if (!this.expressionName[index]) {
this.expressionName[index] = this.expressionsShow[index].oldName this.expressionName[index] = this.expressionsShow[index].oldName
} else { } else {
this.param.rightYAxis && this.param.rightYAxis.elementNames.forEach((item, index) => {
if (item == this.expressionsShow[index].oldName) {
this.param.rightYAxis.elementNames[index] = this.expressionName[index]
}
})
this.expressionsShow[index].oldName = this.expressionName[index] this.expressionsShow[index].oldName = this.expressionName[index]
} }
this.expressionChange() this.expressionChange()
@@ -293,12 +292,6 @@ export default {
}, },
removeExpression (index) { removeExpression (index) {
if (this.expressionsShow.length > 1) { if (this.expressionsShow.length > 1) {
this.param.rightYAxis && this.param.rightYAxis.elementNames.forEach((elementName, subIndex) => {
if (elementName == this.expressionName[index]) {
this.param.rightYAxis.elementNames.splice(subIndex, 1)
}
})
this.expressions.splice(index, 1) this.expressions.splice(index, 1)
this.expressionName.splice(index, 1) this.expressionName.splice(index, 1)
this.expressionsShow.splice(index, 1) this.expressionsShow.splice(index, 1)
@@ -330,10 +323,6 @@ export default {
showError () { showError () {
}, },
hideError (key, index) { hideError (key, index) {
if (!this.param[key] || !this.param[key].length) {
return
}
this.param[key][index].error = false
this.$forceUpdate() this.$forceUpdate()
}, },
move () { move () {
@@ -373,6 +362,8 @@ export default {
this.expressions = [] this.expressions = []
this.expressionsShow = [] this.expressionsShow = []
this.expressionName = [] this.expressionName = []
this.elements = this.$loadsh.cloneDeep(this.querysArray)
this.dataTimeType = this.timeType
if (!this.elements.length) { if (!this.elements.length) {
this.addExpression() this.addExpression()
} else { } else {

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="pens-data"> <div class="pens-data right-box__container">
<div v-if="pen.id"> <div v-if="pen.id">
<!-- <el-input-number v-model="pen.x" @change="change('x')"/>--> <!-- <el-input-number v-model="pen.x" @change="change('x')"/>-->
<!-- node--> <!-- node-->
@@ -256,7 +256,8 @@
Image Image
</div> </div>
<div class="form-row-value"> <div class="form-row-value">
<el-input v-model="pen.image" size="small" @change="change('image')"/> <!-- <el-input v-model="pen.image" size="small" @change="change('image')"/>-->
<meta2dSelectImage :selectImage="pen.image" @updateImage="updateImage"/>
</div> </div>
</div> </div>
<div class="form-row-item"> <div class="form-row-item">
@@ -350,44 +351,6 @@
</div> </div>
</div> </div>
</div> </div>
<!-- valueMapping -->
<div class="form-row-title">
Value mappings
<i class="nz-icon nz-icon-arrow-down" @click="updateShow('valueMapping')"/>
</div>
<div v-show="elements.valueMapping" class="form-row-content">
<div class="form-row-item">
<div class="form-row-key">
color
</div>
<div class="form-row-value">
<nezhaColor
:isTopo="true"
:value-arr="[{name:'background',value: pen.background}]"
@colorChange="colorChange"/>
</div>
</div>
</div>
<!-- tooltip -->
<div class="form-row-title">
tooltip
<i class="nz-icon nz-icon-arrow-down" @click="updateShow('tooltip')"/>
</div>
<div v-show="elements.tooltip" class="form-row-content">
<div class="form-row-item">
<div class="form-row-key">
color
</div>
<div class="form-row-value">
<nezhaColor
:isTopo="true"
:value-arr="[{name:'background',value: pen.background}]"
@colorChange="colorChange"/>
</div>
</div>
</div>
</div> </div>
</div> </div>
<!-- line--> <!-- line-->
@@ -699,16 +662,265 @@
</div> </div>
</div> </div>
</div> </div>
<!-- valueMapping -->
<div class="form-row-title">
Value mappings
<span>
<el-switch
v-model="pen.data.enable.valueMapping"
:active-value="true"
:inactive-value="false"
@change="change('data.enable.valueMapping')"
></el-switch>
<i class="nz-icon nz-icon-arrow-down" @click="updateShow('valueMapping')"/>
</span>
</div>
<transition name="el-zoom-in-top">
<div class="el-form" v-show="elements.valueMapping">
<div class="form-row-content">
<div class="form-row-item">
<div class="form-row-key">
Legend
</div>
<div class="form-row-value">
<el-select v-model="pen.data.legend" size="small">
<el-option v-for="item in queryValues" :key="item.id" :value="item.id" :label='item.name'></el-option>
</el-select>
</div>
</div>
<div class="form-row-item">
<div class="form-row-key">
Statistics
</div>
<div class="form-row-value">
<el-select v-model="pen.data.statistic" size="small">
<el-option v-for="item in statisticsList" :key="item.value" :value="item.value" :label='item.label'></el-option>
</el-select>
</div>
</div>
<div class="form-row-item form-row-item-full chart-config">
<el-row class="el-form">
<draggable
v-model="pen.data.valueMapping"
@end="change"
:scroll-sensitivity="150"
:options="{
dragClass:'drag-valueMapping-class',
fallbackClass:'fallback-class',
forceFallback:true,
ghostClass:'chart-ghost',
chosenClass:'choose-class',
scroll:true,
filter: '.drag-disabled',
animation: 150,
handle: '.drag-sort'
}">
<div
v-for="(item,index) in pen.data.valueMapping"
:key="item.uid"
:class="item.error? 'is-item-box-error' : ''"
>
<div class="chart-title chart-title-config">
<span class="chart-title-content">
<i class="nz-icon nz-icon-arrow-down" :class="item.show?'':'is-active'" @click="showMapping(index)"></i>
<span v-if="item.column && !item.show">{{item.column}}:</span>
<span v-show="!item.show" class="title-content-left">
<span v-if="item.type === 'value'">
{{item.value}}
</span>
<span v-if="item.type === 'range'">
[{{item.from}}{{item.to}})
</span>
<span v-if="item.type === 'regx'">
{{item.regx}}
</span>
<div class="prev-mapping-icon">
<i :class="item.icon" :style="{ color: item.color.icon }"></i>
</div>
<div :style="{background:item.color.bac}" class="prev-mapping-box">
<span :style="{color:item.color.text}">
{{item.display || "T"}}
</span>
</div>
</span>
</span>
<span>
<span @click="addMapping('')" style="margin-right: 5px" :title="$t('tip.add')">
<i class="nz-icon nz-icon-create-square"></i>
</span>
<span @click="copyMapping(index)" style="margin-right: 5px" :title="$t('overall.duplicate')">
<i class="nz-icon nz-icon-override"></i>
</span>
<span @click="removeMapping(index)" style="margin-right: 5px" :title="$t('overall.delete')">
<i class="nz-icon nz-icon-minus"></i>
</span>
<span style="margin-right: 5px;fontSize:17px;cursor: grab;" class="drag-sort" :title="$t('dashboard.panel.chartForm.sort')">
<i class="nz-icon nz-icon-sort" style="cursor: grab;"></i>
</span>
</span>
</div>
<transition-group appear tag="div" name="el-zoom-in-top">
<el-row
v-show="item.show"
:key="1"
class="thresholds-item"
>
<div>
<el-select
v-model="item.type"
size="small"
style="width: 100px"
@change="(val)=>{mappingItemChange(index,val)}"
>
<el-option
v-for="item in mappingTypeList"
:value="item.value"
:label="$t(item.label)"
:key="item.value"/>
</el-select>
</div>
<div
v-if="item.type === 'value'"
:prop="'param.valueMapping.' + index + '.value'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item"
style="display: flex"
key="value"
>
<el-input-number
:controls="false"
size="small"
v-model.number="item.value"
placeholder="value"
@change="change('valueMapping', index)"
></el-input-number>
</div>
<div
v-if="item.type === 'range'"
:prop="'param.valueMapping.' + index + '.from'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item"
key="from"
>
<el-input-number
:controls="false"
size="small"
v-model.number="item.from"
placeholder="from"
@change="change('valueMapping', index)"
></el-input-number>
</div>
<div
v-if="item.type === 'range'"
:prop="'param.valueMapping.' + index + '.to'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item"
key="to"
>
<el-input-number
:controls="false"
size="small"
v-model.number="item.to"
@change="change('valueMapping', index)"
placeholder="to"
></el-input-number>
</div>
<div
v-if="item.type === 'regx'"
:prop="'param.valueMapping.' + index + '.regx'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item"
key="regx"
>
<el-input
size="small"
v-model="item.regx"
placeholder="regx"
@change="change('valueMapping', index)"
></el-input>
</div>
</el-row>
<el-row v-show="item.show" :key="2" class="thresholds-item">
<div>
<div class='mapping-display'>{{$t('config.assetLabel.display')}}</div>
</div>
<div :prop="'param.valueMapping.' + index + '.display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}" class="thresholds-from-item">
<el-input v-model="item.display" style="margin-right: 10px" :placeholder="$t('placeholder.chart.display')" size="small" @change="change('valueMapping', index)" class="mapping-display-input">
<!-- <el-dropdown trigger="click" slot="prefix" placement="top-start">-->
<!-- <div class="el-dropdown-link">-->
<!-- <i v-if="item.icon" class="mapping-icon" :class="item.icon" :style="{ color: item.color.icon }"></i>-->
<!-- <div v-else class="mapping-iconSelect" :title="$t('tip.add')">-->
<!-- <i class="nz-icon nz-icon-create-square"></i>-->
<!-- </div>-->
<!-- </div>-->
<!-- <el-dropdown-menu slot="dropdown" class="mapping-iconPop">-->
<!-- <ul class="mapping-iconList">-->
<!-- <li class="mapping-iconItem" :class="{active:item.icon===subItem.value}" v-for="subItem in mappingIconList" @click="iconActive(item,subItem,index)" :key="subItem.value">-->
<!-- <i :class="subItem.value"></i>-->
<!-- </li>-->
<!-- </ul>-->
<!-- </el-dropdown-menu>-->
<!-- </el-dropdown>-->
</el-input>
</div>
<nezhaColor
:color-val="item.color"
:single="false"
:value-arr="[{name:'bac',value:item.color.bac,key:'bac'},{name:'text',value:item.color.text,key:'text'},{name:'border',value:item.color.icon,key:'icon'}]"
@colorChange="(val,key)=>{valueMappingColorChange(val, key, index)}"
/>
</el-row>
</transition-group>
</div>
</draggable>
<div @click="addMapping" class="thresholds-add">
{{$t('overall.addMapping')}}
</div>
</el-row>
</div>
</div>
</div>
</transition>
<!-- tooltip -->
<div class="form-row-title" v-if="pen.type !== 1">
tooltip
<i class="nz-icon nz-icon-arrow-down" @click="updateShow('tooltip')"/>
</div>
<div v-show="elements.tooltip" class="form-row-content" v-if="pen.type !== 1">
<div class="form-row-item">
<div class="form-row-key">
color
</div>
<div class="form-row-value">
<nezhaColor
:isTopo="true"
:value-arr="[{name:'background',value: pen.background}]"
@colorChange="colorChange"/>
</div>
</div>
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import nezhaColor from '@/components/common/nezhaColor' import nezhaColor from '@/components/common/nezhaColor'
import meta2dSelectImage from '@/components/common/project/meta2d/meta2dSelectImage'
import { imageTemp } from '@/components/common/project/L5/services/canvas'
import { dealImg, getUUID, topologyImg } from '@/components/common/js/common'
import imgDefault from '@/components/common/project/L5/services/img'
import { ColorReverse, randomcolor } from '@/components/common/js/radomcolor/randomcolor'
import lodash from 'lodash'
import draggable from 'vuedraggable'
export default { export default {
name: 'meta2dElement', // node 和 line 所有组件均是分开创建的 修改相同属性时 需要同时修改 name: 'meta2dElement', // node 和 line 所有组件均是分开创建的 修改相同属性时 需要同时修改
components: { components: {
nezhaColor nezhaColor,
meta2dSelectImage,
draggable
}, },
props: { props: {
selectPens: {}, selectPens: {},
@@ -718,13 +930,17 @@ export default {
selectPens: { selectPens: {
immediate: true, immediate: true,
handler (n) { handler (n) {
console.log(n, 'selectPens')
this.pen = n[0] this.pen = n[0]
// todo 判断legend 是否还存在 // todo 判断legend 是否还存在
// this.$forceUpdate() // this.$forceUpdate()
} }
} }
}, },
computed: {
queryValues () {
return this.$store.getters.getQueryValues
}
},
data () { data () {
const theme = localStorage.getItem(`nz-user-${localStorage.getItem('nz-user-id')}-theme`) || 'light' const theme = localStorage.getItem(`nz-user-${localStorage.getItem('nz-user-id')}-theme`) || 'light'
return { return {
@@ -812,7 +1028,7 @@ export default {
r: '5', r: '5',
name: 'circle', name: 'circle',
strokeColor: theme == 'light' ? 'black' : '#BEBEBE' strokeColor: theme == 'light' ? 'black' : '#BEBEBE'
}, }
], ],
lineAnimateOptions: [ lineAnimateOptions: [
{ id: 3, name: this.$t('project.topology.flow') }, { id: 3, name: this.$t('project.topology.flow') },
@@ -821,8 +1037,23 @@ export default {
// { id: 'comet', name: this.$t('project.topology.comet') }, // { id: 'comet', name: this.$t('project.topology.comet') },
{ id: 0, name: this.$t('project.topology.none') } { id: 0, name: this.$t('project.topology.none') }
], ],
statisticsList: this.$CONSTANTS.statisticsList,
mappingTypeList: [
{
label: this.$t('overall.value'),
value: 'value'
}, {
label: this.$t('dashboard.panel.chartForm.valMapping.range'),
value: 'range'
}, {
label: this.$t('dashboard.panel.chartForm.valMapping.regx'),
value: 'regx'
}
]
} }
}, },
mounted () {
},
methods: { methods: {
change (key) { change (key) {
if (key === 'lineDash') { if (key === 'lineDash') {
@@ -831,12 +1062,33 @@ export default {
} }
this.$emit('change', key) this.$emit('change', key)
}, },
updateImage (image) {
this.pen.image = image.image
this.pen.imageId = image.id
this.change('image')
},
colorChange (val, key) { colorChange (val, key) {
this.pen.data.params[key] = val this.pen.data.params[key] = val
this.pen[key] = val this.pen[key] = val
console.log(key, val)
this.change(key) this.change(key)
}, },
valueMappingColorChange (val, key, index) {
if (key === 'thresholds') {
this.pen.data.thresholds[index].color = val
}
if (key === 'bac') {
this.pen.data.valueMapping[index].color.bac = val
this.$set(this.pen.data.valueMapping, index, this.pen.data.valueMapping[index])
}
if (key === 'text') {
this.pen.data.valueMapping[index].color.text = val
this.$set(this.pen.data.valueMapping, index, this.pen.data.valueMapping[index])
}
if (key === 'icon') {
this.pen.data.valueMapping[index].color.icon = val
this.$set(this.pen.data.valueMapping, index, this.pen.data.valueMapping[index])
}
},
updateShow (key) { updateShow (key) {
this.elements[key] = !this.elements[key] this.elements[key] = !this.elements[key]
}, },
@@ -845,7 +1097,58 @@ export default {
e.path[2].children[1].setAttribute('tabindex', '1') e.path[2].children[1].setAttribute('tabindex', '1')
}, },
inputBlur (e) { inputBlur (e) {
},
addMapping () {
const bacColor = randomcolor()
const obj = {
type: 'value',
show: true,
value: undefined,
display: '',
color: {
bac: bacColor + 'FF',
text: ColorReverse(bacColor) + 'FF',
border: randomcolor() + 'FF'
},
uid: getUUID()
}
this.pen.data.valueMapping.push(obj)
},
copyMapping (index) {
const temp = lodash.cloneDeep(this.pen.data.valueMapping[index])
temp.uid = getUUID()
this.pen.data.valueMapping.push(temp)
},
removeMapping (index) {
this.pen.data.valueMapping.splice(index, 1)
},
showMapping (index) {
this.pen.data.valueMapping[index].show = !this.pen.data.valueMapping[index].show
},
mappingItemChange (index, type) {
const mapping = this.pen.data.valueMapping[index]
if (mapping.type === 'value') {
this.pen.data.valueMapping[index] = {
...mapping,
value: undefined
}
}
if (mapping.type === 'range') {
this.pen.data.valueMapping[index] = {
...mapping,
from: undefined,
to: undefined
}
}
if (mapping.type === 'regx') {
this.pen.data.valueMapping[index] = {
...mapping,
regx: ''
}
}
this.$set(this.pen.data.valueMapping, index, this.pen.data.valueMapping[index])
} }
} }
} }
</script> </script>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="topo-header"> <div class="topo-header">
<div v-if="!isChart"> {{projectName}} </div> <div v-if="!isChart"> {{project && project.name}} </div>
<div class="tools-left"> <div class="tools-left">
<div class="tools-left-drag"> <div class="tools-left-drag">
<div <div
@@ -20,6 +20,9 @@
<button v-has="'project_edit'" v-if="!isChart" class="top-tool-btn margin-r-10" type="button" @click="editMeta2d" :title="$t('overall.edit')"> <button v-has="'project_edit'" v-if="!isChart" class="top-tool-btn margin-r-10" type="button" @click="editMeta2d" :title="$t('overall.edit')">
<i class="nz-icon nz-icon-edit"></i> <i class="nz-icon nz-icon-edit"></i>
</button> </button>
<button v-has="'project_edit'" v-if="!isChart" class="top-tool-btn margin-r-10" type="button" @click="saveMeta2d" :title="$t('overall.edit')">
save
</button>
</div> </div>
</div> </div>
</template> </template>
@@ -37,7 +40,7 @@ export default {
type: Boolean, type: Boolean,
default: false default: false
}, },
projectName: {} project: {}
}, },
data () { data () {
return { return {
@@ -54,14 +57,12 @@ export default {
}, },
methods: { methods: {
editMeta2d () { editMeta2d () {
console.log()
this.topoScreenState = JSON.parse(JSON.stringify(this.topoScreen)) this.topoScreenState = JSON.parse(JSON.stringify(this.topoScreen))
this.$store.commit('setShowTopoScreen', true) this.$store.commit('setShowTopoScreen', true)
setTimeout(() => { setTimeout(() => {
this.topoResize(this.meta2dId) this.topoResize(this.meta2dId)
this.initEdit(this.meta2dId) this.initEdit(this.meta2dId)
this.$emit('edit') this.$emit('edit')
console.log(getTopology(this.meta2dId).data())
}) })
}, },
onDragstart (e) { onDragstart (e) {
@@ -86,8 +87,48 @@ export default {
}, },
// 开启钢笔状态 // 开启钢笔状态
setDrawPen () { setDrawPen () {
console.log(123123123123)
getTopology(this.meta2dId).drawLine('line') getTopology(this.meta2dId).drawLine('line')
},
saveMeta2d () {
if (this.isChart) {
this.saveChart()
} else {
this.saveProject()
}
},
saveChart () {
},
saveProject () {
const elements = this.$parent.$refs.meta2dProps.$refs.meta2dData.elements
console.log(elements)
const params = {
topo: getTopology(this.meta2dId).data(),
elements: elements,
timeType: ''
}
this.$put('monitor/project/topo', { topo: JSON.stringify(params), projectId: this.project.id }).then(res => {
this.prevent_opt.save = false
if (res.code === 200) {
this.$message({
message: this.$t('tip.saveSuccess'),
type: 'success'
})
this.$store.commit('setShowTopoScreen', this.topoScreenState)
this.$nextTick(() => {
getTopology(this.meta2dId).lock(1)
getTopology(this.meta2dId).resize()
})
this.$emit('exitEdit', true)
}
}).catch(res => {
this.prevent_opt.save = false
this.$message({
message: res.msg,
type: 'error'
})
})
} }
} }
} }

View File

@@ -1,10 +1,18 @@
<template> <template>
<div class="meta2d-box"> <div class="meta2d-box" v-my-loading="meta2dLoading">
<meta2dHeader :meta2dId="meta2dId" :isChart="isChart" :projectName="projectName" @edit="editFlag = true"/> <meta2dHeader :meta2dId="meta2dId" :isChart="isChart" :project="project" @edit="editFlag = true" @exitEdit="exitEdit"/>
<div class="meta2d-main" :class="isChart ? 'meta2d-chart': 'meta2d-project'"> <div class="meta2d-main" :class="isChart ? 'meta2d-chart': 'meta2d-project'">
<div :id="meta2dId" style="height: 100%;width: 100%"></div> <div :id="meta2dId" style="height: 100%;width: 100%"></div>
</div> </div>
<meta2dProps ref="meta2dProps" :selectPens.sync="selectPens" :querysArray="querysArray" :timeType="timeType" @updatePens="updatePens" v-if="editFlag"/> <meta2dProps
v-if="editFlag"
ref="meta2dProps"
:selectPens.sync="selectPens"
:querysArray="querysArray"
:timeType="timeType"
:meta2dId="meta2dId"
@updatePens="updatePens"
/>
</div> </div>
</template> </template>
@@ -13,9 +21,10 @@ import meta2dHeader from '@/components/common/project/meta2d/meta2dHeader'
import meta2dProps from '@/components/common/project/meta2d/meta2dProps' import meta2dProps from '@/components/common/project/meta2d/meta2dProps'
import meta2dMain from '@/components/common/project/meta2d/js/meta2dMain' import meta2dMain from '@/components/common/project/meta2d/js/meta2dMain'
import { getTopology, setTopology } from '@/components/common/js/common' import { getTopology, setTopology } from '@/components/common/js/common'
import topoUtil from '@/components/common/project/meta2d/js/topoUtil'
export default { export default {
name: 'meta2dMain', name: 'meta2dMain',
mixins: [meta2dMain], mixins: [meta2dMain, topoUtil],
props: { props: {
meta2dId: {}, // 唯一id 不可重复 meta2dId: {}, // 唯一id 不可重复
topoData: {}, // topo图数据 topoData: {}, // topo图数据
@@ -25,7 +34,7 @@ export default {
}, },
querysArray: {}, querysArray: {},
timeType: {}, timeType: {},
projectName: {} project: {}
}, },
components: { components: {
meta2dHeader, meta2dHeader,
@@ -35,6 +44,7 @@ export default {
topoData: { topoData: {
immediate: true, immediate: true,
handler () { handler () {
this.reload()
} }
} }
}, },

View File

@@ -1,14 +1,14 @@
<template> <template>
<div class="props-box props"> <div class="props-box props" @keypress.stop="" @keydown.stop="" @keyup.stop="">
<el-tabs v-model="activeName" type="card"> <el-tabs v-model="activeName" type="card" :before-leave="beforeLeave">
<el-tab-pane label="elements" name="elements" v-if="selectPens.length === 1"> <el-tab-pane label="elements" name="elements" v-if="selectPens.length === 1">
<meta2dElement :selectPens.sync="selectPens" @change="change" :elements="elements"/> <meta2dElement :selectPens.sync="selectPens" @change="change" :elements="elements"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="canvas" name="canvas"> <el-tab-pane label="canvas" name="canvas">
<meta2dCanvas /> <meta2dCanvas :canvasProps="canvasProps" :meta2dId='meta2dId' ref ='meta2dCanvas'/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="data" name="data"> <el-tab-pane label="data" name="data">
<meta2dData :querysArray.sync="querysArray" :timeType.sync="timeType"/> <meta2dData :querysArray.sync="querysArray" :timeType.sync="timeType" ref="meta2dData"/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@@ -18,12 +18,21 @@
import meta2dElement from '@/components/common/project/meta2d/meta2dElement' import meta2dElement from '@/components/common/project/meta2d/meta2dElement'
import meta2dCanvas from '@/components/common/project/meta2d/meta2dCanvas' import meta2dCanvas from '@/components/common/project/meta2d/meta2dCanvas'
import meta2dData from '@/components/common/project/meta2d/meta2dData' import meta2dData from '@/components/common/project/meta2d/meta2dData'
import { getTopology, setTopology, dealImg, topologyImg } from '@/components/common/js/common'
import { fromRoute } from '@/components/common/js/constants'
import chartTempData from '@/components/chart/chartTempData'
import { isTimeSeries } from '@/components/chart/chart/tools'
import bus from '@/libs/bus'
import axios from 'axios'
import topoUtil from '@/components/common/project/meta2d/js/topoUtil'
export default { export default {
name: 'meta2dProps', name: 'meta2dProps',
mixins: [topoUtil],
props: { props: {
selectPens: {}, selectPens: {},
querysArray: {}, querysArray: {},
timeType: {} timeType: {},
meta2dId: {}
}, },
components: { components: {
meta2dElement, meta2dElement,
@@ -32,7 +41,6 @@ export default {
}, },
watch: { watch: {
selectPens (n) { selectPens (n) {
console.log(n)
if (n.length === 1) { if (n.length === 1) {
this.activeName = 'elements' this.activeName = 'elements'
} }
@@ -41,6 +49,9 @@ export default {
data () { data () {
return { return {
activeName: 'canvas', activeName: 'canvas',
canvasProps: {
backGround: true
},
elements: { elements: {
backGround: true, backGround: true,
border: true, border: true,
@@ -56,7 +67,15 @@ export default {
methods: { methods: {
change (key) { change (key) {
this.$emit('updatePens', this.selectPens[0], key) this.$emit('updatePens', this.selectPens[0], key)
} },
beforeLeave (newName, oldName) {
if (oldName === 'data') {
const endTime = new Date().getTime()
const startTime = endTime - 60 * 5 * 1000
this.getQueryValues(this.$refs.meta2dData.elements, startTime, endTime)
}
},
} }
} }
</script> </script>

View File

@@ -0,0 +1,115 @@
<template>
<div class="meta2d-image-box" v-clickoutside="changeSelectBoxShow">
<div @click="selectBoxShow = !selectBoxShow">
<img :src="selectImage" v-if="selectImage" class="image-box">
<div v-else class="image-box image-box-null" />
</div>
<div class="image-select-box" v-if="selectBoxShow">
<div v-for="item in iconArray" :key="item.id" class="image-box-item" @click="selectImageChange(item)">
<img :src="item.image" class="imag-src"/>
<div class="img-text text-ellipsis" :title="item.imageName">{{item.imageName}}</div>
</div>
</div>
</div>
</template>
<script>
import { dealImg, topologyImg } from '@/components/common/js/common'
export default {
name: 'meta2dSelectImage',
props: {
selectImage: {}
},
data () {
return {
tools: [],
imgageLoading: false,
iconArray: [],
selectBoxShow: false
}
},
mounted () {
this.imageInit()
},
methods: {
imageInit () { // 加载所有图片
this.$get('monitor/project/topo/icon').then(res => {
this.imgageLoading = true
this.tools = []
let imgArr = []
let promiseArr = []
res.data.list.forEach((item, index) => {
item.imageName = item.name
delete item.name
promiseArr.push(topologyImg['img' + item.id] || dealImg(`monitor/project/topo/icon/${item.id}/1`, item.id))
imgArr.push({ ...item })
})
Promise.all(promiseArr).then((res2, header) => {
this.iconArray = [...res.data.list]
this.iconArray.forEach((item, index) => {
item.image = res2[index].data
})
this.imgInit = true
this.imgageLoading = false
imgArr = null
promiseArr = null
})
})
},
changeSelectBoxShow () {
this.selectBoxShow = false
},
selectImageChange (item) {
this.$emit('updateImage', item)
}
}
}
</script>
<style scoped lang="scss">
.meta2d-image-box{
position: relative;
.image-box {
width: 30px;
height: 30px;
}
.image-box-null {
border: 1px solid #999999;
box-sizing: border-box;
}
.image-select-box {
text-align: center;
width: 254px;
max-height: 300px;
overflow-y: auto;
z-index: 1;
padding: 10px 0px 0px 10px;
position: absolute;
top: 26px;
background: #ffffff;
border: 1px solid #999999;
border-radius: 4px;
left: 0;
.image-box-item {
width: 50px;
height: 70px;
margin: 0 10px 10px 0;
flex-direction: column;
align-items: center;
display: inline-block;
.imag-src{
width: 50px;
height: 50px;
}
.img-text {
width: 100%;
height: 20px;
line-height: 20px;
font-size: 12px;
text-align: center;
}
}
}
}
</style>

View File

@@ -715,7 +715,6 @@ export default {
this.oldcCodeLength = 0 this.oldcCodeLength = 0
this.codeMirrorValue[this.index] = '' this.codeMirrorValue[this.index] = ''
// this.expressionList[this.index] = '' // this.expressionList[this.index] = ''
console.log(this.index)
this.$set(this.expressionList, this.index, '') this.$set(this.expressionList, this.index, '')
this.$emit('change', '') this.$emit('change', '')
} }
@@ -1183,7 +1182,6 @@ export default {
deep: true, deep: true,
immediate: true, immediate: true,
handler (n, o) { handler (n, o) {
console.log(n)
this.codeMirrorValue[this.index] = n[this.index] this.codeMirrorValue[this.index] = n[this.index]
if (this.isTopo && this.firstInit) { if (this.isTopo && this.firstInit) {
setTimeout(() => { setTimeout(() => {

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="project"> <div class="project">
<!-- <topologyL5 v-if="reloadFacade" ref="facade" :obj="currentProject" :topologyIndexF="topologyIndexF" targetTab.sync="panel" @changeTopologyIndexF="changeTopologyIndexF"/>--> <!-- <topologyL5 v-if="reloadFacade" ref="facade" :obj="currentProject" :topologyIndexF="topologyIndexF" targetTab.sync="panel" @changeTopologyIndexF="changeTopologyIndexF"/>-->
<meta2dMain :meta2dId="'projectId'" :topoData="topoData" :querysArray="querysArray" :projectName="currentProject.name" :timeType="timeType"/> <meta2dMain :meta2dId="'projectId'" :topoData="topoData" :querysArray="querysArray" :project="currentProject" :timeType="timeType" @reload="reload"/>
<transition name="el-zoom-in-bottom"> <transition name="el-zoom-in-bottom">
<bottom-box <bottom-box
v-if="bottomBox.showSubList" v-if="bottomBox.showSubList"

View File

@@ -3,6 +3,7 @@ import Vuex from 'vuex'
import user from './user' import user from './user'
import panel from './panel' import panel from './panel'
import terminalFile from './terminalFile' import terminalFile from './terminalFile'
import meta2dStore from '@/components/common/project/meta2d/js/meta2dStore'
// import topology from './topology' // import topology from './topology'
Vue.use(Vuex) Vue.use(Vuex)
@@ -10,7 +11,8 @@ const store = new Vuex.Store({
modules: { modules: {
user, user,
panel, panel,
terminalFile terminalFile,
meta2dStore
}, },
state: { state: {
/* 监听对象变化,用于顶部菜单与底部内容的同步 */ /* 监听对象变化,用于顶部菜单与底部内容的同步 */