8 changed files with 841 additions and 5 deletions
@ -0,0 +1,152 @@ |
|||||
|
<template> |
||||
|
<el-tabs v-model="activeName" style="margin-top: 8px"> |
||||
|
<el-tab-pane label="图谱" name="1"> |
||||
|
<treeNodeg6 ref="treeGraph" :mockData="mockData" /> |
||||
|
</el-tab-pane> |
||||
|
<el-tab-pane label="表格" name="2"> |
||||
|
<el-table |
||||
|
v-loading="loading" |
||||
|
:data="tableData" |
||||
|
@selection-change="handleSelectionChange" |
||||
|
border |
||||
|
style="width: 100%" |
||||
|
> |
||||
|
|
||||
|
<el-table-column label="代码编号" align="center" prop="codeNum" /> |
||||
|
<el-table-column label="代码名称" align="center" prop="codeName" /> |
||||
|
<el-table-column label="引用标准编号" align="center" prop="stdNum" /> |
||||
|
<el-table-column label="引用标准英文名" align="center" prop="stdCode" /> |
||||
|
<el-table-column label="引用标准中文名" align="center" prop="stdName" /> |
||||
|
<el-table-column label="引用字典编号" align="center" prop="dictNum" /> |
||||
|
<el-table-column label="引用字典英文名" align="center" prop="dictCode" /> |
||||
|
<el-table-column label="引用字典中文名" align="center" prop="dictName" /> |
||||
|
</el-table> |
||||
|
</el-tab-pane> |
||||
|
</el-tabs> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref, onMounted, nextTick } from "vue"; |
||||
|
import { getStdCodeMap } from "@/api/datastd/std"; |
||||
|
import treeNodeg6 from "./treeNodeg6.vue"; |
||||
|
|
||||
|
const activeName = ref("1"); // 默认打开图谱 |
||||
|
|
||||
|
const treeGraph = ref(null); |
||||
|
const tableData = ref([]); |
||||
|
const selections = ref([]); |
||||
|
const loading = ref(false); |
||||
|
const props = defineProps({ |
||||
|
rowData: { |
||||
|
type: Object, |
||||
|
required: false |
||||
|
} |
||||
|
|
||||
|
}); |
||||
|
// mocked data |
||||
|
const mockData = ref({ |
||||
|
id: "g1", |
||||
|
name: props.rowData.codeName, |
||||
|
count: 123456, |
||||
|
label: props.rowData.codeNum, |
||||
|
rate: 1.0, |
||||
|
status: "G", |
||||
|
variableValue: "代码", |
||||
|
variableUp: true, |
||||
|
children:[] |
||||
|
// children: [ |
||||
|
// { |
||||
|
// id: "g12", |
||||
|
// name: "发行机构类型", |
||||
|
// count: 123456, |
||||
|
// label: "iss_ins_type", |
||||
|
// rate: 1.0, |
||||
|
// status: "R", |
||||
|
// currency: "xx001", |
||||
|
// variableValue: "标准", |
||||
|
// variableUp: true, |
||||
|
// children: [ |
||||
|
// { |
||||
|
// id: "g121", |
||||
|
// name: "发行机构类型", |
||||
|
// collapsed: true, |
||||
|
// count: 123456, |
||||
|
// label: "iss_ins_type", |
||||
|
// rate: 1.0, |
||||
|
// status: "B", |
||||
|
// currency: "xx002", |
||||
|
// variableValue: "词典", |
||||
|
// variableUp: true, |
||||
|
// }, |
||||
|
// ], |
||||
|
// }, |
||||
|
// { |
||||
|
// id: "g13", |
||||
|
// name: "发行人编号", |
||||
|
// label: "issr_no", |
||||
|
// rate: 1, |
||||
|
// status: "R", |
||||
|
// currency: "xx002", |
||||
|
// variableValue: "标准", |
||||
|
// variableUp: true, |
||||
|
// }, |
||||
|
// ], |
||||
|
}); |
||||
|
|
||||
|
// 获取数据列表 |
||||
|
const getList = async () => { |
||||
|
loading.value = true; |
||||
|
try { |
||||
|
const response = await listStdCodemap(); |
||||
|
tableData.value = response.rows || []; |
||||
|
} finally { |
||||
|
loading.value = false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const handleSelectionChange = (selection) => { |
||||
|
selections.value = selection; |
||||
|
}; |
||||
|
|
||||
|
// 默认加载图谱 |
||||
|
onMounted(() => { |
||||
|
nextTick(() => { |
||||
|
|
||||
|
getStdCodeMap(props.rowData.id).then(response => { |
||||
|
mockData.value.children = response.data.children; |
||||
|
tableData.value = response.data.tableData; |
||||
|
if (treeGraph.value) { |
||||
|
treeGraph.value.refreshGraph(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
}); |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.app-container { |
||||
|
padding: 20px; |
||||
|
} |
||||
|
|
||||
|
.query-form-container { |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.el-table .el-input { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.form-container { |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.info-text { |
||||
|
font-size: 18px; |
||||
|
line-height: 1.6; |
||||
|
color: #333; |
||||
|
font-weight: 500; |
||||
|
display: inline-block; |
||||
|
width: 100%; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,564 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<div ref="container" id="container" class="graph-container"></div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { onMounted, ref } from 'vue'; |
||||
|
import G6 from '@antv/g6'; |
||||
|
import insertCss from 'insert-css'; |
||||
|
|
||||
|
insertCss(` |
||||
|
.g6-component-tooltip { |
||||
|
background-color: rgba(0,0,0, 0.65); |
||||
|
padding: 10px; |
||||
|
box-shadow: rgb(174, 174, 174) 0px 0px 10px; |
||||
|
width: fit-content; |
||||
|
color: #fff; |
||||
|
border-radius = 4px; |
||||
|
} |
||||
|
`); |
||||
|
|
||||
|
// mocked data |
||||
|
// const mockData = { |
||||
|
// id: 'g1', |
||||
|
// name: '发型机构类型代码', |
||||
|
// count: 123456, |
||||
|
// label: 'SYS049', |
||||
|
// // currency: '代码', |
||||
|
// rate: 1.0, |
||||
|
// status: 'G', |
||||
|
// // variableName: 'V1', |
||||
|
// variableValue:'代码', |
||||
|
// variableUp: true, |
||||
|
// children: [ |
||||
|
// { |
||||
|
// id: 'g12', |
||||
|
// name: '发行机构类型', |
||||
|
// count: 123456, |
||||
|
// label: 'iss_ins_type', |
||||
|
// rate: 1.0, |
||||
|
// status: 'R', |
||||
|
// currency: 'xx001', |
||||
|
// // variableName: 'V2', |
||||
|
// variableValue:'标准', |
||||
|
// variableUp: true, |
||||
|
// children: [ |
||||
|
// { |
||||
|
// id: 'g121', |
||||
|
// name: '发行机构类型', |
||||
|
// collapsed: true, |
||||
|
// count: 123456, |
||||
|
// label: 'iss_ins_type', |
||||
|
// rate: 1.0, |
||||
|
// status: 'B', |
||||
|
// currency: 'xx002', |
||||
|
// variableValue:'词典', |
||||
|
// variableUp: true, |
||||
|
|
||||
|
// }, |
||||
|
|
||||
|
// ], |
||||
|
// }, |
||||
|
// { |
||||
|
// id: 'g13', |
||||
|
// name: '发行人编号', |
||||
|
// label: 'issr_no', |
||||
|
// rate: 1, |
||||
|
// status: 'R', |
||||
|
// currency: 'xx002', |
||||
|
// // variableName: '标准', |
||||
|
// variableValue:'标准', |
||||
|
// variableUp: true, |
||||
|
|
||||
|
// } |
||||
|
|
||||
|
// ], |
||||
|
// }; |
||||
|
|
||||
|
const colors = { |
||||
|
B: '#5B8FF9', |
||||
|
R: '#F46649', |
||||
|
Y: '#EEBC20', |
||||
|
G: '#5BD8A6', |
||||
|
DI: '#A7A7A7', |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
export default { |
||||
|
name: 'G6TreeGraph', |
||||
|
props: { |
||||
|
// 这里声明传入的数据 prop,名称保持 mockData |
||||
|
mockData: { |
||||
|
type: Object, |
||||
|
required: true, |
||||
|
}, |
||||
|
}, |
||||
|
setup(props) { |
||||
|
const container = ref(null); |
||||
|
let graph = null; |
||||
|
// // 组件props配置 |
||||
|
const propsConfig = { |
||||
|
data: props.mockData, |
||||
|
config: { |
||||
|
padding: [20, 50], |
||||
|
defaultLevel: 3, |
||||
|
defaultZoom: 0.8, |
||||
|
modes: { default: ['zoom-canvas', 'drag-canvas'] }, |
||||
|
}, |
||||
|
}; |
||||
|
console.log(props.mockData,"mockDatamockDatamockData") |
||||
|
// 自定义节点和边的注册函数 |
||||
|
const registerFn = () => { |
||||
|
/** 自定义节点 **/ |
||||
|
G6.registerNode( |
||||
|
'flow-rect', |
||||
|
{ |
||||
|
shapeType: 'flow-rect', |
||||
|
draw(cfg, group) { |
||||
|
const { |
||||
|
name = '', |
||||
|
variableName, |
||||
|
variableValue, |
||||
|
variableUp, |
||||
|
label, |
||||
|
collapsed, |
||||
|
currency, |
||||
|
status, |
||||
|
rate, |
||||
|
} = cfg; |
||||
|
|
||||
|
const grey = '#CED4D9'; |
||||
|
const rectConfig = { |
||||
|
width: 202, |
||||
|
height: 60, |
||||
|
lineWidth: 1, |
||||
|
fontSize: 12, |
||||
|
fill: '#fff', |
||||
|
radius: 4, |
||||
|
stroke: grey, |
||||
|
opacity: 1, |
||||
|
}; |
||||
|
|
||||
|
const nodeOrigin = { |
||||
|
x: -rectConfig.width / 2, |
||||
|
y: -rectConfig.height / 2, |
||||
|
}; |
||||
|
|
||||
|
const textConfig = { |
||||
|
textAlign: 'left', |
||||
|
textBaseline: 'bottom', |
||||
|
}; |
||||
|
|
||||
|
const rect = group.addShape('rect', { |
||||
|
attrs: { |
||||
|
x: nodeOrigin.x, |
||||
|
y: nodeOrigin.y, |
||||
|
...rectConfig, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const rectBBox = rect.getBBox(); |
||||
|
|
||||
|
// label title |
||||
|
group.addShape('text', { |
||||
|
attrs: { |
||||
|
...textConfig, |
||||
|
x: 12 + nodeOrigin.x, |
||||
|
y: 20 + nodeOrigin.y, |
||||
|
text: name.length > 28 ? name.substr(0, 28) + '...' : name, |
||||
|
fontSize: 12, |
||||
|
opacity: 0.85, |
||||
|
fill: '#000', |
||||
|
cursor: 'pointer', |
||||
|
}, |
||||
|
name: 'name-shape', |
||||
|
}); |
||||
|
|
||||
|
// price |
||||
|
const price = group.addShape('text', { |
||||
|
attrs: { |
||||
|
...textConfig, |
||||
|
x: 12 + nodeOrigin.x, |
||||
|
y: rectBBox.maxY - 12, |
||||
|
text: label, |
||||
|
fontSize: 16, |
||||
|
fill: '#000', |
||||
|
opacity: 0.85, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
// label currency |
||||
|
group.addShape('text', { |
||||
|
attrs: { |
||||
|
...textConfig, |
||||
|
x: price.getBBox().maxX + 5, |
||||
|
y: rectBBox.maxY - 12, |
||||
|
text: currency, |
||||
|
fontSize: 12, |
||||
|
fill: '#000', |
||||
|
opacity: 0.75, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
// percentage |
||||
|
const percentText = group.addShape('text', { |
||||
|
attrs: { |
||||
|
...textConfig, |
||||
|
x: rectBBox.maxX - 8, |
||||
|
y: rectBBox.maxY - 12, |
||||
|
// text: `${((variableValue || 0) * 100).toFixed(2)}%`, |
||||
|
text: variableValue, |
||||
|
fontSize: 12, |
||||
|
textAlign: 'right', |
||||
|
fill: colors[status], |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
// percentage triangle |
||||
|
const symbol = variableUp ? 'triangle' : 'triangle-down'; |
||||
|
const triangle = group.addShape('marker', { |
||||
|
attrs: { |
||||
|
...textConfig, |
||||
|
x: percentText.getBBox().minX - 10, |
||||
|
y: rectBBox.maxY - 12 - 6, |
||||
|
symbol, |
||||
|
r: 6, |
||||
|
fill: colors[status], |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
// variable name |
||||
|
group.addShape('text', { |
||||
|
attrs: { |
||||
|
...textConfig, |
||||
|
x: triangle.getBBox().minX - 4, |
||||
|
y: rectBBox.maxY - 12, |
||||
|
text: variableName, |
||||
|
fontSize: 12, |
||||
|
textAlign: 'right', |
||||
|
fill: '#000', |
||||
|
opacity: 0.45, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
// bottom line background |
||||
|
group.addShape('rect', { |
||||
|
attrs: { |
||||
|
x: nodeOrigin.x, |
||||
|
y: rectBBox.maxY - 4, |
||||
|
width: rectConfig.width, |
||||
|
height: 4, |
||||
|
radius: [0, 0, rectConfig.radius, rectConfig.radius], |
||||
|
fill: '#E0DFE3', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
// bottom percent |
||||
|
group.addShape('rect', { |
||||
|
attrs: { |
||||
|
x: nodeOrigin.x, |
||||
|
y: rectBBox.maxY - 4, |
||||
|
width: rate * rectBBox.width, |
||||
|
height: 4, |
||||
|
radius: [0, 0, 0, rectConfig.radius], |
||||
|
fill: colors[status], |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
// collapse rect |
||||
|
if (cfg.children && cfg.children.length) { |
||||
|
group.addShape('rect', { |
||||
|
attrs: { |
||||
|
x: rectConfig.width / 2 - 8, |
||||
|
y: -8, |
||||
|
width: 16, |
||||
|
height: 16, |
||||
|
stroke: 'rgba(0, 0, 0, 0.25)', |
||||
|
cursor: 'pointer', |
||||
|
fill: '#fff', |
||||
|
}, |
||||
|
name: 'collapse-back', |
||||
|
modelId: cfg.id, |
||||
|
}); |
||||
|
|
||||
|
// collapse text |
||||
|
group.addShape('text', { |
||||
|
attrs: { |
||||
|
x: rectConfig.width / 2, |
||||
|
y: -1, |
||||
|
textAlign: 'center', |
||||
|
textBaseline: 'middle', |
||||
|
text: collapsed ? '+' : '-', |
||||
|
fontSize: 16, |
||||
|
cursor: 'pointer', |
||||
|
fill: 'rgba(0, 0, 0, 0.25)', |
||||
|
}, |
||||
|
name: 'collapse-text', |
||||
|
modelId: cfg.id, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
this.drawLinkPoints(cfg, group); |
||||
|
return rect; |
||||
|
}, |
||||
|
update(cfg, item) { |
||||
|
const { level, status, name } = cfg; |
||||
|
const group = item.getContainer(); |
||||
|
let mask = group.find((ele) => ele.get('name') === 'mask-shape'); |
||||
|
let maskLabel = group.find((ele) => ele.get('name') === 'mask-label-shape'); |
||||
|
if (level === 0) { |
||||
|
group.get('children').forEach((child) => { |
||||
|
if (child.get('name')?.includes('collapse')) return; |
||||
|
child.hide(); |
||||
|
}); |
||||
|
if (!mask) { |
||||
|
mask = group.addShape('rect', { |
||||
|
attrs: { |
||||
|
x: -101, |
||||
|
y: -30, |
||||
|
width: 202, |
||||
|
height: 60, |
||||
|
opacity: 0, |
||||
|
fill: colors[status], |
||||
|
}, |
||||
|
name: 'mask-shape', |
||||
|
}); |
||||
|
maskLabel = group.addShape('text', { |
||||
|
attrs: { |
||||
|
fill: '#fff', |
||||
|
fontSize: 20, |
||||
|
x: 0, |
||||
|
y: 10, |
||||
|
text: name.length > 28 ? name.substr(0, 16) + '...' : name, |
||||
|
textAlign: 'center', |
||||
|
opacity: 0, |
||||
|
}, |
||||
|
name: 'mask-label-shape', |
||||
|
}); |
||||
|
const collapseRect = group.find((ele) => ele.get('name') === 'collapse-back'); |
||||
|
const collapseText = group.find((ele) => ele.get('name') === 'collapse-text'); |
||||
|
collapseRect?.toFront(); |
||||
|
collapseText?.toFront(); |
||||
|
} else { |
||||
|
mask.show(); |
||||
|
maskLabel.show(); |
||||
|
} |
||||
|
mask.animate({ opacity: 1 }, 200); |
||||
|
maskLabel.animate({ opacity: 1 }, 200); |
||||
|
return mask; |
||||
|
} else { |
||||
|
group.get('children').forEach((child) => { |
||||
|
if (child.get('name')?.includes('collapse')) return; |
||||
|
child.show(); |
||||
|
}); |
||||
|
mask?.animate({ opacity: 0 }, { |
||||
|
duration: 200, |
||||
|
callback: () => mask.hide(), |
||||
|
}); |
||||
|
maskLabel?.animate({ opacity: 0 }, { |
||||
|
duration: 200, |
||||
|
callback: () => maskLabel.hide(), |
||||
|
}); |
||||
|
} |
||||
|
this.updateLinkPoints(cfg, group); |
||||
|
}, |
||||
|
setState(name, value, item) { |
||||
|
if (name === 'collapse') { |
||||
|
const group = item.getContainer(); |
||||
|
const collapseText = group.find((e) => e.get('name') === 'collapse-text'); |
||||
|
if (collapseText) { |
||||
|
if (!value) { |
||||
|
collapseText.attr({ text: '-' }); |
||||
|
} else { |
||||
|
collapseText.attr({ text: '+' }); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
getAnchorPoints() { |
||||
|
return [ |
||||
|
[0, 0.5], |
||||
|
[1, 0.5], |
||||
|
]; |
||||
|
}, |
||||
|
}, |
||||
|
'rect' |
||||
|
); |
||||
|
|
||||
|
G6.registerEdge( |
||||
|
'flow-cubic', |
||||
|
{ |
||||
|
getControlPoints(cfg) { |
||||
|
let controlPoints = cfg.controlPoints; |
||||
|
if (!controlPoints || !controlPoints.length) { |
||||
|
const { startPoint, endPoint, sourceNode, targetNode } = cfg; |
||||
|
const { x: startX, y: startY, coefficientX, coefficientY } = sourceNode |
||||
|
? sourceNode.getModel() |
||||
|
: startPoint; |
||||
|
const { x: endX, y: endY } = targetNode ? targetNode.getModel() : endPoint; |
||||
|
let curveStart = (endX - startX) * coefficientX; |
||||
|
let curveEnd = (endY - startY) * coefficientY; |
||||
|
curveStart = curveStart > 40 ? 40 : curveStart; |
||||
|
curveEnd = curveEnd < -30 ? curveEnd : -30; |
||||
|
controlPoints = [ |
||||
|
{ x: startPoint.x + curveStart, y: startPoint.y }, |
||||
|
{ x: endPoint.x + curveEnd, y: endPoint.y }, |
||||
|
]; |
||||
|
} |
||||
|
return controlPoints; |
||||
|
}, |
||||
|
getPath(points) { |
||||
|
const path = []; |
||||
|
path.push(['M', points[0].x, points[0].y]); |
||||
|
path.push([ |
||||
|
'C', |
||||
|
points[1].x, |
||||
|
points[1].y, |
||||
|
points[2].x, |
||||
|
points[2].y, |
||||
|
points[3].x, |
||||
|
points[3].y, |
||||
|
]); |
||||
|
return path; |
||||
|
}, |
||||
|
}, |
||||
|
'single-line' |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
// 初始化图表 |
||||
|
const initGraph = (data) => { |
||||
|
if (!data) { |
||||
|
return; |
||||
|
} |
||||
|
const { onInit, config } = propsConfig; |
||||
|
const tooltip = new G6.Tooltip({ |
||||
|
offsetX: 20, |
||||
|
offsetY: 30, |
||||
|
itemTypes: ['node'], |
||||
|
getContent: (e) => { |
||||
|
const outDiv = document.createElement('div'); |
||||
|
const nodeName = e.item.getModel().name; |
||||
|
let formatedNodeName = ''; |
||||
|
for (let i = 0; i < nodeName.length; i++) { |
||||
|
formatedNodeName = `${formatedNodeName}${nodeName[i]}`; |
||||
|
if (i !== 0 && i % 20 === 0) |
||||
|
formatedNodeName = `${formatedNodeName}<br/>`; |
||||
|
} |
||||
|
outDiv.innerHTML = `${formatedNodeName}`; |
||||
|
return outDiv; |
||||
|
}, |
||||
|
shouldBegin: (e) => { |
||||
|
if ( |
||||
|
e.target.get('name') === 'name-shape' || |
||||
|
e.target.get('name') === 'mask-label-shape' |
||||
|
) |
||||
|
return true; |
||||
|
return false; |
||||
|
}, |
||||
|
}); |
||||
|
graph = new G6.TreeGraph({ |
||||
|
container: container.value, |
||||
|
...defaultConfig(), |
||||
|
...config, |
||||
|
plugins: [tooltip], |
||||
|
}); |
||||
|
if (typeof onInit === 'function') { |
||||
|
onInit(graph); |
||||
|
} |
||||
|
graph.data(data); |
||||
|
graph.render(); |
||||
|
|
||||
|
const handleCollapse = (e) => { |
||||
|
const target = e.target; |
||||
|
const id = target.get('modelId'); |
||||
|
const item = graph.findById(id); |
||||
|
const nodeModel = item.getModel(); |
||||
|
nodeModel.collapsed = !nodeModel.collapsed; |
||||
|
graph.layout(); |
||||
|
graph.setItemState(item, 'collapse', nodeModel.collapsed); |
||||
|
}; |
||||
|
graph.on('collapse-text:click', (e) => { |
||||
|
handleCollapse(e); |
||||
|
}); |
||||
|
graph.on('collapse-back:click', (e) => { |
||||
|
handleCollapse(e); |
||||
|
}); |
||||
|
|
||||
|
let currentLevel = 1; |
||||
|
const briefZoomThreshold = Math.max(graph.getZoom(), 0.5); |
||||
|
graph.on('viewportchange', (e) => { |
||||
|
if (e.action !== 'zoom') return; |
||||
|
const currentZoom = graph.getZoom(); |
||||
|
let toLevel = currentLevel; |
||||
|
if (currentZoom < briefZoomThreshold) { |
||||
|
toLevel = 0; |
||||
|
} else { |
||||
|
toLevel = 1; |
||||
|
} |
||||
|
if (toLevel !== currentLevel) { |
||||
|
currentLevel = toLevel; |
||||
|
graph.getNodes().forEach((node) => { |
||||
|
graph.updateItem(node, { level: toLevel }); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
// 默认配置,根据 container 的宽高动态生成 |
||||
|
const defaultConfig = () => { |
||||
|
const width = container.value.scrollWidth; |
||||
|
const height = container.value.scrollHeight || 500; |
||||
|
return { |
||||
|
width, |
||||
|
height, |
||||
|
modes: { |
||||
|
default: ['zoom-canvas', 'drag-canvas'], |
||||
|
}, |
||||
|
fitView: true, |
||||
|
animate: true, |
||||
|
defaultNode: { |
||||
|
type: 'flow-rect', |
||||
|
}, |
||||
|
defaultEdge: { |
||||
|
type: 'cubic-horizontal', |
||||
|
style: { |
||||
|
stroke: '#CED4D9', |
||||
|
}, |
||||
|
}, |
||||
|
layout: { |
||||
|
type: 'indented', |
||||
|
direction: 'LR', |
||||
|
dropCap: false, |
||||
|
indent: 300, |
||||
|
getHeight: () => 60, |
||||
|
}, |
||||
|
}; |
||||
|
}; |
||||
|
const refreshGraph = () => { |
||||
|
nextTick(() => { |
||||
|
registerFn(); |
||||
|
initGraph(propsConfig.data); |
||||
|
window.onresize = () => { |
||||
|
if (!graph || graph.get('destroyed')) return; |
||||
|
if (!container.value || !container.value.scrollWidth || !container.value.scrollHeight) |
||||
|
return; |
||||
|
graph.changeSize(container.value.scrollWidth, container.value.scrollHeight); |
||||
|
|
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
return { container ,refreshGraph }; |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.graph-container { |
||||
|
width: 100%; |
||||
|
height: 600px; |
||||
|
/* border: 1px solid #ddd; */ |
||||
|
} |
||||
|
</style> |
Loading…
Reference in new issue