123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170 |
- import { Graph, Cell, Node, Path } from '@antv/x6'
- import { getTextSize, getTextWidth } from "./measure.js"
- import Hierarchy from '@antv/hierarchy'
- export default {
- data() {
- return {
- mindMapDataCurrent:{},
- positionCurrent:{},
- addTypeCurrent:'',
- styleConfig:{},
- mindmapAssistData:{
- mindmapDataUse:[],
- deletedMindmapData:[],// 用于撤销删除,恢复删除掉的数据
- mindmapDataRecoverUse:[],//用于 重做时 恢复思维导图数据
- },
- childNodeSizes:[],//数据节点内部内容宽度数组
- linkLists:[], //link列表
- childNodeCells:[],//存放所有child子数据节点
- }
- },
- mounted() {
-
- },
- created() {
- this.styleConfig=this.$store.state.sand.styleConfig
- // 中心主题
- Graph.registerNode(
- 'mindmap-topic',
- {
- inherit: 'rect',
- markup: [
- {
- tagName: 'rect',
- selector: 'body',
- },
- {
- tagName: 'image',
- selector: 'leftImg',
- },
- {
- tagName: 'image',
- selector: 'rightImg',
- },
- {
- tagName: 'text',
- selector: 'text',
- },
- ],
- attrs: {
- body: {
- rx: 6,
- ry: 6,
- strokeWidth: 1,
- width:100,
- height:50
- },
- leftImg: {
- ref: 'body',
- refX: -16,
- refY: '50%',
- refY2: -8,
- width: 16,
- height: 16,
- 'xlink:href':require('@/assets/img/icons/add_blue_new.png'),
- event: 'add:topic:left',
- class: 'left-topic-image',
- },
- rightImg: {
- ref: 'body',
- refX: '100%',
- refY: '50%',
- refY2: -8,
- width: 16,
- height: 16,
- 'xlink:href':require('@/assets/img/icons/add_blue_new.png'),
- event: 'add:topic:right',
- class: 'right-topic-image',
- },
- text: {
- fontSize: 14,
- fill: this.$store.state.sand.styleConfig.color,
- textWrap:{
- width:-10
- }
- }
- },
- },
- true,
- )
- // 左分支主题
- Graph.registerNode(
- 'mindmap-topic-left',
- {
- inherit: 'rect',
- markup: [
- {
- tagName: 'rect',
- selector: 'body',
- },
- {
- tagName: 'image',
- selector: 'leftImg',
- },
- {
- tagName: 'image',
- selector: 'rightImg',
- },
- {
- tagName: 'text',
- selector: 'text',
- },
- ],
- attrs: {
- body: {
- rx: 6,
- ry: 6,
- strokeWidth: 1,
- width:100,
- height:50
- },
- leftImg: {
- ref: 'body',
- refX: -16,
- refY: '50%',
- refY2: -8,
- width: 16,
- height: 16,
- 'xlink:href':require('@/assets/img/icons/add_blue_new.png'),
- event: 'add:topic:left',
- class: 'left-topic-image',
- },
- text: {
- fontSize: 14,
- fill: this.$store.state.sand.styleConfig.color,
- textWrap:{
- width:-10
- }
- }
- },
- },
- true,
- )
- // 右分支主题
- Graph.registerNode(
- 'mindmap-topic-right',
- {
- inherit: 'rect',
- markup: [
- {
- tagName: 'rect',
- selector: 'body',
- },
- {
- tagName: 'image',
- selector: 'leftImg',
- },
- {
- tagName: 'image',
- selector: 'rightImg',
- },
- {
- tagName: 'text',
- selector: 'text',
- },
- ],
- attrs: {
- body: {
- rx: 6,
- ry: 6,
- strokeWidth: 1,
- width:100,
- height:50
- },
- rightImg: {
- ref: 'body',
- refX: '100%',
- refY: '50%',
- refY2: -8,
- width: 16,
- height: 16,
- 'xlink:href':require('@/assets/img/icons/add_blue_new.png'),
- event: 'add:topic:right',
- class: 'right-topic-image',
- },
- text: {
- fontSize: 14,
- fill:this.$store.state.sand.styleConfig.color,
- textWrap:{
- width:-10
- }
- }
- },
- },
- true,
- )
- //数据节点标题
- Graph.registerNode(
- 'mindmap-child-datanode-title',
- {
- inherit: 'rect',
- markup: [
- {
- tagName: 'rect',
- selector: 'body',
- },
- {
- tagName: 'text',
- selector: 'text',
- },
- ],
- attrs: {
- body: {
- rx: 4,
- ry: 4,
- width:132,
- height:28,
- fill:'#0052D9',
- strokeWidth: 1,
- class: 'mindmap-child-datanode-title',
- },
- text: {
- fontSize: 14,
- fill: '#fff',
- textWrap:{
- width:-10
- },
- class: 'mindmap-child-datanode-title-text',
- }
- },
- }
- )
- //数据子框节点
- Graph.registerNode(
- 'mindmap-child-background-datanode',
- {
- inherit: 'rect',
- markup: [
- {
- tagName: 'rect',
- selector: 'body',
- },
- {
- tagName: 'text',
- selector: 'text',
- },
- ],
- attrs: {
- body: {
- strokeWidth: 1,
- width:110,
- height:66
- },
- },
- },
- true,
- );
- //数据子节点
- Graph.registerNode(
- 'mindmap-child-datanode',
- {
- inherit: 'rect',
- markup: [
- {
- tagName: 'rect',
- selector: 'body',
- },
- {
- tagName: 'text',
- selector: 'text',
- },
- ],
- attrs: {
- body: {
- rx: 6,
- ry: 6,
- strokeWidth: 1,
- width:110,
- height:66
- },
- text: {
- fontSize: 14,
- fill:this.$store.state.sand.styleConfig.color,
- textWrap:{
- width:-10
- }
- }
- },
- },
- true,
- );
- //数据子内部节点
- Graph.registerNode(
- 'mindmap-grandchild-datanode',
- {
- inherit: 'rect',
- markup: [
- {
- tagName: 'rect',
- selector: 'body',
- },
- {
- tagName: "text",
- selector: "text",
- },
- {
- tagName: "text",
- selector: "value",
- },
- ],
- attrs: {
- body: {
- width:110,
- height:66,
- },
- text: {
- fontSize: 14,
- },
- value:{
- fontSize: 14,
- },
- },
- },
- true,
- );
- // 连接器
- Graph.registerConnector(
- 'mindmap',
- (sourcePoint, targetPoint, routerPoints, options) => {
- const midX = sourcePoint.x + 10
- // const midY = sourcePoint.y
- const ctrX = (targetPoint.x - midX) / 5 + midX
- const ctrY = targetPoint.y
- const pathData = `
- M ${sourcePoint.x} ${sourcePoint.y}
- Q ${ctrX} ${ctrY} ${targetPoint.x} ${targetPoint.y}
- `
- return options.raw ? Path.parse(pathData) : pathData
- },
- true,
- )
- // 边
- Graph.registerEdge(
- 'mindmap-edge',
- {
- inherit: 'edge',
- connector: {
- name: 'mindmap',
- },
- attrs: {
- line: {
- targetMarker: false,
- strokeWidth: 2,
- },
- },
- zIndex: 0,
- },
- true,
- )
- },
- methods: {
- setGraph(){
- // 添加左边节点
- this.graph.on('add:topic:left', ({ node }) => {
- if(this.operationType=='view') return
- const { id } = node
- this.setCurrent(id)
- const type = node.prop('type')
- if (this.addChildNode(id, type,'left')) {
- this.mindMapRender()
- }
- })
- // 添加右边节点
- this.graph.on('add:topic:right', ({ node }) => {
- if(this.operationType=='view') return
- const { id } = node
- this.setCurrent(id)
- const type = node.prop('type')
- if (this.addChildNode(id, type,'right')) {
- this.mindMapRender()
- }
- })
- // 改变大小 - 更新数据源
- this.graph.on('node:change:size', (args) => {
- if(this.operationType=='view') return
- if(args.node.shape.indexOf('mindmap')!==-1){
- let ids = args.node.id.split('-')
- let mindmapDataIndex = this.mindmapAssistData.mindmapDataUse.findIndex(mindmap => mindmap.mindmapData.id == ids[0])
- let mindMapDataCurrent = this.mindmapAssistData.mindmapDataUse[mindmapDataIndex]?this.mindmapAssistData.mindmapDataUse[mindmapDataIndex].mindmapData:{}
- let findId = ids[0]
- for (let i = 1; i < ids.length; i++) {
- const element = ids[i];
- findId = findId+'-'+element
- mindMapDataCurrent=mindMapDataCurrent.children.find(it => it.id==findId)
- }
- mindMapDataCurrent.width = args.node.size().width
- mindMapDataCurrent.height = args.node.size().height
- }
- })
- // 改变位置 - 更新数据源
- this.graph.on('node:change:position', (args) => {
- if(this.operationType=='view') return
- if(args.node.shape.indexOf('mindmap')!==-1 && Number(args.node.id)){
- let index = this.mindmapAssistData.mindmapDataUse.findIndex(it =>it.mindmapData.id == args.node.id)
- if(index!=-1){
- this.mindmapAssistData.mindmapDataUse[index].position = args.current
- }
- }
- })
- // tab 键添加节点-右边的 - 更新数据源
- this.graph.bindKey('tab', (e) => {
- if(this.operationType=='view') return
- e.preventDefault()
- const selectedNodes = this.graph.getSelectedCells().filter((item) => {
- return item.shape.indexOf('mindmap')!=-1 && item.isNode()
- })
- if (selectedNodes.length) {
- const node = selectedNodes[0]
- this.setCurrent(node.id)
- let type = node.prop('type')
- let direction = node.shape.indexOf('left')!=-1?'left':'right'
- if (this.addChildNode(node.id, type,direction)) {
- this.mindMapRender()
- }
- }
- })
- // 撤销 - 入栈
- this.graph.history.on('undo', (args) => {
- let mindmapNodes=args.cmds.filter(it => it.data.props && it.data.props.shape.indexOf('mindmap')!=-1 && it.data.node)
- if(!(mindmapNodes && mindmapNodes.length>0)) return
- let mindmapUndoType=mindmapNodes[0].event
-
- if(mindmapUndoType=="cell:added"){
- this.mindmapDeleteRecordPush(mindmapNodes)
- }else if(mindmapUndoType=="cell:removed"){
- this.mindmapAddRecordPush()
- }
- })
- // 重做,出栈
- this.graph.history.on('redo', (args) => {
- let mindmapNodes=args.cmds.filter(it => it.data.props && it.data.props.shape.indexOf('mindmap')!=-1 && it.data.node)
- if(!(mindmapNodes && mindmapNodes.length>0)) return
- this.mindmapRecover()
- })
- },
- // 生成思维导图初始化数据
- generateMindmapData(position,addType){
- let beId=this.mindmapAssistData.mindmapDataUse.length>0?
- parseInt(this.mindmapAssistData.mindmapDataUse[this.mindmapAssistData.mindmapDataUse.length-1].mindmapData.id)+1+'':'1'
- let mindmapData={
- id: beId,
- type: 'topic',
- label: this.$t('SandboxManage.SandFlow.center_theme')||'中心主题',
- width: 160,
- height: 50,
- direction:'double',
- children: [
- {
- id: beId+'-1',
- type: 'topic-branch',
- label: this.$t('SandboxManage.SandFlow.branch_topic')+'1',
- width: 100,
- height: 40,
- direction:'left',
- children: [
- {
- id: beId+'-1-1',
- type: 'topic-child',
- label: this.$t('SandboxManage.SandFlow.sub_topic')+'1',
- width: 60,
- height: 30,
- direction:'left',
- },
- {
- id: beId+'-1-2',
- type: 'topic-child',
- label: this.$t('SandboxManage.SandFlow.sub_topic')+'2',
- width: 60,
- height: 30,
- direction:'left',
- },
- ],
- },
- {
- id: beId+'-2',
- type: 'topic-branch',
- label: this.$t('SandboxManage.SandFlow.branch_topic')+'2',
- width: 100,
- height: 40,
- direction:'right',
- },
- ],
- }
- this.mindmapAssistData.mindmapDataUse.push({mindmapData,position,addType})
- },
- // 通过id设置当前操作的思维导图
- setCurrent(id){
- let rootId = id.split('-')[0]
- let index = this.mindmapAssistData.mindmapDataUse.findIndex(it =>it.mindmapData.id == rootId)
- this.mindMapDataCurrent = this.mindmapAssistData.mindmapDataUse[index]?this.mindmapAssistData.mindmapDataUse[index].mindmapData:{}
- this.positionCurrent = this.mindmapAssistData.mindmapDataUse[index]?this.mindmapAssistData.mindmapDataUse[index].position:{x:0,y:0}
- this.addTypeCurrent = this.mindmapAssistData.mindmapDataUse[index]?this.mindmapAssistData.mindmapDataUse[index].addType:'singleMindmap'
- },
- mindMapRender(i){
- this.graph.startBatch('renderMindmap')
- let mindMapType = i || i==0?this.mindmapAssistData.mindmapDataUse[i].addType:this.addTypeCurrent
- this.mindMapDataCurrent = i || i==0?this.mindmapAssistData.mindmapDataUse[i].mindmapData:this.mindMapDataCurrent
- this.positionCurrent = i || i==0?this.mindmapAssistData.mindmapDataUse[i].position:this.positionCurrent
- const result = Hierarchy.mindmap(this.mindMapDataCurrent, {
- direction: 'H',
- getHeight(d) {
- return d.height
- },
- getWidth(d) {
- return d.width
- },
- getHGap() {
- return 40
- },
- getVGap() {
- return 20
- },
- getSide: (d) => {
- return mindMapType.indexOf('double') != -1?d.data.direction || 'left':'right'
- }
- })
- const cells = []
- let xGap = this.positionCurrent?this.positionCurrent.x-result.x:0
- let yGap = this.positionCurrent?this.positionCurrent.y-result.y:0
- const traverse = (hierarchyItem) => {
- if (hierarchyItem) {
- const { data, children } = hierarchyItem
- let mindmapDirection = mindMapType.indexOf('double') != -1?data.direction:'right'
- let currentCell=this.graph.getCellById(data.id)
- if(!currentCell){
- // 没有 新增
- cells.push(
- this.graph.createNode({
- id: data.id,
- shape:mindmapDirection=='right'?'mindmap-topic-right':mindmapDirection=='left'?'mindmap-topic-left':'mindmap-topic',
- x: xGap+hierarchyItem.x,
- y: yGap+hierarchyItem.y,
- width: data.width,
- height: data.height,
- label: data.label,
- type: data.type,
- attrs:{
- body: {
- stroke: this.$store.state.sand.styleConfig.borderColor,
- fill: this.$store.state.sand.styleConfig.backgroundColor
- },
- text:{
- fill:this.$store.state.sand.styleConfig.color
- }
- },
- }),
- )
- }else{
- // 有,更新下位置信息
- currentCell.position(xGap+hierarchyItem.x,yGap+hierarchyItem.y);
- if(currentCell.shape == 'mindmap-child-background-datanode' && currentCell.getChildren().length > 0){
- let titleNodeSize = this.getTitleNodeSize(currentCell.data.Name,currentCell.size().width);
- let childDataNode = currentCell.getChildren()[0];
- childDataNode.position(xGap+hierarchyItem.x,yGap+hierarchyItem.y + titleNodeSize.height)
- let childrens = childDataNode.getChildren() || [];
- let cs = _.cloneDeep(childrens)
- cs.sort((a, b) => {
- if (a.shape === 'mindmap-child-datanode-title') return 1;
- if (b.shape === 'mindmap-child-datanode-title') return -1;
- return 0;
- });
- cs.map((v,i)=>{
- if(v.shape == 'mindmap-grandchild-datanode'){
- let m = i % 3;
- let w = m == 0 ? 0 : (m == 1 ? cs[0].size().width : cs[0].size().width + cs[1].size().width);
- v.position(xGap+hierarchyItem.x + (m + 1) * 10 + w , yGap+hierarchyItem.y + Math.floor(i / 3) * 66 + titleNodeSize.height);
- } else {
- v.position(xGap+hierarchyItem.x , yGap+hierarchyItem.y);
- }
- })
- }
- }
-
- if (children) {
- children.forEach((item) => {
- const { id, data } = item
- let mindmapChildDirection = mindMapType.indexOf('double') != -1?data.direction:'right'
- let currentEdge=this.graph.getCellById(data.id)
- if(!currentEdge){
- cells.push(
- this.graph.createEdge({
- shape: 'mindmap-edge',
- attrs:{
- line:{
- stroke:this.$store.state.sand.styleConfig.lineColor
- }
- },
- source: {
- cell: hierarchyItem.id,
- anchor: {
- name: 'center',
- args: {
- dx: mindmapChildDirection=='right'?'25%':mindmapChildDirection=='left'?'-25%':0,
- },
- },
- },
- target: {
- cell: id,
- anchor: {
- name: mindmapChildDirection =='left'?'right':'left',
- },
- },
- }),
- )
- }
- traverse(item)
- })
- }
- }
- }
- traverse(result)
- // 排下序,把边放最后面 不然 边 会找不到 节点
- let sortCells = cells.sort(cell => cell.shape.indexOf('edge'))
- this.graph.addCell(sortCells)
- this.graph.stopBatch('renderMindmap')
- },
- findItem(obj,id){
- if (obj.id === id) {
- return {
- parent: null,
- node: obj,
- }
- }
- const { children } = obj
- if (children) {
- for (let i = 0, len = children.length; i < len; i++) {
- const res = this.findItem(children[i], id)
- if (res) {
- return {
- parent: res.parent || obj,
- node: res.node,
- }
- }
- }
- }
- return null
- },
- addChildNode (id, type,direction='left'){
- // 重做不了 清空重做栈
- this.mindmapAssistData.mindmapDataRecoverUse = []
- const res = this.findItem(this.mindMapDataCurrent, id)
- const dataItem = res && res.node
- if (dataItem) {
- let item = null
- let addId ='1'
- if(dataItem.children && dataItem.children.length>0){
- let ids = dataItem.children[dataItem.children.length-1].id.split('-')
- addId = parseInt(ids[ids.length-1])+1+''
- }
- if (type === 'topic') {
- item = {
- id: `${id}-${addId}`,
- type: 'topic-branch',
- label: `分支主题${addId}`,
- width: 100,
- height: 40,
- direction
- }
- } else if (type === 'topic-branch' || type=='topic-child') {
- item = {
- id: `${id}-${addId}`,
- type: 'topic-child',
- label: `子主题${addId}`,
- width: 60,
- height: 30,
- direction
- }
- }
- if (item) {
- if (dataItem.children) {
- dataItem.children.push(item)
- } else {
- dataItem.children = [item]
- }
- return item
- }
- }
- return null
- },
- //添加数据节点
- handleGetDataNodeWidth(list,widthIndex){
- let arr = [[],[],[]]; //按列分组,获取当前列的内容的最大长度作为该列的最大长度
- list.map((item,index)=>{
- arr[index % 3].push(item)
- });
- let widthArr = [];
- arr.map((arrs,arrsIndex)=>{
- let widths = [];
- arrs.map(item=>{
- widths.push(getTextWidth(item.label,'Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif',14) || 0);
- widths.push(getTextWidth(item.value,'Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif',14) || 0);
- })
- let max = widths.length > 0 ? Math.max.apply(null,widths) : 0;
- if(max) widthArr[arrsIndex] = max > 106 ? max : 106;
- });
- this.childNodeSizes[widthIndex] = widthArr || [];
- let sum = widthArr.reduce((accumulator, current) => {
- return accumulator + current;
- },0);
- sum += list.filter(_=>_).length >= 3 ? 40 : (20 + 10*(list.length - 1));
- return sum;
- },
- getDataNodeSize(data,index){
- const list = data.calculationMethod;
- let height = Math.ceil(list.length / 3) * 66;
- let width = this.handleGetDataNodeWidth(list,index);
- return {
- height:height || 66,
- width:width || 50,
- }
- },
- getTitleNodeSize(name,width){
- let nameWidth = getTextWidth(name,'Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif',14) + 10;
- let titleWidth = nameWidth < width ? nameWidth : width;
- titleWidth = titleWidth < 126 ? 126 : titleWidth;
- let h = getTextSize(name,titleWidth,14,'Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif');
- h.height = h.height < 30 ? 30 : h.height;
- return h
- },
- addMindmapDataNodes(id,list,direction){
- // 重做不了 清空重做栈
- this.mindmapAssistData.mindmapDataRecoverUse = []
- const res = this.findItem(this.mindMapDataCurrent, id);
- const dataItem = res && res.node;
- if(dataItem.children && dataItem.children.length > 0){ //将原数据清空
- const types = ['mindmap-child-background','datanode-title','datanode-grandchild','datanode-child']
- dataItem.children = dataItem.children.filter(_=>!types.includes(_.type))
- }
- this.linkLists = [];
- this.childNodeSizes = [];
- this.childNodeCells = [];
- if (dataItem) {
- list.map((_,index)=>{
- let item = null
- let addId ='1'
- if(dataItem.children && dataItem.children.length>0){
- let ids = dataItem.children[dataItem.children.length-1].id.split('-')
- addId = parseInt(ids[ids.length-1])+1+''
- };
- let h = {height:30,width:200};
- let titleH = {height:0,width:0}
- if(!_.calculationMethod || !_.calculationMethod.length){
- h = getTextSize(_.Name,200,14,'Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif');
- h.height = h.height < 30 ? 30 : h.height;
- } else {
- h = this.getDataNodeSize(_,index);
- titleH = this.getTitleNodeSize(_.Name,h.width);
- }
- item = {
- id: `${id}-${addId}`,
- type: !_.calculationMethod || !_.calculationMethod.length ? 'datanode-title' : 'mindmap-child-background',
- label: !_.calculationMethod || !_.calculationMethod.length ? _.Name : '',
- width: h.width,
- height: h.height + titleH.height,
- direction:direction,
- data:_,
- }
-
- this.linkLists.push(item);
- if (item) {
- if (dataItem.children) {
- dataItem.children.push(item)
- } else {
- dataItem.children = [item]
- }
- this.mindMapDataRender();
- if(this.childNodeCells.length == list.length){ //添加完成
- const select_cell = this.graph.getSelectedCells()[0];
- select_cell.setChildren(this.childNodeCells)
- }
- }
- })
- }
- },
- mindMapDataRender(i){ //添加数据节点的渲染
- this.graph.startBatch('renderMindmap')
- let mindMapType = i || i==0?this.mindmapAssistData.mindmapDataUse[i].addType:this.addTypeCurrent
- this.mindMapDataCurrent = i || i==0?this.mindmapAssistData.mindmapDataUse[i].mindmapData:this.mindMapDataCurrent
- this.positionCurrent = i || i==0?this.mindmapAssistData.mindmapDataUse[i].position:this.positionCurrent
- const result = Hierarchy.mindmap(this.mindMapDataCurrent, {
- direction: 'H',
- getHeight(d) {
- return d.height
- },
- getWidth(d) {
- return d.width
- },
- getHGap() {
- return 40
- },
- getVGap() {
- return 20
- },
- getSide: (d) => {
- return mindMapType.indexOf('double') != -1?d.data.direction || 'left':'right'
- }
- })
- const cells = [];
- let xGap = this.positionCurrent?this.positionCurrent.x-result.x:0
- let yGap = this.positionCurrent?this.positionCurrent.y-result.y:0
- const traverse = (hierarchyItem) => {
- if (hierarchyItem) {
- const { data, children } = hierarchyItem
- let mindmapDirection = mindMapType.indexOf('double') != -1?data.direction:'right'
- let currentCell=this.graph.getCellById(data.id)
- const shapesObject = {
- 'datanode-title':'mindmap-child-datanode-title',
- 'datanode-child':'mindmap-child-datanode',
- 'datanode-grandchild':'mindmap-grandchild-datanode',
- 'mindmap-child-background':'mindmap-child-background-datanode'
- }
- if(!currentCell){
- // 没有 新增
- const wrapNode = this.graph.createNode({
- id: data.id,
- shape:shapesObject[data.type],
- x: xGap+hierarchyItem.x,
- y: yGap+hierarchyItem.y,
- width: data.width,
- height: data.height,
- label: data.label,
- type: data.type,
- attrs:{
- body: {
- stroke: data.type == 'datanode-title' ? '#0052D9' : 'transparent',
- fill: data.type == 'datanode-title' ? '#0052D9' : 'transparent',
- },
- text:{
- fill:data.type == 'datanode-title' ? '#FFFFFF' : 'transparent',
- }
- },
- data:data.data,
- })
- cells.push(wrapNode);
- if(data.type == 'mindmap-child-background' || data.type == 'datanode-title') this.childNodeCells.push(wrapNode);
-
- let titleNodeSize = this.getTitleNodeSize(data.data.Name,data.width);
- let currentNode = null;
- if(data.type == 'mindmap-child-background'){
- currentNode = this.graph.createNode({
- id: `${data.id}+0` ,
- shape:'mindmap-child-datanode',
- x: xGap+hierarchyItem.x,
- y: yGap+hierarchyItem.y + titleNodeSize.height,
- width: data.width,
- height: data.height - titleNodeSize.height,
- label: '',
- type:'datanode-child',
- attrs:{
- body: {
- stroke: this.$store.state.sand.styleConfig.borderColor,
- fill: this.$store.state.sand.styleConfig.backgroundColor,
- 'pointer-events': 'none',
- },
- text:{
- fill:this.$store.state.sand.styleConfig.color,
- 'pointer-events': 'none',
- }
- },
- data:data.data,
- })
- cells.push(currentNode);
- wrapNode.setChildren([currentNode])
- }
- let titleNode = null;
- if(data.data && data.data.detailParams && data.data.detailParams.id && data.data && data.data.calculationMethod && data.data.calculationMethod.length > 0){
- titleNode = this.graph.createNode({
- id: `${data.id}-0`,
- shape:'mindmap-child-datanode-title',
- x: xGap+hierarchyItem.x,
- y: yGap+hierarchyItem.y,
- width: titleNodeSize.width,
- height: titleNodeSize.height,
- label: data.data.Name,
- type: 'datanode-title',
- attrs:{
- body: {
- stroke: '#0052D9',
- fill: '#0052D9'
- },
- text:{
- fill:'#FFFFFF'
- }
- },
- data:data.data,
- });
- cells.push(titleNode);
- }
- // 处理内部数据节点
- if(data.data && data.data.calculationMethod && data.data.calculationMethod.length > 0){
- let cNodes = data.data.calculationMethod.map((v,i)=>{
- let linkIndex = this.linkLists.findIndex(x=>x.id == data.id);
- let widthArr = this.childNodeSizes[linkIndex] ? this.childNodeSizes[linkIndex] : [];
- let m = i % 3;
- let w = m == 0 ? 0 : (m == 1 ? widthArr[0] : widthArr[0] + widthArr[1])
- let innerNode = this.graph.createNode({
- id: `${data.id}-${i + 1}`,
- shape:'mindmap-grandchild-datanode',
- x: xGap+hierarchyItem.x + (m + 1) * 10 + w,
- y: yGap+hierarchyItem.y + titleNodeSize.height + Math.floor(i / 3) * 66,
- width: widthArr[m],
- height: 66,
- type: 'datanode-grandchild',
- attrs:{
- body:{
- stroke: '',
- strokeWidth: 0,
- fill: 'transparent',
- 'pointer-events': 'none',
- },
- text:{
- fill:this.$store.state.sand.styleConfig.color,
- text:v.label,
- refWidth:1,
- refY: 10,
- textVerticalAnchor:'top',
- 'pointer-events': 'none',
- },
- value:{
- fill:this.$store.state.sand.styleConfig.color,
- text:v.value,
- refWidth:1,
- refX:"50%",
- refY: '100%',
- refY2:-10,
- textVerticalAnchor:'bottom',
- 'text-anchor':'middle',
- 'pointer-events': 'none',
- },
- },
- data:v,
- });
- cells.push(innerNode);
- return innerNode
- })
- currentNode.setChildren(titleNode ? [...cNodes,titleNode] : cNodes)
- }
- }else{
- // 有,更新下位置信息
- currentCell.position(xGap+hierarchyItem.x,yGap+hierarchyItem.y);
- if(currentCell.shape == 'mindmap-child-background-datanode' && currentCell.getChildren().length > 0){
- let titleNodeSize = this.getTitleNodeSize(currentCell.data.Name,currentCell.size().width);
- let childDataNode = currentCell.getChildren()[0];
- childDataNode.position(xGap+hierarchyItem.x,yGap+hierarchyItem.y + titleNodeSize.height)
- let childrens = childDataNode.getChildren() || [];
- let cs = _.cloneDeep(childrens)
- cs.sort((a, b) => {
- if (a.shape === 'mindmap-child-datanode-title') return 1;
- if (b.shape === 'mindmap-child-datanode-title') return -1;
- return 0;
- });
- cs.map((v,i)=>{
- if(v.shape == 'mindmap-grandchild-datanode'){
- let m = i % 3;
- let w = m == 0 ? 0 : (m == 1 ? cs[0].size().width : cs[0].size().width + cs[1].size().width);
- v.position(xGap+hierarchyItem.x + (m + 1) * 10 + w , yGap+hierarchyItem.y + Math.floor(i / 3) * 66 + titleNodeSize.height);
- } else {
- v.position(xGap+hierarchyItem.x , yGap+hierarchyItem.y);
- }
- })
- }
- }
- if (children) {
- children.forEach((item) => {
- const { id, data } = item
- let mindmapChildDirection = mindMapType.indexOf('double') != -1?data.direction:'right'
- let currentEdge=this.graph.getCellById(data.id)
- if(!currentEdge){
- cells.push(
- this.graph.createEdge({
- shape: 'mindmap-edge',
- attrs:{
- line:{
- stroke:this.$store.state.sand.styleConfig.lineColor
- }
- },
- source: {
- cell: hierarchyItem.id,
- anchor: {
- name: 'center',
- args: {
- dx: mindmapChildDirection=='right'?'25%':mindmapChildDirection=='left'?'-25%':0,
- },
- },
- },
- target: {
- cell: id,
- anchor: {
- name: mindmapChildDirection =='left'?'right':'left',
- },
- },
- }),
- )
- }
- traverse(item)
- })
- }
- }
- }
- traverse(result)
- // 排下序,把边放最后面 不然 边 会找不到 节点
- let sortCells = cells.sort(cell => cell.shape.indexOf('edge'))
- let cells_result = sortCells.sort(cell => cell.shape.indexOf('mindmap-grandchild-datanode'));
- this.graph.addCell(cells_result)
- this.graph.stopBatch('renderMindmap')
- },
- getMindmapDataUse(){
- return this.mindmapAssistData
- },
- mindmapDeleteRecordPush(mindmapNodes){
- let shouldOperations=[]
- this.mindmapAssistData.mindmapDataUse.map((item,index)=>{
- let levelIds = mindmapNodes.filter(mindMap => mindMap.data.id.startsWith(item.mindmapData.id)).map(mindMap => mindMap.data.id)
- if(!(levelIds && levelIds.length>0)) return
- let mindMapIds=[...levelIds]
- for (let i = 0; i < levelIds.length; i++) {
- const element = levelIds[i]
- mindMapIds=mindMapIds.filter( id => id.indexOf(element) !=0 || id==element)
- }
- shouldOperations.push(mindMapIds)
- })
- // 入栈
- if(!this.canRedo){
- this.mindmapAssistData.mindmapDataRecoverUse=[JSON.stringify(this.mindmapAssistData.mindmapDataUse)]
- }else{
- this.mindmapAssistData.mindmapDataRecoverUse.push(JSON.stringify(this.mindmapAssistData.mindmapDataUse))
- }
- shouldOperations.map(it =>{
- it.map(it1 =>{
- this.deleteMindmapData(it1,this.mindmapAssistData.mindmapDataUse)
- })
- })
- },
- mindmapAddRecordPush(){
- // 入栈
- if(!this.canRedo){
- this.mindmapAssistData.mindmapDataRecoverUse=[JSON.stringify(this.mindmapAssistData.mindmapDataUse)]
- }else{
- this.mindmapAssistData.mindmapDataRecoverUse.push(JSON.stringify(this.mindmapAssistData.mindmapDataUse))
- }
- let recoverDeletedData=this.mindmapAssistData.deletedMindmapData.pop()
- if(recoverDeletedData && recoverDeletedData.length>0){
- // 添加
- recoverDeletedData.map(it =>{
- it.map(it1 =>{
- this.addMindmapData(it1,this.mindmapAssistData.mindmapDataUse)
- })
- })
- }
- },
- deleteMindmapData(id,data){
- let ids = id.split('-')
- let mindmapDataIndex = data.findIndex(mindmap => mindmap.mindmapData.id == ids[0])
- if(ids.length==1){
- data.splice(mindmapDataIndex,1)
- return
- }
- let mindmapData = data[mindmapDataIndex].mindmapData
- let findId = ids[0]
- for (let i = 1; i < ids.length-1; i++) {
- const element = ids[i];
- findId = findId+'-'+element
- mindmapData=mindmapData.children.find(it => it.id==findId)
- }
- let endId = ids[ids.length-1]
- let endIndex = mindmapData.children.findIndex(it => it.id == findId+'-'+endId)
- mindmapData.children.splice(endIndex,1)
- },
- addMindmapData(item,data){
- let isRoot = item.mindmapData?true:false
- let id = isRoot?item.mindmapData.id:item.id
-
- if(isRoot){
- // 恢复根节点
- let mindmapDataIndexRoot=data.length
- for (let i = 0; i < data.length-1; i++) {
- const element = data[i];
- if((+id) < (+element.mindmapData.id)){
- mindmapDataIndexRoot=0
- break
- }else if((+id) > (+element.mindmapData.id) && (+id) < (+data[i+1].mindmapData.id)){
- mindmapDataIndexRoot=i+1
- break
- }
- }
- data.splice(mindmapDataIndexRoot,0,item)
- return
- }
- let ids = id.split('-')
- let mindmapDataIndex = data.findIndex(mindmap => {
- return mindmap.mindmapData.id == ids[0]
- })
- let mindmapData = data[mindmapDataIndex].mindmapData
- let findId = ids[0]
- for (let i = 1; i < ids.length-1; i++) {
- const element = ids[i];
- findId = findId+'-'+element
- mindmapData=mindmapData.children.find(it => it.id==findId)
- }
- let endId = ids[ids.length-1]
- let endIndex = mindmapData.children.length
- if(mindmapData.children.length==1){
- // 只有一个
- let prevIdx = mindmapData.children[0].id.substring(mindmapData.children[0].id.lastIndexOf('-')+1)
- if((+endId) < (+prevIdx)){
- endIndex=0
- }else{
- endIndex=1
- }
- }else{
- for (let i = 0; i < mindmapData.children.length-1; i++) {
- // 两个及以上
- const element = mindmapData.children[i];
- let prevIdx = element.id.substring(element.id.lastIndexOf('-')+1)
- let nextIdx = mindmapData.children[i+1].id.substring(mindmapData.children[i+1].id.lastIndexOf('-')+1)
- // 找到对应位置,前提 id是按顺序的
- if((+endId) < (+prevIdx)){
- endIndex=0
- break
- }else if((+endId) > (+prevIdx) && (+endId) < (+nextIdx)){
- endIndex=i+1
- break
- }
- }
- }
- mindmapData.children.splice(endIndex,0,item)
- },
- mindmapRecover(){
- // 重做添加时 恢复数据指针前进
- let recoverData = this.mindmapAssistData.mindmapDataRecoverUse.pop()
- if(recoverData) this.mindmapAssistData.mindmapDataUse=JSON.parse(recoverData)
- },
- },
- }
|