From 656ea3139db54b8dc9a29b8cb239d0f0df9a6c05 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期二, 27 六月 2023 18:19:42 +0800 Subject: [PATCH] 2023-06-27 --- src/menu/components/chart/antv-X6/index.jsx | 594 +++++++--------------------------------------------------- 1 files changed, 75 insertions(+), 519 deletions(-) diff --git a/src/menu/components/chart/antv-X6/index.jsx b/src/menu/components/chart/antv-X6/index.jsx index 96e04e1..0cfcbf6 100644 --- a/src/menu/components/chart/antv-X6/index.jsx +++ b/src/menu/components/chart/antv-X6/index.jsx @@ -1,27 +1,20 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { is, fromJS } from 'immutable' -import { Popover, Tooltip, message } from 'antd' -import { ToolOutlined, DeleteOutlined, FontColorsOutlined, VerticalAlignTopOutlined, VerticalAlignBottomOutlined, SaveOutlined, ZoomInOutlined, ZoomOutOutlined, OneToOneOutlined, DoubleLeftOutlined, DownloadOutlined } from '@ant-design/icons' +import { Popover, Tooltip } from 'antd' +import { ToolOutlined, DeleteOutlined, FontColorsOutlined, VerticalAlignTopOutlined, VerticalAlignBottomOutlined, SaveOutlined, ZoomInOutlined, ZoomOutOutlined, OneToOneOutlined, DownloadOutlined } from '@ant-design/icons' import { Graph, Shape } from '@antv/x6' -import { Stencil } from '@antv/x6-plugin-stencil' -import { Transform } from '@antv/x6-plugin-transform' -import { Selection } from '@antv/x6-plugin-selection' -import { Snapline } from '@antv/x6-plugin-snapline' -import { Keyboard } from '@antv/x6-plugin-keyboard' -import { Clipboard } from '@antv/x6-plugin-clipboard' -import { History } from '@antv/x6-plugin-history' -import { Export } from '@antv/x6-plugin-export' import MKEmitter from '@/utils/events.js' import asyncComponent from '@/utils/asyncComponent' import asyncIconComponent from '@/utils/asyncIconComponent' import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js' +import lanes from './lane.json' +import xflows from './xflow.json' import './index.scss' const SettingComponent = asyncIconComponent(() => import('@/menu/datasource')) const ChartCompileForm = asyncIconComponent(() => import('./chartcompile')) -const NodeUpdate = asyncIconComponent(() => import('./nodeupdate')) const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) @@ -115,7 +108,7 @@ }, 'name-rect': { width: 200, - height: 30, + height: 36, fill: '#5F95FF', stroke: '#fff', strokeWidth: 1, @@ -128,9 +121,10 @@ textAnchor: 'middle', fontWeight: 'bold', fill: '#fff', - fontSize: 12, + fontSize: 14, }, }, + zIndex: 0 }, true, ) @@ -144,8 +138,8 @@ attrs: { body: { strokeWidth: 1, - stroke: '#5F95FF', - fill: '#EFF4FF' + stroke: '#000000', + fill: '#FFFFFF' }, text: { fontSize: 12, @@ -174,8 +168,8 @@ attrs: { body: { strokeWidth: 1, - stroke: '#5F95FF', - fill: '#EFF4FF' + stroke: '#000000', + fill: '#FFFFFF' }, text: { fontSize: 12, @@ -204,8 +198,8 @@ attrs: { body: { strokeWidth: 1, - stroke: '#5F95FF', - fill: '#EFF4FF' + stroke: '#000000', + fill: '#FFFFFF' }, text: { fontSize: 12, @@ -234,8 +228,8 @@ attrs: { body: { strokeWidth: 1, - stroke: '#5F95FF', - fill: '#EFF4FF' + stroke: '#000000', + fill: '#FFFFFF' }, text: { fontSize: 12, @@ -264,8 +258,8 @@ points: '100,10 40,198 190,78 10,78 160,198', attrs: { body: { - fill: '#EFF4FF', - stroke: '#5F95FF', + fill: '#FFFFFF', + stroke: '#000000', strokeWidth: 1, fillRule: 'nonzero' }, @@ -287,6 +281,26 @@ true ) +Graph.registerNode( + 'mk-text', + { + inherit: 'rect', + width: 66, + height: 36, + attrs: { + body: { + strokeWidth: 0, + fill: 'transparent' + }, + text: { + fontSize: 12, + fill: '#262626' + } + } + }, + true +) + class antvX6Chart extends Component { static propTpyes = { card: PropTypes.object, @@ -295,15 +309,8 @@ } state = { - card: null, - eventListener: null, - toolunfold: true, - nodeunfold: true, - node: null + card: null } - - selectNode = null - mkGraph = null UNSAFE_componentWillMount () { const { card } = this.props @@ -311,7 +318,7 @@ if (card.isNew) { let _plot = { width: card.width || 24, - height: 400, + height: 500, subtype: card.subtype, name: card.name, grid: { @@ -322,7 +329,8 @@ thickness: 1 } }, - gridType: 'dot' + gridType: 'dot', + export: 'png' } let _card = { @@ -379,8 +387,8 @@ if ( card.plot.subtype !== res.plot.subtype || - card.plot.gridType !== res.plot.gridType || - card.plot.backgroundColor !== res.plot.backgroundColor + (res.plot.gridType && card.plot.gridType !== res.plot.gridType) || + (res.plot.gridType && card.plot.backgroundColor !== res.plot.backgroundColor) ) { let _element = document.getElementById(card.uuid + 'container') if (_element) { @@ -401,8 +409,6 @@ this.xflowrender() } else if (card.plot.subtype === 'lane') { this.lanerender() - // } else if (card.plot.subtype === 'xflow') { - // this.xflowrender() } } @@ -444,8 +450,8 @@ return new Shape.Edge({ attrs: { line: { - stroke: '#A2B1C3', - strokeWidth: 2, + stroke: '#000000', + strokeWidth: 1, targetMarker: { name: 'block', width: 12, @@ -473,190 +479,16 @@ } }) - // #region 浣跨敤鎻掍欢 - graph - .use(new Transform({ - resizing: true, - rotating: true - })) - .use(new Selection()) - .use(new Snapline()) - .use(new Keyboard()) - .use(new Clipboard()) - .use(new History()) - .use(new Export()) - - // #region 鍒濆鍖� stencil - const stencil = new Stencil({ - title: '娴佺▼鍥�', - target: graph, - stencilGraphWidth: 180, - stencilGraphHeight: 180, - groups: [ - { - title: '閫氱敤鑺傜偣', - name: 'group1' - }, - { - title: '鑷畾涔�', - name: 'group2', - graphHeight: 120, - layoutOptions: { - rowHeight: 70 - } - } - ], - layoutOptions: { - columns: 2, - columnWidth: 80, - rowHeight: 55 + let cells = [] + xflows.forEach((item) => { + if (item.shape === 'edge') { + cells.push(graph.createEdge(item)) + } else { + cells.push(graph.createNode(item)) } }) - - document.getElementById(card.uuid + 'stencil').appendChild(stencil.container) - - // #region 蹇嵎閿笌浜嬩欢 - graph.bindKey(['meta+c', 'ctrl+c'], () => { - const cells = graph.getSelectedCells() - if (cells.length) { - graph.copy(cells) - } - return false - }) - graph.bindKey(['meta+x', 'ctrl+x'], () => { - const cells = graph.getSelectedCells() - if (cells.length) { - graph.cut(cells) - } - return false - }) - graph.bindKey(['meta+v', 'ctrl+v'], () => { - if (!graph.isClipboardEmpty()) { - graph.paste({ offset: 32 }) - } - return false - }) - - // undo redo - graph.bindKey(['meta+z', 'ctrl+z'], () => { - if (graph.canUndo()) { - graph.undo() - } - return false - }) - graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => { - if (graph.canRedo()) { - graph.redo() - } - return false - }) - - // 鍒犻櫎鍏冪礌 - graph.bindKey(['backspace', 'delete'], () => { - const cells = graph.getSelectedCells() - if (cells.length) { - graph.removeCells(cells) - this.selectNode = null - this.setState({node: null}) - } - }) - - // 鎺у埗杩炴帴妗╂樉绀�/闅愯棌 - const showPorts = (ports, show) => { - for (let i = 0, len = ports.length; i < len; i += 1) { - ports[i].style.visibility = show ? 'visible' : 'hidden' - } - } - graph.on('node:mouseenter', () => { - const container = document.getElementById(card.uuid + 'container') - const ports = container.querySelectorAll('.x6-port-body') - showPorts(ports, true) - }) - graph.on('node:mouseleave', () => { - const container = document.getElementById(card.uuid + 'container') - const ports = container.querySelectorAll('.x6-port-body') - showPorts(ports, false) - }) - - graph.on('node:click', ({ e, x, y, node, view }) => { - this.selectNode = node - - this.setState({node: node.store.data}) - }) - graph.on('edge:click', ({ e, x, y, edge, view }) => { - this.selectNode = edge - - this.setState({node: edge.store.data}) - - graph.clearTransformWidgets() - }) - graph.on('blank:click', ({ e, x, y }) => { - this.selectNode = null - - this.setState({node: null}) - }) - - const r1 = graph.createNode({ - shape: 'mk-rect', - label: '寮�濮�', - attrs: { - body: { - rx: 20, - ry: 26 - } - } - }) - const r2 = graph.createNode({ - shape: 'mk-rect', - label: '杩囩▼' - }) - const r3 = graph.createNode({ - shape: 'mk-rect', - attrs: { - body: { - rx: 6, - ry: 6 - } - }, - label: '鍙�夎繃绋�' - }) - const r4 = graph.createNode({ - shape: 'mk-polygon', - attrs: { - body: { - refPoints: '0,10 10,0 20,10 10,20' - } - }, - label: '鍐崇瓥' - }) - const r5 = graph.createNode({ - shape: 'mk-polygon', - attrs: { - body: { - refPoints: '10,0 40,0 30,20 0,20' - } - }, - label: '鏁版嵁' - }) - const r6 = graph.createNode({ - shape: 'mk-circle', - label: '杩炴帴' - }) - - stencil.load([r1, r2, r3, r4, r5, r6], 'group1') - - const p1 = graph.createNode({ - shape: 'mk-ellipse', - label: 'ellipse' - }) - const p2 = graph.createNode({ - shape: 'mk-star', - label: '' - }) - - stencil.load([p1, p2], 'group2') - - this.mkGraph = graph + graph.resetCells(cells) + graph.positionContent('center') } lanerender = () => { @@ -664,16 +496,13 @@ const graph = new Graph({ container: document.getElementById(card.uuid + 'container'), - grid: card.plot.grid, scaling: { min: 0.5, max: 2 }, autoResize: true, panning: true, - background: { - color: card.plot.backgroundColor || 'transparent' - }, + background: { color: '#ffffff' }, mousewheel: { enabled: true, zoomAtMousePosition: true, @@ -697,8 +526,8 @@ return new Shape.Edge({ attrs: { line: { - stroke: '#A2B1C3', - strokeWidth: 2, + stroke: '#000000', + strokeWidth: 1, targetMarker: { name: 'block', width: 12, @@ -734,9 +563,9 @@ if (parentNode) { return parentNode.getBBox().moveAndExpand({ x: 0, - y: 30, + y: 36, width: 0, - height: -30, + height: -36, }) } } @@ -745,277 +574,16 @@ } }) - // #region 浣跨敤鎻掍欢 - graph - .use(new Transform({ - resizing: true, - rotating: true - })) - .use(new Selection()) - .use(new Snapline()) - .use(new Keyboard()) - .use(new Clipboard()) - .use(new History()) - .use(new Export()) - - // #region 鍒濆鍖� stencil - const stencil = new Stencil({ - title: '娴佺▼鍥�', - target: graph, - stencilGraphWidth: 180, - stencilGraphHeight: 180, - groups: [ - { - title: '閫氱敤鑺傜偣', - name: 'group1' - }, - { - title: '鑷畾涔�', - name: 'group2', - graphHeight: 120, - layoutOptions: { - rowHeight: 70 - } - } - ], - layoutOptions: { - columns: 2, - columnWidth: 80, - rowHeight: 55 - } - }) - - document.getElementById(card.uuid + 'stencil').appendChild(stencil.container) - - // #region 蹇嵎閿笌浜嬩欢 - graph.bindKey(['meta+c', 'ctrl+c'], () => { - const cells = graph.getSelectedCells() - if (cells.length) { - graph.copy(cells) - } - return false - }) - graph.bindKey(['meta+x', 'ctrl+x'], () => { - const cells = graph.getSelectedCells() - if (cells.length) { - graph.cut(cells) - } - return false - }) - graph.bindKey(['meta+v', 'ctrl+v'], () => { - if (!graph.isClipboardEmpty()) { - graph.paste({ offset: 32 }) - } - return false - }) - - // undo redo - graph.bindKey(['meta+z', 'ctrl+z'], () => { - if (graph.canUndo()) { - graph.undo() - } - return false - }) - graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => { - if (graph.canRedo()) { - graph.redo() - } - return false - }) - - // 鍒犻櫎鍏冪礌 - graph.bindKey(['backspace', 'delete'], () => { - const cells = graph.getSelectedCells() - if (cells.length) { - graph.removeCells(cells) - this.selectNode = null - this.setState({node: null}) - } - }) - - // 鎺у埗杩炴帴妗╂樉绀�/闅愯棌 - const showPorts = (ports, show) => { - for (let i = 0, len = ports.length; i < len; i += 1) { - ports[i].style.visibility = show ? 'visible' : 'hidden' - } - } - graph.on('node:mouseenter', () => { - const container = document.getElementById(card.uuid + 'container') - const ports = container.querySelectorAll('.x6-port-body') - showPorts(ports, true) - }) - graph.on('node:mouseleave', () => { - const container = document.getElementById(card.uuid + 'container') - const ports = container.querySelectorAll('.x6-port-body') - showPorts(ports, false) - }) - - graph.on('node:click', ({ e, x, y, node, view }) => { - this.selectNode = node - - this.setState({node: node.store.data}) - }) - graph.on('edge:click', ({ e, x, y, edge, view }) => { - this.selectNode = edge - - this.setState({node: edge.store.data}) - - graph.clearTransformWidgets() - }) - graph.on('blank:click', ({ e, x, y }) => { - this.selectNode = null - - this.setState({node: null}) - }) - - const r1 = graph.createNode({ - shape: 'mk-rect', - label: '寮�濮�', - attrs: { - body: { - rx: 20, - ry: 26 - } - } - }) - const r2 = graph.createNode({ - shape: 'mk-rect', - label: '杩囩▼' - }) - const r3 = graph.createNode({ - shape: 'mk-rect', - attrs: { - body: { - rx: 6, - ry: 6 - } - }, - label: '鍙�夎繃绋�' - }) - const r4 = graph.createNode({ - shape: 'mk-polygon', - attrs: { - body: { - refPoints: '0,10 10,0 20,10 10,20' - } - }, - label: '鍐崇瓥' - }) - const r5 = graph.createNode({ - shape: 'mk-polygon', - attrs: { - body: { - refPoints: '10,0 40,0 30,20 0,20' - } - }, - label: '鏁版嵁' - }) - const r6 = graph.createNode({ - shape: 'mk-circle', - label: '杩炴帴' - }) - - stencil.load([r1, r2, r3, r4, r5, r6], 'group1') - - const p1 = graph.createNode({ - shape: 'mk-ellipse', - label: 'ellipse' - }) - const p2 = graph.createNode({ - shape: 'mk-star', - label: '' - }) - - stencil.load([p1, p2], 'group2') - - let data = [{"id":"1","shape":"lane","width":200,"height":500,"position":{"x":60,"y":60},"label":"<Function>"},{"id":"2","shape":"lane","width":200,"height":500,"position":{"x":260,"y":60},"label":"<Function>"},{"id":"3","shape":"lane","width":200,"height":500,"position":{"x":460,"y":60},"label":"<Function>"},{"id":"4","shape":"lane","width":200,"height":500,"position":{"x":660,"y":60},"label":"<Function>"}] let cells = [] - data.forEach((item) => { - if (item.shape === 'lane-edge') { + lanes.forEach((item) => { + if (item.shape === 'edge') { cells.push(graph.createEdge(item)) } else { cells.push(graph.createNode(item)) } }) graph.resetCells(cells) - graph.zoomToFit({ padding: 10, maxScale: 1 }) - - this.mkGraph = graph - } - - setTop = () => { - if (!this.selectNode) { - message.warning('璇烽�夋嫨鑺傜偣锛�') - return - } - this.selectNode.toFront() - } - - setBottom = () => { - if (!this.selectNode) { - message.warning('璇烽�夋嫨鑺傜偣锛�') - return - } - // let cells = this.mkGraph.getCells() - this.selectNode.toBack() - } - - // zoom() 鍙幏鍙栨垨鑰呰缃缉鏀炬瘮渚� - setZoomIn = () => { - this.mkGraph.zoom(0.1) - } - - setZoomOut = () => { - this.mkGraph.zoom(-0.1) - } - - setZoomInt = () => { - this.mkGraph.zoomTo(1) - } - - save = () => { - // let nodes = this.mkGraph.toJSON() - } - - savePicture = () => { - const { card } = this.state - this.mkGraph.exportPNG(card.name, {padding: 20}) - } - - changeProps = (value, key) => { - const { node } = this.state - - if (node.shape === 'edge') { - if (key === 'title') { - this.selectNode.setLabels(value) - } else if (key === 'stroke') { - this.selectNode.attr('line/stroke', value) - } else if (key === 'strokeWidth') { - this.selectNode.attr('line/strokeWidth', value) - } else if (key === 'lineType') { - if (value === 'dash') { - this.selectNode.attr('line/strokeDasharray', 5) - } else { - this.selectNode.attr('line/strokeDasharray', 0) - } - } else if (key === 'fontSize') { - this.selectNode.attr('text/fontSize', value) - } else if (key === 'fontFill') { - this.selectNode.attr('text/fill', value) - } - } else { - if (key === 'title') { - this.selectNode.attr('text/text', value) - } else if (key === 'fill') { - this.selectNode.attr('body/fill', value) - } else if (key === 'stroke') { - this.selectNode.attr('body/stroke', value) - } else if (key === 'fontSize') { - this.selectNode.attr('text/fontSize', value) - } else if (key === 'fontFill') { - this.selectNode.attr('text/fill', value) - } - } + graph.positionContent('top') } updateComponent = (card) => { @@ -1061,7 +629,7 @@ } render() { - const { card, toolunfold, nodeunfold, node } = this.state + const { card } = this.state let _style = resetStyle(card.style) return ( @@ -1080,45 +648,33 @@ <NormalHeader config={card} updateComponent={this.updateComponent}/> <div className="mk-toolbar"> <div className="left-tool"> - <Tooltip title="缃墠"> - <VerticalAlignTopOutlined onClick={this.setTop}/> - </Tooltip> - <Tooltip title="缃悗"> - <VerticalAlignBottomOutlined onClick={this.setBottom}/> - </Tooltip> + {card.plot.subtype === 'xflow' ? <Tooltip title="缃墠"> + <VerticalAlignTopOutlined/> + </Tooltip> : null} + {card.plot.subtype === 'xflow' ? <Tooltip title="缃悗"> + <VerticalAlignBottomOutlined/> + </Tooltip> : null} <Tooltip title="淇濆瓨"> - <SaveOutlined onClick={this.save}/> + <SaveOutlined/> </Tooltip> - <Tooltip title="瀵煎嚭鍥剧墖"> - <DownloadOutlined onClick={this.savePicture}/> - </Tooltip> + {card.plot.export === 'png' ? <Tooltip title="瀵煎嚭鍥剧墖"> + <DownloadOutlined/> + </Tooltip> : null} </div> <div className="right-tool"> <Tooltip title="鏀惧ぇ"> - <ZoomInOutlined onClick={this.setZoomIn}/> + <ZoomInOutlined/> </Tooltip> <Tooltip title="缂╁皬"> - <ZoomOutOutlined onClick={this.setZoomOut}/> + <ZoomOutOutlined/> </Tooltip> <Tooltip title="1:1"> - <OneToOneOutlined onClick={this.setZoomInt}/> + <OneToOneOutlined/> </Tooltip> </div> </div> <div className="canvas" style={{width: '100%', minHeight: card.plot.height, height: card.plot.height}} id={card.uuid + 'canvas'}> - <div id={card.uuid + 'stencil'} className={'mk-stencil ' + (toolunfold ? '' : 'merge')}> - <div className="tool-control" onClick={() => this.setState({toolunfold: !toolunfold})}> - <DoubleLeftOutlined /> - </div> - </div> <div id={card.uuid + 'container'} className="mk-container"></div> - <div className={'mk-node-edit ' + (nodeunfold ? '' : 'merge')}> - <div className="tool-control" onClick={() => this.setState({nodeunfold: !nodeunfold})}> - <DoubleLeftOutlined /> - </div> - <div className="header">璁剧疆</div> - {!node ? <div className="empty">鏈�変腑</div> : <NodeUpdate node={node} onChange={this.changeProps}/>} - </div> </div> <div className="component-name"> <div className="center"> -- Gitblit v1.8.0