123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- <template>
- <div ref="graphContainerRef" class="mxgraph-container"></div>
- </template>
- <script setup lang="ts">
- import { myMxGraph, myMxRubberband, myMxConstants, myMxEvent, myMxPopupMenu } from '@/graph/mxGraph'
- const graphContainerRef = ref<HTMLElement | null>(null)
- const graphInstance = ref<InstanceType<typeof myMxGraph> | null>(null)
- provide('mxgraph-instance', graphInstance)
- function initGraph(container: HTMLElement): InstanceType<typeof myMxGraph> {
- const graph = new myMxGraph(container)
- // 基本配置
- graph.setPanning(true)
- graph.setConnectable(true)
- new myMxRubberband(graph)
- // 配置样式
- configureStyles(graph)
- // 设置事件监听
- setupGraphListeners(graph)
- // 添加上下文菜单
- setupContextMenu(graph)
- // 初始示例图形
- createSampleGraph(graph)
- return graph
- }
- function configureStyles(graph: InstanceType<typeof myMxGraph>) {
- const style = graph.getStylesheet().getDefaultVertexStyle()
- Object.assign(style, {
- [myMxConstants.STYLE_SHAPE]: myMxConstants.SHAPE_RECTANGLE,
- [myMxConstants.STYLE_STROKECOLOR]: '#2d8cf0',
- [myMxConstants.STYLE_FILLCOLOR]: '#ffffff',
- [myMxConstants.STYLE_FONTCOLOR]: '#333333',
- [myMxConstants.STYLE_STROKEWIDTH]: 2
- })
- const edgeStyle = graph.getStylesheet().getDefaultEdgeStyle()
- Object.assign(edgeStyle, {
- [myMxConstants.STYLE_ENDARROW]: myMxConstants.ARROW_CLASSIC,
- [myMxConstants.STYLE_STROKECOLOR]: '#666666',
- [myMxConstants.STYLE_STROKEWIDTH]: 2
- })
- }
- function setupGraphListeners(graph: InstanceType<typeof myMxGraph>) {
- graph
- .getSelectionModel()
- .addListener(myMxConstants.EVENT_CHANGE, (_sender: unknown, evt: any) => {
- const cells = evt.getProperty('added')
- console.log('Selected cells:', cells)
- })
- graph.addListener(myMxConstants.EVENT_DOUBLE_CLICK, (_sender: unknown, evt: any) => {
- const cell = evt.getProperty('cell')
- if (cell) {
- const newValue = prompt('输入新值:', graph.convertValueToString(cell) || '')
- if (newValue !== null) {
- graph.getModel().setValue(cell, newValue)
- }
- }
- })
- }
- function setupContextMenu(graph: InstanceType<typeof myMxGraph>) {
- myMxEvent.disableContextMenu(graph.container)
- graph.addListener(myMxConstants.EVENT_CONTEXT_MENU, (_sender: unknown, evt: any) => {
- const cell = evt.getProperty('cell')
- evt.preventDefault()
- if (!cell) return
- const menu = new myMxPopupMenu((menu: any) => {
- menu.addItem('删除', null, () => {
- graph.removeCells([cell])
- })
- menu.addItem('复制', null, () => {
- graph.setSelectionCell(graph.cloneCell(cell))
- })
- })
- const pt = myMxEvent.getClientXY(evt.getEvent())
- menu.popup(pt.x, pt.y, null, evt.getEvent())
- })
- }
- function createSampleGraph(graph: InstanceType<typeof myMxGraph>) {
- const parent = graph.getDefaultParent()
- graph.getModel().beginUpdate()
- try {
- const v1 = graph.insertVertex(parent, null, '开始', 20, 20, 80, 40)
- const v2 = graph.insertVertex(parent, null, '步骤1', 20, 80, 80, 40)
- const v3 = graph.insertVertex(parent, null, '结束', 20, 140, 80, 40)
- graph.insertEdge(parent, null, '', v1, v2)
- graph.insertEdge(parent, null, '', v2, v3)
- } finally {
- graph.getModel().endUpdate()
- }
- }
- onMounted(async () => {
- if (graphContainerRef.value) {
- graphInstance.value = initGraph(graphContainerRef.value)
- }
- })
- </script>
- <style lang="scss" scoped>
- .mxgraph-container {
- flex: 1;
- height: calc(100vh - 90px);
- background: url('@/assets/graph/images/grid.gif');
- }
- </style>
|