feat: topo 重构 添加 右键菜单 , 按钮状态,以及 text扩充

This commit is contained in:
zhangyu
2023-02-23 16:43:15 +08:00
parent 2c0c06829c
commit acd18071fc
10 changed files with 390 additions and 43 deletions

View File

@@ -8,23 +8,22 @@
& > div {
line-height: 2.2;
a {
color: $--color-text-primary;
&:hover {
color: $--color-primary;
}
span {
display: block;
padding: 0 0.2rem;
text-decoration: none;
cursor: pointer;
&:hover {
color: #1890ff;
}
&.flex {
display: flex;
}
&.disabled {
color: #ccc;
color: $--color-text-disabled;
cursor: default;
}
}

View File

@@ -36,6 +36,9 @@
line-height: 14px;
margin-right: 10px;
}
.is-active-meta2d.top-tool-item {
background: $--background-color-disabled;
}
.top-tool-item-scale {
margin-left: 40px;
padding: 0;

View File

@@ -0,0 +1,153 @@
<template>
<div class="menus">
<div>
<span :class="{disabled: !selectPens.length}" @click="onTop()">{{$t('project.topology.top')}}</span>
</div>
<div>
<span :class="{disabled: !selectPens.length}" @click="onBottom()">{{$t('project.topology.bottom')}}</span>
</div>
<div>
<span :class="{disabled: !selectPens.length}" @click="onUp()">{{$t('project.topology.up')}}</span>
</div>
<div>
<span :class="{disabled: !selectPens.length}" @click="onDown()">{{$t('project.topology.down')}}</span>
</div>
<!-- <div class="line"></div>-->
<!-- <div>-->
<!-- <span :class="{disabled: !selectPens.length}" @click="onLock()">{{$t('overall.delete')}}</span>-->
<!-- </div>-->
<div class="line"></div>
<div>
<span :class="{disabled: !selectPens.length}" @click="onDel()">{{$t('overall.delete')}}</span>
</div>
<div class="line"></div>
<div>
<span @click="undo()" class="flex" :class="{disabled:!( historyIndex > -1 && !isNull(historyIndex))}">
<span class="full">{{$t('project.topology.undo')}}</span>
<span class="ml50">Ctrl + Z</span>
</span>
</div>
<div>
<span @click="redo()" class="flex" :class="{disabled: historyIndex >= historiesLength - 1 }">
<span class="full">{{$t('project.topology.redo')}}</span>
<span class="ml50">Shift + Z</span>
</span>
</div>
<div class="line"></div>
<div>
<span @click="canvascut()" class="flex" :class="{disabled: !selectPens.length}">
<span class="full">{{$t('project.topology.cut')}}</span>
<span class="ml50">Ctrl + X</span>
</span>
</div>
<div>
<span @click="canvascopy()" class="flex" :class="{disabled: !selectPens.length}">
<span class="full">{{$t('overall.duplicate')}}</span>
<span class="ml50">Ctrl + C</span>
</span>
</div>
<div>
<span @click="canvaspaste()" class="flex">
<span class="full">{{$t('project.topology.paste')}}</span>
<span class="ml50">Ctrl + V</span>
</span>
</div>
</div>
</template>
<script >
import { getTopology } from '../../js/common'
import bus from '@/libs/bus'
export default {
data () {
return {
historyIndex: null,
historiesLength: 0
}
},
props: {
meta2dId: {
require: true
},
selectPens: {
require: true
}
},
mounted () {
this.historyIndex = getTopology(this.meta2dId).store.historyIndex
this.historiesLength = getTopology(this.meta2dId).store.histories.length
},
methods: {
undo () { // 撤销
getTopology(this.meta2dId).undo()
// getTopology(this.meta2dId).inactive()
bus.$emit('changeSelectPens', [])
},
redo () { // 重做
getTopology(this.meta2dId).redo()
// getTopology(this.meta2dId).inactive()
bus.$emit('changeSelectPens', [])
},
onTop () {
for (const item of this.selectPens) {
getTopology(this.meta2dId).top(item)
}
getTopology(this.meta2dId).render()
},
onUp () {
for (const item of this.selectPens) {
getTopology(this.meta2dId).up(item)
}
getTopology(this.meta2dId).render()
},
onDown () {
for (const item of this.selectPens) {
getTopology(this.meta2dId).down(item)
}
getTopology(this.meta2dId).render()
},
onBottom () {
for (const item of this.selectPens) {
getTopology(this.meta2dId).bottom(item)
}
getTopology(this.meta2dId).render()
},
onCombine () {
if (this.selectPens.length < 2) {
return
}
getTopology(this.meta2dId).combine(this.selectPens)
getTopology(this.meta2dId).render()
},
onUncombine () {
if (this.selectPens.length < 2) {
return
}
getTopology(this.meta2dId).uncombine(this.selectPens)
getTopology(this.meta2dId).render()
},
onLock () {
getTopology(this.meta2dId).render()
},
onDel () {
getTopology(this.meta2dId).delete(this.selectPens)
},
canvascut () {
getTopology(this.meta2dId).cut(this.selectPens)
},
canvascopy () {
getTopology(this.meta2dId).copy(this.selectPens)
},
canvaspaste () {
getTopology(this.meta2dId).paste()
},
isNull (val) {
return this.$loadsh.isNull(val)
}
}
}
</script>

View File

@@ -35,12 +35,18 @@ export default {
legends: [],
title: '',
titleShow: true
}
},
contextmenu: {
left: null,
top: null,
bottom: null
},
setContextmenu: true
}
},
mixins: [topoUtil],
methods: {
init () {
init: function () {
const meta2dOptions = {
minScale: 0.25,
maxScale: 2
@@ -55,6 +61,7 @@ export default {
// meta2d.registerCanvasDraw(chartsPens())
/* 画布绑定事件 */
meta2d.beforeAddPens = (pens) => { // 添加画笔前
bus.$emit('changeDrawState')
if (pens.length === 1) {
if (!pens[0].type) {
this.nodeInit(pens[0])
@@ -69,7 +76,7 @@ export default {
// 返回 true 允许 remove
return true
}
// getTopology(this.topoData)).on('translate', this.topTranslate) // 平移·
meta2d.on('translate', this.topTranslate) // 平移·
meta2d.on('active', this.pensActive) // 选中·
// meta2d.on('translatePens', () => {}) // 移动画笔结束·
// meta2d.on('translatingPens', () => {}) // 移动画笔进行中·
@@ -77,15 +84,13 @@ export default {
meta2d.on('leave', this.penLeave) // 移出画笔·
// meta2d.on('add', this.appPen) // 添加新画笔·
meta2d.on('click', this.topoClick) // click画笔·
setTopology(this.meta2dId, meta2d)
},
reload () {
this.position.show = false
const endTime = new Date().getTime()
const startTime = endTime - 60 * this.params.timeType * 1000
console.log(startTime)
this.getQueryValues(this.querysArray, startTime, endTime).then((arr) => {
console.log(arr)
this.clacTopoData(this.topoData, arr).then((data) => {
getTopology(this.meta2dId).resize()
getTopology(this.meta2dId).open(data)
@@ -110,6 +115,11 @@ export default {
statistic: 'last',
parent: '',
value: '',
source: 'text',
textParent: '',
textLegend: '',
text: pen.text || '',
textValue: '',
enable: {
valueMapping: true,
tooltip: true
@@ -198,9 +208,10 @@ export default {
this.selectPens = []
}
},
topTranslate () {
this.setContextmenu = false
},
penEnter (pen, e) { // 移入节点
console.log(pen, e, 'penEnter')
console.log(getTopology(this.meta2dId).getPenRect(pen))
if (this.timer3) {
clearTimeout(this.timer3)
this.timer3 = null
@@ -217,7 +228,6 @@ export default {
}
this.timer3 = setTimeout(() => {
let ePosition = window.ePosition
console.log(this.meta2dId, ePosition)
let boxWidth = this.$refs.meta2dBox.offsetWidth
let boxHeight = this.$refs.meta2dBox.offsetHeight
this.position.left = ePosition.layerX
@@ -258,12 +268,10 @@ export default {
}
},
tooltipOver () {
console.log('tooltipOver')
clearTimeout(this.timer3)
this.timer3 = null
},
tooltipOut () {
console.log('tooltipOut')
this.timer3 = setTimeout(() => {
this.position.show = false
this.timer3 = null
@@ -287,9 +295,45 @@ export default {
},
exitEdit (isRefresh) {
this.editFlag = false
this.position.show = false
if (isRefresh) {
this.$emit('reload')
}
},
beforeEdit () {
this.editFlag = true
this.contextmenu = {
left: null,
top: null,
bottom: null
}
this.position.show = false
},
onContextMenu (event) {
if (!this.setContextmenu) {
return
}
event.preventDefault()
event.stopPropagation()
if (event.clientY + 360 < document.body.clientHeight) {
this.contextmenu = {
left: event.clientX + 'px',
top: event.clientY + 'px'
}
} else {
this.contextmenu = {
left: event.clientX + 'px',
bottom: document.body.clientHeight - event.clientY + 'px'
}
}
},
contextmenuNone () {
this.contextmenu = {
left: null,
top: null,
bottom: null
}
}
},
beforeDestroy () {

View File

@@ -2,7 +2,7 @@ import { getTopology, setTopology, dealImg, topologyImg } from '@/components/com
import bus from '@/libs/bus'
import axios from 'axios'
import { getMetricTypeValue } from '@/components/common/js/tools'
import chartDataFormat from "@/components/chart/chartDataFormat";
import chartDataFormat from '@/components/chart/chartDataFormat'
export default {
methods: {
topoResize (id) {
@@ -141,13 +141,20 @@ export default {
if (pen.isNz) {
if (pen.data.legend && pen.data.enable.valueMapping) {
const findItem = queryValues.find(query => query.name === pen.data.legend && query.parent === pen.data.parent)
console.log(findItem)
if (findItem) {
pen.data.value = getMetricTypeValue(findItem.values, findItem.elements.statistic || 'last')
pen.data.showValue = chartDataFormat.getUnit(findItem.elements.unit).compute(pen.data.value, null, 2)
this.selectMapping(pen)
}
}
if (pen.data.source === 'legend' && pen.data.textParent && pen.data.textLegend) {
const findItem = queryValues.find(query => query.name === pen.data.textLegend && query.parent === pen.data.textParent)
if (findItem) {
const value = getMetricTypeValue(findItem.values, findItem.elements.statistic || 'last')
pen.data.textValue = chartDataFormat.getUnit(findItem.elements.unit).compute(value, null, 2)
pen.text = pen.data.textValue
}
}
} else {
// 处理 le5le的数据
}

View File

@@ -343,6 +343,24 @@
</div>
</div>
<div class="form-row-item form-row-item-full">
<div class="form-row-key">
Source
</div>
<div class="form-row-value">
<el-select :placeholder="$t('el.select.placeholder')" :popper-append-to-body="true"
class="right-box-row-with-btn no-style-class" popper-class="chart-box-dropdown-small right-box-select-top right-public-box-dropdown-top"
size="mini"
v-model="pen.data.source" value-key="chartType" @change="change('data.source')">
<el-option :label="'Text'" :value="'text'">
<span class="panel-dropdown-label-txt">{{ 'Text' }}</span>
</el-option>
<el-option :label="'Legend'" :value="'legend'">
<span class="panel-dropdown-label-txt">{{ 'Legend' }}</span>
</el-option>
</el-select>
</div>
</div>
<div class="form-row-item form-row-item-full" v-if="pen.data.source !== 'legend'">
<div class="form-row-key">
Content
</div>
@@ -350,6 +368,27 @@
<el-input maxlength="256" show-word-limit v-model="pen.text" size="small" :rows="4" type="textarea" @change="change('text')"/>
</div>
</div>
<div class="form-row-item form-row-item-full" v-if="pen.data.source === 'legend'">
<div class="form-row-value">
<div class="form-row-item form-row-item-full">
<div class="form-row-key">
Legend
</div>
<div class="form-row-value">
<div style="display: inline-block;width: calc(20% - 3px)">
<el-select v-model="pen.data.textParent" size="small">
<el-option v-for="item in queryValues.filter(query => query.type === 'title')" :key="item.id" :value="item.name" :label='item.name'></el-option>
</el-select>
</div>
<div style="display: inline-block;width: calc(80% - 3px)">
<el-select v-model="pen.data.textLegend" size="small">
<el-option v-for="item in queryValues.filter(query => (query.parent === pen.data.textParent) && query.type === 'item')" :key="item.id" :value="item.name" :label='item.name'></el-option>
</el-select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -1110,6 +1149,18 @@ export default {
const val = this.pen.borderType
this.pen.lineDash = val ? (val == 1 ? [5, 5] : ((val == 2 ? [10, 10] : [10, 10, 2, 10]))) : []
}
if (key === 'text') {
this.pen.data.text = this.pen.text
}
if (key === 'data.source') {
key = 'text'
if (this.pen.data.source === 'text') {
this.pen.text = this.pen.data.text
}
if (this.pen.data.source === 'legend') {
this.pen.text = this.pen.data.textValue
}
}
this.$emit('change', key)
},
updateImage (image) {

View File

@@ -1,7 +1,16 @@
<template>
<div class="meta2d-box list-page" v-my-loading="meta2dLoading" ref="meta2dBox">
<meta2dHeader :meta2dId="meta2dId" :isChart="isChart" :project="project" :editFlag="editFlag" @edit="editFlag = true" @exitEdit="exitEdit" @reload="reload"/>
<div class="meta2d-main" :class="isChart ? 'meta2d-chart': 'meta2d-project'">
<meta2dHeader
ref="header"
:meta2dId="meta2dId"
:isChart="isChart"
:project="project"
:editFlag="editFlag"
@edit="beforeEdit"
@exitEdit="exitEdit"
@reload="reload"
/>
<div class="meta2d-main" :class="isChart ? 'meta2d-chart': 'meta2d-project'" @contextmenu="onContextMenu($event)">
<div :id="meta2dId" style="height: 100%;width: 100%"></div>
</div>
<meta2dProps
@@ -13,6 +22,9 @@
:meta2dId="meta2dId"
@updatePens="updatePens"
/>
<div class="context-menu" v-if="contextmenu.left && editFlag && !isPreview" :style="this.contextmenu">
<CanvasContextMenu :meta2dId="meta2dId" :selectPens.sync="selectPens"></CanvasContextMenu>
</div>
<div
v-show="position.show && !editFlag"
@mouseleave="tooltipOut"
@@ -35,6 +47,7 @@ import meta2dHeader from '@/components/common/project/meta2d/meta2dHeader'
import meta2dProps from '@/components/common/project/meta2d/meta2dProps'
import meta2dMain from '@/components/common/project/meta2d/js/meta2dMain'
import meta2dTooltip from '@/components/common/project/meta2d/meta2dTooltip'
import CanvasContextMenu from '@/components/common/project/meta2d/CanvasContextMenu'
import { getTopology, setTopology } from '@/components/common/js/common'
import topoUtil from '@/components/common/project/meta2d/js/topoUtil'
import bus from '@/libs/bus'
@@ -52,10 +65,16 @@ export default {
params: {},
project: {}
},
computed: {
isPreview () {
return this.$refs.header && this.$refs.header.isPreview
}
},
components: {
meta2dHeader,
meta2dProps,
meta2dTooltip
meta2dTooltip,
CanvasContextMenu
},
watch: {
topoData: {
@@ -69,10 +88,18 @@ export default {
this.init()
bus.$on('changeSelectPens', this.pensActive)
this.$refs.meta2dBox.addEventListener('mousemove', this.mousemove)
// this.$refs.meta2dBox.addEventListener('mousedown', this.mousedown)
this.$refs.meta2dBox.addEventListener('mouseup', this.mouseup)
window.addEventListener('click', this.contextmenuNone)
},
methods: {
mousemove (e) {
window.ePosition = e
},
mouseup () {
setTimeout(() => {
this.setContextmenu = true
}, 100)
}
},
beforeDestroy () {
@@ -80,6 +107,7 @@ export default {
setTopology(this.meta2dId, null)
bus.$off('changeSelectPens', this.pensActive)
this.$refs.meta2dBox.removeEventListener('mousemove', this.mousemove)
this.$refs.meta2dBox.removeEventListener('mouseup', this.mouseup)
}
}

View File

@@ -5,7 +5,7 @@
<img :src="selectImage" class="image-box">
</div>
<div v-else class="image-box image-box-null" />
<i class="nz-icon nz-icon-close" style="position: absolute;top: 0;right: 0;font-size: 10px" @click.stop="selectImageChange({image: '', id: ''})"/>
<i class="nz-icon nz-icon-close" style="position: absolute;top: -7px;left: 25px;font-size: 10px" @click.stop="selectImageChange({image: '', id: ''})"/>
</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)">-->

View File

@@ -47,7 +47,6 @@ export default {
params: {
immediate: true,
handler (n) {
console.log(n, this.querysArray)
this.chartInfo.type = this.params.chartType || 'line'
const chartData = []
const elements = []
@@ -67,16 +66,11 @@ export default {
}
}
})
console.log(chartData)
if (chartData.length && this.$refs.panelChart) {
this.chartInfo.elements = elements
console.log(elements)
this.$refs.panelChart.chartData = chartData
this.$refs.panelChart.loading = false
this.$nextTick(() => {
console.log(this.$refs.panelChart)
console.log(this.$refs.panelChart.$refs.chart)
console.log(this.$refs.panelChart.$refs.chart.$refs['chart' + this.chartInfo.id])
this.$refs.panelChart.$refs.chart.$refs['chart' + this.chartInfo.id].initChart()
})
}

View File

@@ -1,19 +1,34 @@
<template>
<div class="tool-top" id="tool-top">
<div id="tools-left-drag" class="top-tool-item" :title="'add node'">
<div class="tool-top" id="tool-top" @mouseup="changeDrawLineFlag(false)">
<div id="tools-left-drag" class="top-tool-item" :title="'add node'" :class="dragstartFlag ? 'is-active-meta2d' : ''">
<div
draggable="true"
@mousedown="changeState('dragstartFlag')"
@dragstart.stop="onDragstart($event)"
@click="onTouchstart($event)"
>
<i class="nz-icon nz-icon-zhengfangxing" />
</div>
</div>
<div id="tools-left-draw" class="top-tool-item" @click="setDrawPen()" :title="'add line'">
<div id="tools-left-draw"
class="top-tool-item"
:class="drawLineFlag ? 'is-active-meta2d' : ''"
@click="changeState('drawLineFlag')"
:title="'add line'">
<i class="nz-icon nz-icon-compare" />
</div>
<div id="undo" :class="['top-tool-item',]" @click="undo"> <i class="nz-icon nz-icon-revoke" :title="$t('overall.revocation')"/> </div>
<div id="redo" :class="['top-tool-item',]" @click="redo"> <i class="nz-icon nz-icon-revoke1" :title="$t('overall.redo')"/> </div>
<div id="undo"
class="top-tool-item"
:class="undoFlag ? '' : 'is-active-meta2d' "
@click="undo">
<i class="nz-icon nz-icon-revoke" :title="$t('overall.revocation')"/>
</div>
<div id="redo"
class="top-tool-item"
:class="redoFlag ? '' : 'is-active-meta2d' "
@click="redo"
>
<i class="nz-icon nz-icon-revoke1" :title="$t('overall.redo')"/>
</div>
<!--<div> 保存为图片 </div>-->
<div class="top-tool-item" @click="del" :title="$t('overall.delete')"> <i class="nz-icon nz-icon-delete"/> </div>
<div class="top-tool-item top-tool-item-scale">
@@ -86,6 +101,8 @@ export default {
rule: false,
map: false
},
dragstartFlag: false,
drawLineFlag: false,
scaleNum: 100,
penLineType: [
{ d: 'M5 14 a100,50 0 0,1 85,0', 'stroke-dasharray': '', name: 'curve' },
@@ -100,7 +117,9 @@ export default {
{ d: 'M5 14 l85 0', fill: '#000000', stroke: '', 'stroke-width': '', cx: '10', cy: '14', r: '5', name: 'circleSolid' },
{ d: 'M5 14 l85 0', fill: '#ffffff', stroke: '#000000', 'stroke-width': '1', cx: '10', cy: '14', r: '5', name: 'circle' }
],
redoFlag: false
redoFlag: false,
undoFlag: false,
store: {}
}
},
props: {
@@ -108,6 +127,26 @@ export default {
require: true
}
},
computed: {
},
watch: {
'store.historyIndex': {
handler (n) {
const historyIndex = this.store.historyIndex
const histories = this.store.histories
if (historyIndex < histories.length - 1) {
this.redoFlag = true
} else {
this.redoFlag = false
}
if (historyIndex > -1 && !this.$loadsh.isNull(historyIndex)) {
this.undoFlag = true
} else {
this.undoFlag = false
}
}
}
},
mounted () {
const dataOption = getTopology(this.meta2dId).store.data
Object.keys(this.option).forEach(key => {
@@ -118,8 +157,11 @@ export default {
}
})
getTopology(this.meta2dId).on('scale', this.topoScale) // 缩放·
this.store = getTopology(this.meta2dId).store
bus.$on('changeDrawState', this.waiveDraw)
},
methods: {
getTopology,
onDragstart (e) {
const pen = {
name: 'rectangle',
@@ -140,9 +182,29 @@ export default {
}
getTopology(this.meta2dId).canvas.addCaches = deepClone([pen])
},
// 开启钢笔状态
setDrawPen () {
changeDrawLineFlag () {
if (this.dragstartFlag) {
this.dragstartFlag = false
}
},
// 变更状态
changeState (key) {
if (key === 'dragstartFlag') {
this.dragstartFlag = !this.dragstartFlag
}
if (key === 'drawLineFlag') {
this.drawLineFlag = !this.drawLineFlag
if (this.drawLineFlag) { // 开启钢笔
getTopology(this.meta2dId).drawLine('line')
} else {
getTopology(this.meta2dId).drawLine()
}
}
},
waiveDraw () {
this.drawLineFlag = false
getTopology(this.meta2dId).drawLine()
this.dragstartFlag = false
},
changeOption (key) {
// getTopology(this.meta2dId).data[key] = this.option[key]
@@ -165,12 +227,13 @@ export default {
undo () { // 撤销
getTopology(this.meta2dId).undo()
// getTopology(this.meta2dId).inactive()
bus.$emit('changeSelectPens', [])
// bus.$emit('changeSelectPens', [])
},
redo () { // 重做
getTopology(this.meta2dId).redo()
// getTopology(this.meta2dId).render()
// getTopology(this.meta2dId).inactive()
bus.$emit('changeSelectPens', [])
// bus.$emit('changeSelectPens', [])
},
centerView () { // 居中显示
getTopology(this.meta2dId).centerView()
@@ -213,3 +276,8 @@ export default {
}
}
</script>
<style scoped lang="scss">
.is-active-meta2d {
background: #0000ff;
}
</style>