Commit e33fc5d5 by 史敦盼

数据主题关系视图及其他问题修复

1 parent bb5c1e3e
......@@ -238,9 +238,9 @@ const initAttributePanel = function(that) {
})
}
}
propertyList.forEach(item => {
propertyList.forEach((item, index) => {
if(Object.keys(item).length) {
addListPanel(that, propertyList, item.cnName || item.name, item.value_ || item.value, item.controlType, item.dictKey);
addListPanel(that, propertyList, item.cnName || item.name, item.value_ || item.value, item.controlType, item.dictKey, index);
}
})
}
......@@ -320,24 +320,31 @@ const initAttributePanel = function(that) {
const currentItem = archiData.find(
(item) => item.elementId == e.target.value,
)
$('#parentElement').val('')
// this.getShangJiJieDianSelect(currentItem)
getPreArc(currentItem, valueSelect2)
}
console.log('valueSelect2', valueSelect2)
infoItemContain.appendChild(valueSelect);
break
case '上级元素':
valueSelect2.style.cssText = baseEleStyle;
valueSelect2.value = value
valueSelect2.onchange = function (e) {
parentElementChange(e.target.value)
}
infoItemContain.appendChild(valueSelect2);
break
case '上级资产':
const valueSelect3 = document.createElement('select');
valueSelect3.style.cssText = 'width: 100%;background: #ffffff;';
infoItemContain.appendChild(valueSelect3);
const valueTree = document.createElement('input');
valueTree.style.cssText = 'width: 100%;background: #ffffff;';
valueTree.id = 'selectree'
// $("#selectree").selectTree({
// isSimpleNode: true,
// debug: true,
// data: this.treeSelectData // 后台查询的数据 返回为data
// });
infoItemContain.appendChild(valueTree);
break
default:
break;
......@@ -361,16 +368,15 @@ const initAttributePanel = function(that) {
success: function (res) {
if(res.code === 200) {
const archiData = res.data;
archiData.forEach((v, i) => {
var option1 = document.createElement("option");
option1.value = v.parentElement;
option1.text = v.parentElement;
if(v.parentElement == c.value) {
c.text = v.parentElement
c.options[i].selected = true
}
c.appendChild(option1);
})
$.each(archiData, function(i, option) {
$('#parentElement').append($('<option>', {
value: option.parentElement,
text: option.parentElement
}));
});
$('#parentElement').val('')
console.log(c)
}
// console.log('result', res)
},
......@@ -412,8 +418,9 @@ const initAttributePanel = function(that) {
// }
// }
}
const addListPanel = function(that, originAttr, attrName_, attrValue_, controlType, dictKey) {
const addListPanel = function(that, originAttr, attrName_, attrValue_, controlType, dictKey, $index) {
const add_item_container = document.createElement('div');
add_item_container.id = `item_container_id_${$index}`
add_item_container.style.cssText = 'display: flex;justify-content: space-between;padding: 4px 0 4px 10px;';
add_item_container.className = 'add_item_container';
......@@ -431,8 +438,6 @@ const addListPanel = function(that, originAttr, attrName_, attrValue_, controlTy
//属性值--------------------------------------------------------------------
const item_right_container = document.createElement('div');
item_right_container.style.cssText = 'display: flex;justify-content: space-between;width: 70%;';
// const valueSpan = document.createElement('span');
// valueSpan.style.cssText = 'white-space: normal;'
// valueSpan.innerHTML = attrValue_
......@@ -452,8 +457,12 @@ const addListPanel = function(that, originAttr, attrName_, attrValue_, controlTy
item_right_container.appendChild(item_right_input);
break;
case 1:
const item_right_textarea = document.createElement('textarea');
item_right_textarea.rows = "4"; // 设置显示的行数为2行
var item_right_textarea = document.createElement('input');
item_right_textarea.style.pointerEvents = 'auto'
item_right_textarea.style.userSelect = 'text'
// item_right_textarea.id = `textarea_id_${$index}`
// item_right_textarea.rows = "4"; // 设置显示的行数为2行
// item_right_textarea.cols = "4";
item_right_textarea.value = attrValue_ || '';
item_right_textarea.style.cssText = 'width: 100%;background: #ffffff;';
......@@ -463,12 +472,11 @@ const addListPanel = function(that, originAttr, attrName_, attrValue_, controlTy
res.value_ = e.target.value;
}
item_right_container.appendChild(item_right_textarea);
item_right_textarea.focus()
// item_right_textarea.focus()
break;
case 2:
const item_right_select = document.createElement('select');
item_right_select.value = attrValue_;
// item_right_select.text =
item_right_select.style.cssText = 'width: 100%;background: #ffffff;';
$.ajax({
......@@ -565,7 +573,7 @@ function parentElementChange(eleName) {
}
$.ajax({
method: 'post',
url: `http://${ajaxUrl}/eadc-shared-ability/arc-ast-info/qryByTree`,
url: `http://${ajaxUrl}/eadc-architecture/arc-ast-info/qryByTree`,
data: JSON.stringify(params),
contentType: 'application/json',
success: function (res) {
......
......@@ -851,3 +851,11 @@ export function postRequestShared(url, params){
export function queryArchiBelongId(params) {
return post(EADC_ARRCHITECTURE + '/archi-model-dict-detail/gDictByKey', params)
}
// 资产编号查重
export function queryRepeatAssetByNumber(params) {
return post(EADC_ARRCHITECTURE + '/assetByNumber', params)
}
// 查询资产详情
export function getAssetDetail(params) {
return post(EADC_ARRCHITECTURE + '/archi-asset-view/assetTickInfo', params)
}
\ No newline at end of file
const state = {
graphData: []
graphData: [], // 业务能力视图数据
dataSubjectRelationshipGraphData: [], // 数据主题关系视图数据
}
const mutations = {
CHANGE_GRAPH_DATA: (state, data) => {
state.graphData = data
},
CHANGE_DATA_SUB_GRAPH_DATA: (state, data) => {
state.dataSubjectRelationshipGraphData = data
}
}
export default {
......
......@@ -32,3 +32,13 @@
opacity: 0;
transform: translateX(30px);
}
/*
进入和离开动画可以使用不同
持续时间和速度曲线。
*/
.slide-enter-active, .slide-leave-active {
transition: transform 0.3s;
}
.slide-enter, .slide-leave-to /* .slide-leave-active for <2.1.8 */ {
transform: translateX(-100%);
}
\ No newline at end of file
......@@ -76,3 +76,14 @@ export function deepClone(source) {
})
return targetObj
}
/**
* @description: 数组对象去重
* @param {Array} list
* @param {String} key
* @return {Array}
* @author: pan
*/
export function deduplication(list, key) {
let map = new Map()
return list.filter((item) => !map.has(item[key].toString()) && map.set(item[key].toString()))
}
\ No newline at end of file
......@@ -1176,7 +1176,7 @@ export default {
}
},
handleChange(value) {
// console.log('value', value)
console.log('value', value)
// 当选中值变化时,更新绑定的对象
let selectedObject = {}
if (value && value.length) {
......@@ -1308,7 +1308,8 @@ export default {
this.getShangJiJieDianSelect(data)
},
zuJianLeiXingSelectChange(data, flag) {
this.preArcList = []
this.treeSelectData = []
//所属元素选择后
// console.log(data)
// console.log(this.zuJianLeiXingSelect)
......@@ -1770,11 +1771,19 @@ export default {
padding-bottom: 20px; */
}
.left_container {
width: 20%;
width: 200px;
border-right: 1px solid #ccc;
margin-right: 20px;
/deep/ .filter-tree {
width: 100%;
padding: 10px 0 10px 10px;
box-sizing: border-box;
}
}
.right_container {
width: calc(80% - 20px);
// width: calc(80% - 20px);
flex: 1;
min-width: 0;
}
.el-button.is-disabled {
color: #c0c4cc !important;
......
<template>
<div>
<el-dialog
:title="title"
:visible.sync="showDialog"
:close-on-click-modal="false"
width="60%"
@open="handleOpen()"
@close="handleClose()"
>
<div>
<Form ref="addForm" :form-options="formOptions" label-width="120px">
<template #iconSetting="{ formData }">
<div class="flex">
<img
:style="{
width: selectGraphSrc ? '80px' : 0,
height: selectGraphSrc ? '40px' : 0,
}"
:src="selectGraphSrc"
alt=""
/>
<el-button type="primary" @click="openGraphDialog"
>图形选择</el-button
>
<el-color-picker
v-model="formData.color"
:predefine="predefineColors"
>
</el-color-picker>
</div>
</template>
</Form>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" v-preventReClick @click="fnAdd()"
>确定</el-button
>
<el-button @click="handleClose()">取消</el-button>
</span></el-dialog
>
<!-- 选择图形 -->
<ChooseSvg @emitSvg="getChooseSvg" :visible.sync="chooseSvgVisible" />
</div>
</template>
<script>
import Form from '@/components/Form.vue'
import ChooseSvg from '@/views/busi-assets-list/ChooseSvg.vue'
import {
queryZiChanJiaGouZuJianLeiXing,
getPreArc,
queryZuJianLeiXingBelongForm,
getDianXingAnLiSelectData,
getQryByTree,
queryRepeatAssetByNumber,
} from '@/api/index'
import { archiEleColor } from '@/config'
export default {
props: {
visible: {
type: Boolean,
default: false,
},
title: {
type: String,
default: '',
},
archiBelongId: {
type: String,
default: '',
},
},
data() {
return {
// 所属元素集合
archiEleOptions: [],
// 上级元素集合
parentElementOptions: [],
// 上级节点
treeSelectData: [],
// 资产属性
dynamicForm_: [],
// 上级节点属性
superiorNodeValue: null,
superiorNodeLabel: null,
selectCode: null,
predefineColors: archiEleColor,
chooseSvgVisible: false,
selectGraphSrc: '',
selectGraphShape: '',
graphId: '',
// 选择的上级节点对应的详细信息
selectedObject: {}
}
},
components: { Form, ChooseSvg },
computed: {
formOptions() {
const that = this
let arr = []
arr = [
{
label: '资产名称', // label文字
prop: 'assetName', // 字段名
element: 'el-input', // 指定elementui组件
placeholder: '请填写资产名称', // elementui组件属性
rules: [
{ required: true, trigger: 'blur', message: '不能为空' },
// { validator: this.assetNameValidator, trigger: 'blur' },
],
},
{
label: '资产编号', // label文字
prop: 'assetNumber', // 字段名
element: 'el-input', // 指定elementui组件
placeholder: '请填写资产编号', // elementui组件属性
rules: [{ required: true, trigger: 'blur', message: '不能为空' }],
},
{
label: '所属元素', // label文字
prop: 'archiEleId', // 字段名
element: 'el-select', // 指定elementui组件
// initValue: undefined, // 字段初始值
placeholder: '请选择', // elementui组件属性
options: this.archiEleOptions,
rules: [{ required: true, trigger: 'change', message: '不能为空' }],
filterable: true,
keyOption: {
label: 'elementName',
value: 'elementId',
},
events: {
change(e) {
that.archiEleIdChange(e)
},
},
},
{
label: '上级元素', // label文字
prop: 'parentElement', // 字段名
element: 'el-select', // 指定elementui组件
initValue: undefined, // 字段初始值
placeholder: '请选择', // elementui组件属性
options: this.parentElementOptions,
filterable: true,
keyOption: {
label: 'parentElement',
value: 'parentElement',
},
events: {
change(e) {
that.parentElementChange(e)
},
},
},
{
label: '上级节点', // label文字
prop: 'superiorNode', // 字段名
element: 'el-cascader', // 指定elementui组件
initValue: undefined, // 字段初始值
placeholder: '请选择', // elementui组件属性
filterable: true,
options: this.treeSelectData,
props: {
children: 'children',
label: 'assetName',
value: 'assetId',
checkStrictly: true,
},
events: {
change(e) {
that.superiorNodeChange(e)
},
},
},
{
label: '排序', // label文字
prop: 'sort', // 字段名
element: 'el-input-number', // 指定elementui组件
min: 0,
initValue: 0,
},
{
label: '图标设置',
prop: 'iconSetting',
__slotName: 'iconSetting',
rules: [{ required: true, trigger: 'change', message: '不能为空' }],
},
]
this.dynamicForm_.forEach((v, i) => {
if (v.controlType == 0) {
arr = [
...arr,
{
label: v.cnName, // label文字
prop: `value_${i}`, // 字段名
element: 'el-input', // 指定elementui组件
placeholder: '请输入内容', // elementui组件属性
span: 24,
},
]
} else if (v.controlType == 1) {
arr = [
...arr,
{
label: v.cnName, // label文字
prop: `value_${i}`, // 字段名
element: 'el-input', // 指定elementui组件
placeholder: '请输入内容', // elementui组件属性
type: 'textarea',
rows: 3,
maxlength: '200',
showWordLimit: true,
span: 24,
},
]
} else {
arr = [
...arr,
{
label: v.cnName, // label文字
prop: `value_${i}`, // 字段名
element: 'el-select', // 指定elementui组件
placeholder: '请选择', // elementui组件属性
options: v.dictArray_,
filterable: true,
keyOption: {
label: 'label',
value: 'id',
},
span: 24,
},
]
}
})
return arr
},
showDialog: {
get() {
return this.visible
},
set(value) {
this.$emit('update:visible', value)
},
},
getArchiType() {
let archiType = ''
switch (this.archiBelongId) {
case '5':
archiType = 'ARCHI_SAFE'
break
case '4':
archiType = 'ARCHI_TECHNOLOGY'
break
case '3':
archiType = 'ARCHI_DATA'
break
case '2':
archiType = 'ARCHI_APPLICATION'
break
case '1':
archiType = 'ARCHI_BUSINESS'
break
}
return archiType
},
},
methods: {
assetNameValidator(rule, value, callback) {
if (value && value.trim().length !== null) {
const params = {}
queryRepeatAssetByNumber({})
}
},
getChooseSvg(svgInfo) {
this.selectGraphSrc = svgInfo.icon
this.selectGraphShape = svgInfo.iconName
this.graphId = svgInfo.graphId
this.$nextTick(() => {
this.$set(
this.$refs['addForm'].formData,
'iconSetting',
svgInfo.graphId,
)
this.$refs['addForm'].$refs['formRef'].clearValidate('iconSetting')
})
},
openGraphDialog() {
this.chooseSvgVisible = true
},
// 所属元素change事件
archiEleIdChange(data) {
this.parentElementOptions = []
this.treeSelectData = []
console.log('所属change', data)
const currentItem = this.archiEleOptions.find(
(item) => item.elementId == data,
)
this.getParentElementOptions(currentItem)
const params = {
type: '1',
typeId: data,
}
queryZuJianLeiXingBelongForm(params).then((res) => {
if (res.code == 200) {
if (res.data.length > 0) {
res.data.map((item) => {
if (item.controlType == 2) {
this.get_key(item.dictKey).then((res2) => {
this.$set(item, 'dictArray_', res2)
})
}
item['value_'] = ''
})
this.dynamicForm_ = res.data
} else {
this.dynamicForm_ = []
}
}
})
},
get_key(key) {
//查询字典
const params = {
key: key,
}
return new Promise((resolve, reject) => {
getDianXingAnLiSelectData(params).then((res) => {
if (res.code == 200) {
resolve(res.data)
}
})
})
},
// 上级元素change事件
parentElementChange(eleName) {
//上级节点下拉框值
const params = {
archiType: this.getArchiType,
archiAssetState: 2,
archiStage: 1,
eleName,
}
getQryByTree(params).then((res) => {
if (res.code == 200) {
this.treeSelectData = res.data
}
})
},
// 获取上级元素
getParentElementOptions(item) {
getPreArc({ eleName: item?.elementName }).then((res) => {
if (res.code === 200) {
this.parentElementOptions = res.data
if (!this.parentElementOptions.length) {
// 没有上级元素时,上级节点查对应所属元素下的所有上级节点
this.parentElementChange(item?.elementName)
}
}
})
},
// 上级节点change
superiorNodeChange(value) {
// 当选中值变化时,更新绑定的对象
this.selectedObject = {}
if (value && value.length) {
// 假设我们根据id来查询对象
this.selectedObject = this.findObjectById(this.treeSelectData, value[0])
} else {
this.selectedObject = null
}
this.superiorNodeValue = this.selectedObject.assetId
this.superiorNodeLabel = this.selectedObject.assetName
this.selectCode = this.selectedObject.assetCode
},
findObjectById(items, id) {
for (let i = 0; i < items.length; i++) {
if (items[i].assetId === id) {
return items[i]
}
if (items[i].children) {
const found = this.findObjectById(items[i].children, id)
if (found) {
return found
}
}
}
return null
},
getArchiEleOptions() {
//所属元素下拉框值
const params = {
state: '1',
type: '1',
// elementName: elementName,
archiBelongId: this.archiBelongId,
scopeList: [1, 3],
}
queryZiChanJiaGouZuJianLeiXing(params).then((res) => {
if (res.code == 200) {
this.archiEleOptions = res.data
} else {
this.$message.error(res.msg)
}
})
},
handleOpen() {
this.$nextTick(() => {
this.$refs['addForm'].addInitValue()
this.$refs['addForm'].onReset()
})
this.getArchiEleOptions()
},
handleClose() {
this.showDialog = false
this.selectGraphSrc = ''
this.selectGraphShape = ''
this.graphId = ''
this.dynamicForm_ = []
this.archiEleOptions = []
// 上级元素集合
this.parentElementOptions = []
// 上级节点
this.treeSelectData = []
this.formOptions.forEach((v) => {
if (v.prop === 'superiorNode') {
v.initValue = []
} else {
v.initValue = null
}
})
this.$refs['addForm'].addInitValue()
this.$refs['addForm'].onReset()
},
fnAdd() {
this.$refs['addForm'].onValidate(() => {
const params = this.handleAddParams()
const parentId = params.superiorNode?.length
? params.superiorNode[0]
: '0'
let children = undefined
let name = ''
let emitParams = {}
if (parentId != '0') {
emitParams = {
...this.selectedObject,
parentId: this.selectedObject.parentAssetId,
id: this.selectedObject.assetId,
name: this.selectedObject.assetName,
archiAssetType: 3,
children: [{
...params,
name: params.assetName
}]
}
// children = []
// children.push({
// ...this.selectedObject,
// parentId: this.selectedObject.parentAssetId,
// id: this.selectedObject.assetId,
// name: params.assetName,
// })
// name = params.parentAssetName
} else {
emitParams = {
...params,
archiAssetType: 3,
parentId,
children: [],
name: params.assetName,
}
}
this.$emit('add', emitParams)
this.handleClose()
})
},
handleAddParams() {
const formInfo = this.$refs['addForm'].getData()
const currentItem = this.archiEleOptions.find(
(item) => item.elementId == formInfo.archiEleId,
)
let fieldsValue = []
if (this.dynamicForm_.length > 0) {
this.dynamicForm_.forEach((item, i) => {
fieldsValue.push({
id: item.propertyId,
cnName: item.cnName,
value_: formInfo[`value_${i}`],
controlType: item.controlType,
dictKey: item.dictKey ? item.dictKey : null,
})
})
} else {
fieldsValue = [{}]
}
console.log('this.dynamicForm_', this.dynamicForm_)
console.log('formInfo', formInfo)
const params = {
...formInfo,
archiAssetState: 2,
archiStage: 1,
archiBelongId: this.archiBelongId,
archiType: this.getArchiType,
parentAssetId: this.superiorNodeValue,
parentAssetName: this.superiorNodeLabel,
assetCode: this.selectCode,
fieldsValue,
eleName: currentItem.elementName,
icon: this.selectGraphSrc,
iconName: this.selectGraphShape,
parentElement: [formInfo.parentElement || ''],
graphId: this.graphId,
state: 1,
}
return params
},
},
}
</script>
<style scoped lang="scss">
@import '@/styles/elementui.scss';
</style>
......@@ -3,6 +3,8 @@
</template>
<script>
import businessCapabilityGraphMixin from './mixins/businessCapabilityGraph.mixin.js'
import dataSubjectRelationshipGraphMixin from './mixins/dataSubjectRelationshipGraph.mixin.js'
export default {
data() {
return {
......@@ -11,11 +13,10 @@ export default {
graphData: []
}
},
mixins: [businessCapabilityGraphMixin, dataSubjectRelationshipGraphMixin],
components: {},
computed: {
mockData() {
return this.$store.state.graphData.graphData
},
},
mounted() {
this.graph = new mxGraph(document.getElementById('mxGraph_root'))
......@@ -28,200 +29,7 @@ export default {
clear() {
this.model.clear()
},
init() {
this.graphData = [{
name: '业务能力视图',
children: this.mockData
}]
console.log('mockData', this.mockData)
// mxgraph 被暴露在window下,所以可以直接调用
const parent = this.graph.getDefaultParent()
this.graph.removeCells(this.graph.getChildVertices(parent)); //清空画布
const model = this.graph.getModel()
// 启动一次更新会话
model.beginUpdate()
try {
//设置元素可编辑,不然无法自动布局
this.graph.setCellsLocked(false)
// 插入一个矩形
const v1 = this.graph.insertVertex(
parent,
null,
this.graphData[0].name,
20,
20,
null,
null,
'html=1;fontColor=#000000;fillColor=#dcf8e5;labelPosition=center;verticalAlign=top;align=center;strokeColor=#7fc2a0;',
)
this.insertVertex(v1, this.graphData[0].children)
// console.log(v1)
console.log('parent', parent)
// 子节点宽高调整
this.setGeometry(parent.children[0].children)
// 重新调整整体布局
const allCellData = parent.children[0].children
// 获取业务域最大宽度
let maxWidthArr = []
allCellData.forEach(v => {
const currentItem = model.getGeometry(v)
maxWidthArr.push(currentItem.width)
})
const maxWidth = Math.max(...maxWidthArr)
var geometry = model.getGeometry(parent.children[0])
let maxHeightArr = []
allCellData.forEach((v, i) => {
// 每个宽度统一成最大宽度的那一个
let currentMiddleItemGeometry = model.getGeometry(v)
currentMiddleItemGeometry.width = maxWidth
// 当前所属行
const row = Math.ceil((i + 1) / 3)
// 当前行的高度统一
const currentRowCol3 = allCellData[row * 3 - 1] ? model.getGeometry(allCellData[row * 3 - 1]).height : 0
const currentRowCol2 = allCellData[row * 3 - 2] ? model.getGeometry(allCellData[row * 3 - 2]).height : 0
const currentRowCol1 = allCellData[row * 3 - 3] ? model.getGeometry(allCellData[row * 3 - 3]).height : 0
const currentRowMaxHeight = Math.max(...[currentRowCol3, currentRowCol2, currentRowCol1])
// console.log('currentRowMaxHeight', currentRowMaxHeight)
currentMiddleItemGeometry.height = currentRowMaxHeight || 80
if((i + 1) % 3 === 1) {
maxHeightArr.push(currentRowMaxHeight || 80)
}
if(i > 2) {
// 取当前所属行的上一行的3个,取最大高度,来设置y
const lastRowCol3 = model.getGeometry(allCellData[(row - 1) * 3 - 1]).height
const lastRowCol2 = model.getGeometry(allCellData[(row - 1) * 3 - 2]).height
const lastRowCol1 = model.getGeometry(allCellData[(row - 1) * 3 - 3]).height
const lastRowMaxHeight = Math.max(...[lastRowCol3, lastRowCol2, lastRowCol1])
// 上一行的y
const lastRowY = model.getGeometry(allCellData[(row - 1) * 3 - 3]).y
currentMiddleItemGeometry.y = lastRowY + lastRowMaxHeight + 20
// console.log('currentMiddleItemGeometry.y', currentMiddleItemGeometry.y)
}
// geometry.height += 40
})
// 调整父节点宽高
if(allCellData.length > 2) {
geometry.width = maxWidth * 3 + 60
} else {
geometry.width = maxWidth * allCellData.length + (allCellData.length - 1) * 20 + 40
}
const sum = maxHeightArr.reduce((a, b) => a + b, 0);
// console.log('sum', sum, maxHeightArr)
geometry.height = sum + maxHeightArr.length * 20 + 20
// geometry.height += 40
// geometry.width += 40
// model.setGeometry(v1, geometry)
} finally {
model.endUpdate()
// 获取xml
var encoder = new mxCodec()
var node = encoder.encode(model)
console.log('node', node)
}
},
insertVertex(node, list) {
if (list && list.length) {
list.forEach((v, idx) => {
var cell = this.graph.insertVertex(
node,
null,
v.name,
this.getItemX(v, idx),
this.getItemY(v, idx),
// idx > 2 ? getItemY(idx, v.children) + 20 : 20,
v.checkChildren ? null : 100,
v.checkChildren ? null : 40,
`html=1;fontColor=#000000;fillColor=${
v.checkChildren ? '#dcf8e5' : '#f2fcf5'
};labelPosition=center;verticalAlign=${
v.checkChildren ? 'top' : 'middle'
};align=center;strokeColor=#7fc2a0;`,
)
// console.log('cell', cell)
if (v.checkChildren && v.checkChildren.length) {
this.insertVertex(cell, v.checkChildren)
}
})
}
},
// 计算cell的x坐标
getItemX(item, idx) {
if (item.children) {
// return idx * (130 * 3) + 20
const col = (idx + 1) % 3
// console.log('col', idx, col)
// console.log('---', col > 0 ? col * (110 * 3) + 20 : 3 * (110 * 3) + 20 )
return col > 0 ? (col - 1) * (130 * 3) + 20 : 2 * (130 * 3) + 20
} else {
if (idx > 2) {
if ((idx + 1) % 3 === 1) {
return 20
} else if ((idx + 1) % 3 === 2) {
if(Array.isArray(item.checkChildren)) {
return 410
} else {
return 140
}
// return 140 // 410
} else {
if(Array.isArray(item.checkChildren)) {
return 380 * 2 + 40
} else {
return 2 * 100 + 60
}
// return 2 * 140 + 20 // 380 * 2 + 40
}
} else {
return idx * 120 + 20
}
}
},
getItemY(item, idx) {
const rows = Math.ceil((idx + 1) / 3)
if (item.children) {
return 20
// const h = Math.ceil(item.children.length / 3)
// if (idx > 2) {
// return rows * (h * 50) + 20
// } else {
// return 30
// }
} else {
if (idx > 2) {
if (rows > 2) {
return rows * 40 + (rows - 2) * 20
} else {
return rows * 40
}
} else {
return 20
}
}
},
setGeometry(list) {
for (let index = 0; index < list.length; index++) {
const v = list[index]
if (!v.children) {
let geometry = this.model.getGeometry(v)
geometry.height = 60
// geometry.width = 20
return
}
// console.log('v', v)
let geometry = this.model.getGeometry(v)
geometry.height += 20
geometry.width += 20
// this.model.setGeometry(v, geometry)
// if (!v.children) {
// return this.setGeometry(v.children)
// }
}
},
},
}
</script>
......
......@@ -4,12 +4,12 @@
* @Autor: pan
* @Date: 2024-04-23 11:30:05
* @LastEditors: pan
* @LastEditTime: 2024-04-24 20:05:34
* @LastEditTime: 2024-04-28 17:05:14
-->
<template>
<div class="dataMapping w-100">
<div class="top-content-tab w-100">
<el-tabs v-model="activeName" @tab-click="handleClick">
<div class="top-content-tab w-100 flex">
<el-tabs v-model="activeName">
<el-tab-pane
:label="item.label"
:name="item.value"
......@@ -18,12 +18,37 @@
>
</el-tab-pane>
</el-tabs>
<div class="flex-e-c flex-1">
<el-button
type="primary"
plain
icon="el-icon-circle-plus-outline"
@click="fnPushData()"
>添加行</el-button
>
<el-button icon="el-icon-document-checked" type="primary" plain
>保存</el-button
>
<el-button
v-preventReClick
@click="fnGraph()"
icon="el-icon-picture-outline"
type="primary"
plain
>绘图</el-button
>
</div>
</div>
<div class="flex w-100 flex-1" style="min-height: 0">
<div class="left-content">
<div class="filter-input m-10">
<el-input placeholder="输入关键字进行过滤" v-model="filterText">
</el-input>
<div class="flex m-t-10 m-l-14">
<el-checkbox v-model="checkAll" @change="fnCheckAll"
>全选</el-checkbox
>
</div>
</div>
<div class="tree-content">
<!-- :check-strictly="true" -->
......@@ -42,30 +67,107 @@
@check="handleNodeClick"
></el-tree>
</div>
<div class="flex-e-c m-10">
<el-button icon="el-icon-document-checked" type="primary" plain
>保存</el-button
</div>
<div class="right-content flex-1 flex" :class="{ 'hide-left': collapse }">
<div class="collapse" @click="collapse = !collapse">
<svg
t="1714268548503"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="13918"
width="30"
height="30"
>
<path
d="M0 256C0 114.6112 114.6112 0 256 0h512c141.3888 0 256 114.6112 256 256v512c0 141.3888-114.6112 256-256 256H256C114.6112 1024 0 909.3888 0 768V256z"
fill="#0d857f"
opacity=".6"
p-id="13919"
data-spm-anchor-id="a313x.search_index.0.i9.76a23a81azHzXJ"
class="selected"
></path>
<path
d="M627.968 768V256h64v512h-64z m-114.688-499.1488l51.456 38.4-152.832 204.8 152.832 204.8-51.456 38.4-181.248-243.2 181.248-243.2z"
fill="#FFFFFF"
p-id="13920"
></path>
</svg>
</div>
<transition name="slide">
<div style="width: 50%" v-show="!collapse">
<el-table
:data="tableData"
border
stripe
height="100%"
class="w-100"
>
<el-table-column
align="center"
type="index"
width="50"
label="序号"
>
</el-table-column>
<el-table-column
:formatter="formatter"
align="center"
prop="name"
label="业务域"
>
</el-table-column>
<el-table-column
:formatter="formatter2"
align="center"
prop="name"
label="一级业务职能"
>
</el-table-column>
<el-table-column
align="center"
prop="archiAssetType"
label="状态"
>
</el-table-column>
<el-table-column align="center" label="操作">
<template #default="{ row, $index }">
<el-button
v-preventReClick
@click="fnGraph()"
icon="el-icon-picture-outline"
type="primary"
size="mini"
plain
>绘图</el-button
@click="fnPerfect(row, $index)"
>完善</el-button
>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="right-content flex-1">
</transition>
<div class="graphContent flex-1">
<MxGraph ref="graph" />
</div>
</div>
</div>
<Add
title="添加行"
:archi-belong-id="activeName"
@add="handleAdd"
:visible.sync="visible"
/>
</div>
</template>
<script>
import Add from './Add.vue'
import MxGraph from './MxGraph.vue'
import { getAutomaticGraphing, query_jia_gou_ceng_ci_new } from '@/api'
import {
getAutomaticGraphing,
query_jia_gou_ceng_ci_new,
getAssetDetail,
} from '@/api'
import { deduplication } from '@/utils'
export default {
name: 'dataMapping',
data() {
......@@ -79,47 +181,198 @@ export default {
graphData: [],
tabOptions: [],
activeName: '',
visible: false,
tableData: [],
addData: [],
checkAll: false,
allKeys: [],
collapse: false,
dataSubGraphData: []
}
},
components: { MxGraph },
components: { MxGraph, Add },
created() {
this.getOptions()
},
watch: {
activeName(v) {
this.handleTabChange()
},
filterText(val) {
this.$refs.tree.filter(val)
},
},
computed: {},
mounted() {
// this.$refs.tree.setCheckedKeys(["176", '1775128878519729929', '1775128878519729938', '1775128878519729939', '177', '180', '1062', '1775128878519729932', '1775128878519729925', '1775128878519729933', '1775128878519729934', '1775128878519729926', '1775128878519729935', '1775128878519730025', '1775128878519730026']);
},
methods: {
handleClick() {
fnCheckAll(v) {
// console.log(v)
if (v) {
this.allKeys = []
this.getNodeKeys(this.treeData)
// const keys = this.treeData.map(item => item.id);
this.$refs.tree.setCheckedKeys(this.allKeys)
} else {
this.$refs.tree.setCheckedKeys([])
}
this.tableData = [...this.$refs.tree.getCheckedNodes(), ...this.addData]
if (this.tableData.length) {
this.fnGraph()
} else {
this.$refs['graph'].clear()
}
},
getNodeKeys(list) {
list.map((item) => {
this.allKeys.push(item.id)
if (item.children) {
this.getNodeKeys(item.children)
}
})
},
handleAdd(data) {
this.addData.push(data)
if (data.children.length) {
this.addData.push(data.children[0])
}
this.tableData = [...this.tableData, ...this.addData]
console.log('addData', this.addData)
},
fnPushData(row, index) {
this.visible = true
// this.tableData.splice(index + 1, 0, {
// ...row,
// status: '0',
// })
},
fnPerfect(row, index) {
this.$confirm('是否确认完善?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.$set(row, 'status', '1')
})
.catch(() => {})
},
formatter(row, column, cellValue, index) {
if (row.parentId === '0') {
return cellValue
} else {
let name = ''
this.tableData.forEach((v) => {
if (v.id == row.parentId) {
name = v.name
}
if (!v.id) {
name = v.parentAssetName
}
})
if (!name && row.children) {
name = row.children[0].name
}
return name
}
},
formatter2(row, column, cellValue, index) {
if (row.parentId === '0') {
return '-'
} else {
return cellValue
}
},
handleTabChange() {
if (this.activeName != '0') {
this.fnGetAutomaticGraphing()
}
this.tableData = []
this.$refs['graph'].clear()
this.checkAll = false
this.allKeys = []
this.$refs.tree.setCheckedKeys([])
},
getOptions() {
query_jia_gou_ceng_ci_new({ typeValue: 'archi_belong' }).then((res) => {
if (res.code == 200) {
this.tabOptions = res.data
this.activeName = this.tabOptions[0].value
this.fnGetAutomaticGraphing()
// this.fnGetAutomaticGraphing()
} else {
this.$message.warning(res.msg)
}
})
},
fnGraph() {
this.getCheckedNodes()
this.handleDataToGraph()
},
getCheckedNodes() {
handleDataToGraph(data, node) {
console.log(this.$refs.tree.getCheckedNodes())
switch (this.activeName) {
case '1':
this.handleBusGraph()
break
case '2':
break
case '3':
this.handleDataSubGraph(data, node)
break
default:
break
}
},
// 数据主题关系视图成图逻辑
handleDataSubGraph(data, node) {
if(node.checked) {
getAssetDetail({ assetId: data.id }).then((res) => {
if (res.code === 200) {
this.dataSubGraphData.push(res.data)
let arr = this.fnHandleToSubData()
arr = deduplication(arr, 'lineName')
this.$store.commit('graphData/CHANGE_DATA_SUB_GRAPH_DATA', arr)
console.log('arr', arr)
this.$refs['graph'].initDataSubjectRelationshipGraph()
}
})
} else {
this.dataSubGraphData = this.dataSubGraphData.filter(v => v.id != data.id)
let arr = this.fnHandleToSubData()
arr = deduplication(arr, 'lineName')
this.$store.commit('graphData/CHANGE_DATA_SUB_GRAPH_DATA', arr)
this.$refs['graph'].initDataSubjectRelationshipGraph()
}
},
fnHandleToSubData() {
const checkedNodeKeys = this.getCheckedKeys()
let arr = []
this.dataSubGraphData.forEach(v => {
const targetList = JSON.parse(v.targetAsset)
targetList.forEach(t => {
if(checkedNodeKeys.includes(t.asset_id)) {
arr.push({
lineName: t.rela_name,
targetName: t.asset_name,
sourceName: v.assetName
})
}
})
})
return arr
},
// 业务能力视图成图数据逻辑
handleBusGraph() {
const checkedNodes = this.$refs.tree.getCheckedNodes()
this.graphData = checkedNodes.filter((v) => v.parentId === '0')
const addNodes = this.addData.filter((v) => v.parentId === '0')
const childNodes = checkedNodes.filter((v) => v.parentId !== '0')
this.handleGraphData(this.graphData, childNodes)
console.log('this.graphData', this.graphData)
this.$store.commit('graphData/CHANGE_GRAPH_DATA', this.graphData)
const addChildNodes = this.addData.filter((v) => v.parentId !== '0')
const showGraphData = [...this.graphData, ...addNodes]
this.handleGraphData(showGraphData, [...childNodes, ...addChildNodes])
console.log('showGraphData', showGraphData)
this.$store.commit('graphData/CHANGE_GRAPH_DATA', showGraphData)
this.$refs['graph'].init()
},
handleGraphData(parentNodes, childNodes) {
......@@ -133,10 +386,14 @@ export default {
})
},
getCheckedKeys() {
console.log(this.$refs.tree.getCheckedKeys())
return this.$refs.tree.getCheckedKeys()
},
fnGetAutomaticGraphing() {
getAutomaticGraphing({ archiBelongId: this.activeName }).then((res) => {
const params = {
archiBelongId: this.activeName,
parentAssetId: this.activeName === '3' ? '0' : undefined,
}
getAutomaticGraphing(params).then((res) => {
if (res.code == 200) {
this.treeData = res.data
}
......@@ -149,8 +406,14 @@ export default {
handleNodeClick(data) {
const node = this.$refs.tree.getNode(data.id)
console.log('data', data)
console.log('node',node)
console.log('node', node)
this.setNode(node)
this.tableData = [...this.$refs.tree.getCheckedNodes(), ...this.addData]
if (!this.tableData.length) {
this.$refs['graph'].clear()
} else {
this.handleDataToGraph(data, node)
}
},
setNode(node) {
if (node.checked) {
......@@ -182,12 +445,13 @@ export default {
}
</script>
<style scoped lang="scss">
@import '@/styles/transition.scss';
.dataMapping {
margin: 16px;
flex-direction: column;
display: flex;
.left-content {
width: 335px;
width: 235px;
height: 100%;
// overflow-y: auto;
margin: 0 10px;
......@@ -200,14 +464,36 @@ export default {
}
}
.right-content {
width: 0;
height: 100%;
box-sizing: border-box;
background-color: rgb(255, 255, 255);
background-position: -1px -1px;
box-shadow: 0px 0px 2px 1px #d1d1d1;
overflow: auto;
position: relative;
.graphContent {
width: 50%;
overflow: auto;
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHBhdHRlcm4gaWQ9ImdyaWQiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZD0iTSAwIDEwIEwgNDAgMTAgTSAxMCAwIEwgMTAgNDAgTSAwIDIwIEwgNDAgMjAgTSAyMCAwIEwgMjAgNDAgTSAwIDMwIEwgNDAgMzAgTSAzMCAwIEwgMzAgNDAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2QwZDBkMCIgb3BhY2l0eT0iMC4yIiBzdHJva2Utd2lkdGg9IjEiLz48cGF0aCBkPSJNIDQwIDAgTCAwIDAgMCA0MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZDBkMGQwIiBzdHJva2Utd2lkdGg9IjEiLz48L3BhdHRlcm4+PC9kZWZzPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JpZCkiLz48L3N2Zz4=');
}
.collapse {
right: 50%;
width: 30px;
height: 30px;
top: 50%;
position: absolute;
cursor: pointer;
z-index: 10;
transition: transform 0.5s;
}
&.hide-left {
.collapse {
left: 0;
transform: rotate(180deg);
}
}
}
/deep/ .el-tree {
flex: 1;
min-height: 0;
......
/*
* @Description: 业务能力视图逻辑
* @Version: 2.0
* @Autor: pan
* @Date: 2024-04-28 11:05:28
* @LastEditors: pan
* @LastEditTime: 2024-04-28 16:01:35
*/
const businessCapabilityGraphMixin = {
computed: {
mockData() {
return this.$store.state.graphData.graphData
},
},
methods: {
init() {
this.graphData = [
{
name: '业务能力视图',
children: this.mockData,
},
]
console.log('mockData', this.mockData)
// mxgraph 被暴露在window下,所以可以直接调用
const parent = this.graph.getDefaultParent()
this.graph.removeCells(this.graph.getChildVertices(parent)) //清空画布
const model = this.graph.getModel()
var style = this.graph.getStylesheet().getDefaultVertexStyle()
// 禁止编辑文本
style[mxConstants.STYLE_EDITABLE] = false
// 启动一次更新会话
model.beginUpdate()
try {
//设置元素可编辑,不然无法自动布局
this.graph.setCellsLocked(false)
// 插入一个矩形
const v1 = this.graph.insertVertex(
parent,
null,
this.graphData[0].name,
20,
20,
null,
null,
'html=1;fontColor=#000000;fillColor=#dcf8e5;labelPosition=center;verticalAlign=top;align=center;strokeColor=#7fc2a0;',
)
this.insertVertex(v1, this.graphData[0].children)
// console.log(v1)
console.log('parent', parent)
// 子节点宽高调整
this.setGeometry(parent.children[0].children)
// 重新调整整体布局
const allCellData = parent.children[0].children
// 获取业务域最大宽度
let maxWidthArr = []
allCellData.forEach((v) => {
const currentItem = model.getGeometry(v)
maxWidthArr.push(currentItem.width || 100)
})
const maxWidth = Math.max(...maxWidthArr)
var geometry = model.getGeometry(parent.children[0])
let maxHeightArr = []
allCellData.forEach((v, i) => {
// 每个宽度统一成最大宽度的那一个
let currentMiddleItemGeometry = model.getGeometry(v)
currentMiddleItemGeometry.width = maxWidth
// 当前所属行
const row = Math.ceil((i + 1) / 3)
// 当前行的高度统一
const currentRowCol3 = allCellData[row * 3 - 1]
? model.getGeometry(allCellData[row * 3 - 1]).height
: 0
const currentRowCol2 = allCellData[row * 3 - 2]
? model.getGeometry(allCellData[row * 3 - 2]).height
: 0
const currentRowCol1 = allCellData[row * 3 - 3]
? model.getGeometry(allCellData[row * 3 - 3]).height
: 0
const currentRowMaxHeight = Math.max(
...[currentRowCol3, currentRowCol2, currentRowCol1],
)
// console.log('currentRowMaxHeight', currentRowMaxHeight)
currentMiddleItemGeometry.height = currentRowMaxHeight || 80
if ((i + 1) % 3 === 1) {
maxHeightArr.push(currentRowMaxHeight || 80)
}
if (i > 2) {
// 取当前所属行的上一行的3个,取最大高度,来设置y
const lastRowCol3 = model.getGeometry(
allCellData[(row - 1) * 3 - 1],
)
const lastRowCol2 = model.getGeometry(
allCellData[(row - 1) * 3 - 2],
)
const lastRowCol1 = model.getGeometry(
allCellData[(row - 1) * 3 - 3],
)
const lastRowMaxHeight = Math.max(
...[lastRowCol3.height, lastRowCol2.height, lastRowCol1.height],
)
// 上一行的y
const lastRowY = model.getGeometry(allCellData[(row - 1) * 3 - 3]).y
currentMiddleItemGeometry.y = lastRowY + lastRowMaxHeight + 20
if ((i + 1) % 3 === 1) {
currentMiddleItemGeometry.x = lastRowCol1.x
} else if ((i + 1) % 3 === 2) {
currentMiddleItemGeometry.x = lastRowCol2.x
} else {
currentMiddleItemGeometry.x = lastRowCol3.x
}
// console.log('currentMiddleItemGeometry.y', currentMiddleItemGeometry.y)
} else {
if (i > 0) {
const last = model.getGeometry(allCellData[i - 1])
currentMiddleItemGeometry.x = last.x + last.width + 20
}
}
})
// 调整父节点宽高
if (allCellData.length > 2) {
geometry.width = maxWidth * 3 + 80
} else {
geometry.width =
maxWidth * allCellData.length + (allCellData.length - 1) * 20 + 40
}
const sum = maxHeightArr.reduce((a, b) => a + b, 0)
console.log('sum', sum, maxHeightArr)
geometry.height = sum + maxHeightArr.length * 20 + 20
} finally {
model.endUpdate()
// 获取xml
var encoder = new mxCodec()
var node = encoder.encode(model)
console.log('node', node)
}
},
insertVertex(node, list) {
if (list && list.length) {
list.forEach((v, idx) => {
var cell = this.graph.insertVertex(
node,
null,
v.name,
this.getItemX(v, idx),
this.getItemY(v, idx),
// idx > 2 ? getItemY(idx, v.children) + 20 : 20,
v.checkChildren ? null : 100,
v.checkChildren ? null : 40,
`html=1;fontColor=#000000;fillColor=${
v.checkChildren ? '#dcf8e5' : '#f2fcf5'
};labelPosition=center;verticalAlign=${
v.checkChildren ? 'top' : 'middle'
};align=center;strokeColor=#7fc2a0;`,
)
// console.log('cell', cell)
if (v.checkChildren && v.checkChildren.length) {
this.insertVertex(cell, v.checkChildren)
}
})
}
},
// 计算cell的x坐标
getItemX(item, idx) {
console.log('item', item, idx)
if (item.children) {
// return idx * (130 * 3) + 20
const col = (idx + 1) % 3
// console.log('col', idx, col)
// console.log('---', col > 0 ? col * (110 * 3) + 20 : 3 * (110 * 3) + 20 )
return col > 0 ? (col - 1) * (130 * 3) + 20 : 2 * (130 * 3) + 20
} else {
if (idx > 2) {
if ((idx + 1) % 3 === 1) {
return 20
} else if ((idx + 1) % 3 === 2) {
if (Array.isArray(item.checkChildren)) {
return 410
} else {
return 140
}
// return 140 // 410
} else {
if (Array.isArray(item.checkChildren)) {
return 380 * 2 + 40
} else {
return 2 * 100 + 60
}
// return 2 * 140 + 20 // 380 * 2 + 40
}
} else {
// if(Array.isArray(item.checkChildren)) {
// return 380 * idx + 40
// } else {
return idx * 120 + 20
// }
}
}
},
getItemY(item, idx) {
const rows = Math.ceil((idx + 1) / 3)
if (item.children) {
return 20
// const h = Math.ceil(item.children.length / 3)
// if (idx > 2) {
// return rows * (h * 50) + 20
// } else {
// return 30
// }
} else {
if (idx > 2) {
if (rows > 2) {
return rows * 40 + (rows - 2) * 20
} else {
return rows * 40
}
} else {
return 20
}
}
},
setGeometry(list) {
for (let index = 0; index < list.length; index++) {
const v = list[index]
if (!v.children) {
let geometry = this.model.getGeometry(v)
geometry.height = 60
return
}
// console.log('v', v)
let geometry = this.model.getGeometry(v)
geometry.height += 20
geometry.width += 20
}
},
},
}
export default businessCapabilityGraphMixin
/*
* @Description: 数据主题关系视图逻辑
* @Version: 2.0
* @Autor: pan
* @Date: 2024-04-28 11:10:26
* @LastEditors: pan
* @LastEditTime: 2024-04-28 17:02:34
*/
// const items = [
// '财务',
// '人员',
// '项目',
// '物资',
// '资产',
// '市场',
// '客户',
// '电网',
// '综合',
// '安全',
// ]
// const mockData = [
// {
// sourceName: '财务',
// targetName: '人员',
// lineName: '经营管理费用',
// },
// {
// sourceName: '财务',
// targetName: '项目',
// lineName: '项目成本控制',
// },
// {
// sourceName: '财务',
// targetName: '物资',
// lineName: '物资核算',
// },
// {
// sourceName: '财务',
// targetName: '资产',
// lineName: '资产核算',
// },
// {
// sourceName: '财务',
// targetName: '市场',
// lineName: '交易结算',
// },
// {
// sourceName: '财务',
// targetName: '客户',
// lineName: '电费结算',
// },
// {
// sourceName: '人员',
// targetName: '项目',
// lineName: '项目执行',
// },
// {
// sourceName: '人员',
// targetName: '资产',
// lineName: '归属、运维、操作',
// },
// {
// sourceName: '人员',
// targetName: '电网',
// lineName: '调控',
// },
// {
// sourceName: '人员',
// targetName: '安全',
// lineName: '人身安全',
// },
// {
// sourceName: '项目',
// targetName: '物资',
// lineName: '项目物资',
// },
// {
// sourceName: '项目',
// targetName: '资产',
// lineName: '项目资产',
// },
// {
// sourceName: '项目',
// targetName: '综合',
// lineName: '规划',
// },
// {
// sourceName: '物资',
// targetName: '资产',
// lineName: '库存',
// },
// {
// sourceName: '资产',
// targetName: '客户',
// lineName: '协议',
// },
// {
// sourceName: '资产',
// targetName: '电网',
// lineName: '运行',
// },
// {
// sourceName: '市场',
// targetName: '客户',
// lineName: '电力需求',
// },
// {
// sourceName: '客户',
// targetName: '电网',
// lineName: '电能服务',
// },
// {
// sourceName: '电网',
// targetName: '安全',
// lineName: '电网结构、运行安全',
// },
// ]
const dataSubjectRelationshipGraphMixin = {
data() {
return {
// dataSubjectRelationshipData: []
}
},
computed: {
items() {
const arr = this.dataSubGraphData || []
let itemArr = []
if(arr.length) {
arr.forEach(v => {
itemArr.push(v.sourceName)
itemArr.push(v.targetName)
})
return Array.from(new Set(itemArr))
} else {
return []
}
},
dataSubGraphData() {
return this.$store.state.graphData.dataSubjectRelationshipGraphData
},
},
methods: {
initDataSubjectRelationshipGraph() {
const parent = this.graph.getDefaultParent()
this.graph.removeCells(this.graph.getChildVertices(parent)) //清空画布
const model = this.graph.getModel()
var style = this.graph.getStylesheet().getDefaultVertexStyle()
// 禁止编辑文本
style[mxConstants.STYLE_EDITABLE] = false
console.log('model', model)
// 启动一次更新会话
model.beginUpdate()
var shapeList = {}
try {
//设置元素可编辑,不然无法自动布局
this.graph.setCellsLocked(false)
// graph.setTooltips(true)
// graph.setAllowDanglingEdges(false)
// graph.setMultigraph(true)
this.items.forEach((item, i) => {
shapeList['v' + i] = this.graph.insertVertex(
parent,
null,
item,
20,
20,
120,
40,
'html=1;fontColor=#000000;fillColor=#ffff00;labelPosition=center;verticalAlign=middle;align=center;strokeColor=#000;',
)
})
console.log('shapeList', shapeList)
this.dataSubGraphData.forEach((v) => {
let [source, target] = [null, null]
for (const key in shapeList) {
if (Object.hasOwnProperty.call(shapeList, key)) {
const element = shapeList[key]
if (element.value === v.sourceName) {
source = element
}
if (element.value === v.targetName) {
target = element
}
}
}
// 连接矩形
this.graph.insertEdge(
parent,
null,
v.lineName,
source,
target,
'endArrow=none;fontColor=#666;strokeColor=#666;rounded=0',
)
})
var layout = new mxHierarchicalLayout(this.graph, mxConstants.DIRECTION_WEST) //水平流
// var layout = new mxFastOrganicLayout(this.graph, false)
// layout.forceConstant = 100
// console.info(mxHierarchicalLayout)
// var layout = new mxHierarchicalLayout(graph,mxConstants.DIRECTION_NORTH); //垂直流
// var layout = new mxCircleLayout(this.graph); // 圆形
// var layout = new mxCompactTreeLayout(this.graph);
// layout.levelDistance = 330;
// layout.nodeDistance = 150
// layout.edgeRouting = false;
layout.execute(this.graph.getDefaultParent())
this.graph.fit();//自适应
this.graph.center(true,true,0.2,0.3);// 调整整体图形位于画布的位置
var sc = this.graph.getView().getScale();//获取当前的缩放比例
this.graph.zoomTo(Math.round(sc/2));//在缩放一半,否则是满屏状态,不好看
} finally {
model.endUpdate()
// 获取xml
var encoder = new mxCodec()
var node = encoder.encode(model)
console.log('node', node)
}
},
},
}
export default dataSubjectRelationshipGraphMixin
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!