logic-helper
Version:
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
930 lines (903 loc) • 31.1 kB
JavaScript
import '@/assets/go.js';
import {
createTemplate,
gojsEventParser,
getFormatData,
createContextMenu,
allEvents,
transformer,
formateModelData,
Record
} from './Utils.js'
import Node from './Node.js'
import Link from './Link.js'
import deepEqual from 'deep-equal';
import {
diff
} from 'deep-object-diff';
import {
ref,
watch,
toRaw,
markRaw
} from 'vue'
const $ = go.GraphObject.make; // for conciseness in defining templates
function init(diagramId = 'myDiagramDiv', paletteId = 'myPaletteDiv') {
// Since 2.2 you can also author concise templates with method chaining instead of GraphObject.make
// For details, see https://gojs.net/latest/intro/buildingObjects.html
const myDiagram =
$(go.Diagram, diagramId, // must name or refer to the DIV HTML element
{
"undoManager.isEnabled": true // enable undo & redo
});
// when the document is modified, add a "*" to the title and enable the "Save" button
myDiagram.addDiagramListener("Modified", e => {
var button = document.getElementById("SaveButton");
if (button) button.disabled = !myDiagram.isModified;
var idx = document.title.indexOf("*");
if (myDiagram.isModified) {
if (idx < 0) document.title += "*";
} else {
if (idx >= 0) document.title = document.title.slice(0, idx);
}
});
// define the Node templates for regular nodes
// the default category
myDiagram.nodeTemplateMap.add("Input", createTemplate('Input'));
myDiagram.nodeTemplateMap.add("Step", createTemplate());
myDiagram.nodeTemplateMap.add("Conditional", createTemplate('Conditional'));
myDiagram.nodeTemplateMap.add("Start", createTemplate('Start'));
myDiagram.nodeTemplateMap.add("End", createTemplate('End'));
myDiagram.nodeTemplateMap.add("Delay", createTemplate('Delay'));
myDiagram.nodeTemplateMap.add("Interrupt", createTemplate('Interrupt'));
myDiagram.nodeTemplateMap.add("Subroutine", createTemplate('Subroutine'));
myDiagram.nodeTemplateMap.add("Repeat", createTemplate('Repeat'));
myDiagram.groupTemplate = createTemplate('Group');
// taken from ../extensions/Figures.js:
go.Shape.defineFigureGenerator("File", (shape, w, h) => {
var geo = new go.Geometry();
var fig = new go.PathFigure(0, 0, true); // starting point
geo.add(fig);
fig.add(new go.PathSegment(go.PathSegment.Line, .75 * w, 0));
fig.add(new go.PathSegment(go.PathSegment.Line, w, .25 * h));
fig.add(new go.PathSegment(go.PathSegment.Line, w, h));
fig.add(new go.PathSegment(go.PathSegment.Line, 0, h).close());
var fig2 = new go.PathFigure(.75 * w, 0, false);
geo.add(fig2);
// The Fold
fig2.add(new go.PathSegment(go.PathSegment.Line, .75 * w, .25 * h));
fig2.add(new go.PathSegment(go.PathSegment.Line, w, .25 * h));
geo.spot1 = new go.Spot(0, .25);
geo.spot2 = go.Spot.BottomRight;
return geo;
});
myDiagram.nodeTemplateMap.add("Comment", createTemplate('Comment'));
// replace the default Link template in the linkTemplateMap
myDiagram.linkTemplate = createTemplate('Link');
// the context menu allows users to make a position vacant,
// remove a role and reassign the subtree, or remove a department
myDiagram.nodeTemplate.contextMenu = createContextMenu.call(myDiagram, ['删除'], (node, btn) => {
myDiagram.model.removeNodeData(node.data);
})
myDiagram.linkTemplate.contextMenu = createContextMenu.call(myDiagram, ['删除'], (node, btn) => {
myDiagram.model.removeLinkData(node.data);
})
// temporary links used by LinkingTool and RelinkingTool are also orthogonal:
myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;
myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal;
// initialize the Palette that is on the left side of the page
const myPalette = $(go.Palette, paletteId, // must name or refer to the DIV HTML element
{
nodeTemplateMap: myDiagram.nodeTemplateMap, // share the templates used by myDiagram
groupTemplateMap: myDiagram.groupTemplateMap,
model: new go.GraphLinksModel([ // specify the contents of the Palette
{
category: "Start",
text: "Start"
},
{
isGroup: true,
text: "Group",
horiz: true,
category: "Group"
},
{
category: "Input",
text: "Input"
},
{
category: "Step",
text: "Step"
},
{
category: "Conditional",
text: '???'
},
// {
// category: "Delay",
// text: "Delay"
// },
{
category: "Repeat",
text: "Repeat"
},
{
category: "Subroutine",
text: "Subroutine"
},
{
category: "End",
text: "End"
},
{
category: "Comment",
text: "Comment"
},
])
});
// Overview
let myOverview =
$(go.Overview, "myOverviewDiv", // the HTML DIV element for the Overview
{ observed: myDiagram, contentAlignment: go.Spot.Center }); // tell it which Diagram to show and pan
return {
myDiagram,
myPalette,
myOverview
};
} // end init
export function load(json) {
myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value);
}
// print the diagram by opening a new window holding SVG images of the diagram contents for each page
export function printDiagram() {
var svgWindow = window.open();
if (!svgWindow) return; // failure to open a new Window
var printSize = new go.Size(700, 960);
var bnds = this.myDiagram.documentBounds;
var x = bnds.x;
var y = bnds.y;
while (y < bnds.bottom) {
while (x < bnds.right) {
var svg = this.myDiagram.makeSvg({
scale: 1.0,
position: new go.Point(x, y),
size: printSize
});
svgWindow.document.body.appendChild(svg);
x += printSize.width;
}
x = bnds.x;
y += printSize.height;
}
setTimeout(() => svgWindow.print(), 1);
}
let throttleBar = null;
let x = 0
export default class {
constructor(store) {
const evt = {};
this.setModelRecords = new Record()
this.store = store;
allEvents.forEach(e => {
evt[e] = new Set();
})
this.events = markRaw(evt)
this.links = markRaw({});
this.nodes = markRaw({});
this.watchers = markRaw(new Set());
this.model = ref({})
watch(this.model, (val, oldVal) => {
val = formateModelData(toRaw(val));
oldVal = toRaw(oldVal);
console.log(val, '>>>>>>>>??????++++')
if (!deepEqual(val, oldVal)) {
const position ={...this.myDiagram.position}
const rect = {...this.myDiagram.viewportBounds};
clearInterval(throttleBar);
this.setModelRecords.setData(val);
const difference = diff(oldVal, val);
this.watchers.forEach(fn => fn(difference, val, oldVal));
store.topo.update(store.storage.topoId, transformer(val, store.storage));
this.setModel(val);
try {
if (difference.nodeDataArray) {
for (let k in difference.nodeDataArray) {
if (difference.nodeDataArray[k] === undefined) {
let key = oldVal.nodeDataArray[k].key;
if (this.nodes[key].category === 'Start' || this.nodes[key].category === 'End') {
this.addCategoryTemplate(this.nodes[key].category);
}
if(this.store.topo.selectedEle&&key===this.store.topo.selectedEle.id){
this.store.topo.selectEle(null)
}
continue;
}
let v = val.nodeDataArray[k];
this.nodes[v.key] = new Node(v);
this.nodes[v.key].setModel(this);
if(this.store.topo.selectedEle&&this.nodes[v.key].id ===this.store.topo.selectedEle.id){
this.store.topo.selectEle(this.nodes[v.key])
}
if(this.nodes[v.key].caption ===undefined){
this.nodes[v.key].setData({
caption: v.text + ' caption'
})
}
}
}
if (difference.linkDataArray) {
for (let k in difference.linkDataArray) {
if (difference.linkDataArray[k] === undefined) {
this.links[k] && this.links[k].remove();
continue;
}
let v = val.linkDataArray[k];
this.links[v.key] = new Link(v);
this.links[v.key].setModel(this);
this.links[v.key].update({
visible: !!this.links[v.key].text
})
}
}
}catch(e) {
console.log('watch model error: ',difference);
console.error(e);
}
this.refresh();
requestAnimationFrame(() => {
this.myDiagram.zoomToRect(new go.Rect(position.x, position.y, rect.width, rect.height));
})
}
}, {
deep: true
})
}
ctlZ() {
this.setModel(this.setModelRecords.prev());
}
ctlY() {
this.setModel(this.setModelRecords.next());
}
zoomToFit() {
this.myDiagram.commandHandler.zoomToFit()
}
getDiagramSize() {
return this.myDiagram.documentBounds;
}
forbiden() {
this.myDiagram.isReadOnly = true;
}
enable() {
this.myDiagram.isReadOnly = false;
}
init(diagramId, paletteId) {
const {
myDiagram,
myPalette
} = init.call(this, diagramId, paletteId);
this.myDiagram = myDiagram;
this.myPalette = myPalette;
this.myDiagram.animationManager.initialAnimationStyle = go.AnimationManager.None;
for (let k in this.events) {
this.myDiagram.addDiagramListener(k, (e) => {
const data = gojsEventParser(e, this);
this.events[k].forEach((fn) => {
fn(data);
})
});
}
this.addEventListener(['ChangedSelection', 'ObjectSingleClicked'], e => {
this.store.topo.selectEle(e.el)
})
this.addModelChangedListener(evt => {
this.model.value = this.getModel();
})
return this;
}
save() {
this.myDiagram.isModified = false;
return this.myDiagram.model.toJson();
}
changeNodeCategory(key, type) {
this.myDiagram.startTransaction('changeNodeCategory');
this.myDiagram.model.setDataProperty(this.myDiagram.model.findNodeDataForKey(key), 'category', type);
this.myDiagram.commitTransaction('changeNodeCategory');
}
addModelChangedListener(fn) {
this.myDiagram.addModelChangedListener(evt => {
if (!evt.isTransactionFinished) return;
fn(evt);
});
}
refresh() {
for (let k in this.nodes) {
this.nodes[k].refresh();
}
}
moveToCenter(key) {
const node = this.myDiagram.findNodeForKey(key);
node&&this.myDiagram.centerRect(node.actualBounds);
}
nodeIsOutView(key) {
const node = this.myDiagram.findNodeForKey(key);
return !node||!this.myDiagram.viewportBounds.containsRect(node?.actualBounds);
}
scale(scale) {
this.myDiagram.scale = scale;
}
printDiagram() {
printDiagram.call(this);
}
addNode(nodeList = []) {
if (!Array.isArray(nodeList)) {
nodeList = [nodeList];
}
this.myDiagram.startTransaction('add node');
nodeList.forEach(({text}) => {
this.myDiagram.model.addNodeData({
category: 'Step',
text: text,
});
})
this.myDiagram.commitTransaction('add node');
}
removeNode(key) {
this.myDiagram.startTransaction('remove node' + key);
if (key == this.store.topo.selectedEle?.key) {
this.store.topo.selectEle(null)
}
this.myDiagram.model.removeNodeData(this.myDiagram.model.findNodeDataForKey(key));
this.myDiagram.commitTransaction('remove node' + key);
}
removeLink(key) {
this.myDiagram.startTransaction('remove link' + key);
if (key == this.store.topo.selectedEle?.key) {
this.store.topo.selectEle(null)
}
this.myDiagram.model.removeLinkData(this.myDiagram.model.findLinkDataForKey(key));
this.myDiagram.commitTransaction('remove link' + key);
}
updateNode(key, data) {
this.myDiagram.startTransaction('update node' + key);
Object.keys(data).forEach(k => {
this.myDiagram.model.setDataProperty(this.myDiagram.model.findNodeDataForKey(key), k, data[k]);
})
this.myDiagram.commitTransaction('update node' + key);
}
updateLink(key, data) {
this.myDiagram.startTransaction('update link' + key);
Object.keys(data).forEach(k => {
this.myDiagram.model.setDataProperty(this.myDiagram.model.findLinkDataForKey(key), k, data[k]);
})
this.myDiagram.commitTransaction('update link' + key);
}
reverseLink(key) {
this.myDiagram.startTransaction('reverse link' + key);
let link = this.myDiagram.model.findLinkDataForKey(key);
let from = link.from;
let to = link.to;
let fromPort = link.fromPort;
let toPort = link.toPort;
const fromNodeCategory = this.myDiagram.model.findNodeDataForKey(from).category;
const toNodeCategory = this.myDiagram.model.findNodeDataForKey(to).category;
if(fromNodeCategory === 'Conditional'&&toNodeCategory !== 'Conditional'){
this.myDiagram.model.setDataProperty(link, 'visible', false);
} else if(fromNodeCategory !== 'Conditional'&&toNodeCategory === 'Conditional'){
this.myDiagram.model.setDataProperty(link, 'visible', true);
}
this.myDiagram.model.setDataProperty(link, 'fromPort', toPort);
this.myDiagram.model.setDataProperty(link, 'toPort', fromPort);
this.myDiagram.model.setDataProperty(link, 'from', to);
this.myDiagram.model.setDataProperty(link, 'to', from);
this.myDiagram.commitTransaction('reverse link' + key);
}
setLinkDataProp(key, prop, val) {
this.myDiagram.startTransaction('setLinkLabel');
this.myDiagram.model.setDataProperty(this.myDiagram.model.findLinkDataForKey(key), prop, val);
this.myDiagram.commitTransaction('setLinkLabel');
}
getNodeByField(field,value) {
return Object.keys(this.nodes).map(key=>this.nodes[key]).filter(node=>{
return node[field] == value;
})
}
getLinkByField(field, value){
return Object.keys(this.links).map(key=>this.links[key]).filter(link=>{
return link[field] == value;
})
}
getLinkByFT(from, to) {
return Object.keys(this.links).map(key => this.links[key]).filter(link => {
return link.id == `${from}>${to}`;
})
}
highlightNode(key = Object.keys(this.nodes)) {
if (Array.isArray(key)) {
key.forEach(k => {
this.highlightNode(k)
})
return;
}
const node = this.$getNode(key);
if (node) {
node.isHighlighted = true;
this.nodes[key].isHighlighted = true;
}
}
unhighlightNode(key = Object.keys(this.nodes)) {
if (Array.isArray(key)) {
key.forEach(k => {
k&&this.unhighlightNode(k)
})
return;
}
const node = this.$getNode(key);
if (node) {
node.isHighlighted = false;
this.nodes[key].isHighlighted = false;
}
}
highlightLink(key = Object.keys(this.links)) {
if (Array.isArray(key)) {
key.forEach(k => {
k&&this.highlightLink(k)
})
return;
}
const link = this.$getLink(key);
if (link) {
link.isHighlighted = true;
this.links[key].isHighlighted = true;
}
}
unhighlightLink(key = Object.keys(this.links)) {
if (Array.isArray(key)) {
key.forEach(k => {
k&& this.unhighlightLink(k)
})
return;
}
const link = this.$getLink(key);
if (link) {
link.isHighlighted = false;
this.links[key].isHighlighted = false;
}
}
toggleText(key = Object.keys(this.nodes),bool) {
if (Array.isArray(key)) {
key.forEach(k => {
k&&this.toggleText(k,bool)
})
return;
}
const node = this.getNode(key);
if (node) {
node.setData({
isTextVisible: bool
})
}
}
toggleCaption(key = Object.keys(this.nodes),bool) {
if (Array.isArray(key)) {
key.forEach(k => {
k&&this.toggleCaption(k,bool)
})
return;
}
const node = this.getNode(key);
if (node) {
node.setData({
isCaptionVisible: bool
})
}
}
grayNode(key = Object.keys(this.nodes)){
if (Array.isArray(key)) {
key.forEach(k => {
k&&this.grayNode(k)
})
return;
}
const node = this.$getNode(key);
if (node) {
node.isEnabled = false;
this.nodes[key].isEnabled = false;
}
}
ungrayNode(key = Object.keys(this.nodes)){
if (Array.isArray(key)) {
key.forEach(k => {
k&&this.ungrayNode(k)
})
return;
}
const node = this.$getNode(key);
if (node) {
node.isEnabled = true;
this.nodes[key].isEnabled = true;
}
}
ungrayLink(key = Object.keys(this.links)){
if (Array.isArray(key)) {
key.forEach(k => {
k&&this.grayLink(k)
})
return;
}
const link = this.$getLink(key);
if (link) {
link.isEnabled = true;
this.links[key].isEnabled = true;
}
}
grayLink(key = Object.keys(this.links)){
if (Array.isArray(key)) {
key.forEach(k => {
this.ungrayLink(k)
})
return;
}
const link = this.$getLink(key);
if (link) {
link.isEnabled = false;
this.links[key].isEnabled = false;
}
}
getHightlightedNodes() {
return Object.keys(this.nodes).filter(k => this.nodes[k].isHighlighted)
}
getHightlightedLinks() {
return Object.keys(this.links).filter(k => this.links[k].isHighlighted)
}
getGrayNodes() {
return Object.keys(this.nodes).filter(k => this.nodes[k].isEnabled)
}
getGrayLinks() {
return Object.keys(this.links).filter(k => this.links[k].isEnabled)
}
copyNode(id) {
if (id) {
const node = this.$getNode(id);
if (node) {
this.myDiagram.select(node);
}
}
this.myDiagram.commandHandler.copySelection();
}
pasteNode(id) {
if (id) {
const node = this.$getNode(id);
if (node) {
this.myDiagram.select(node);
}
}
const node = this.myDiagram.commandHandler.pasteSelection(this.myDiagram.lastInput.documentPoint);
}
$getNode(key) {
const node = this.myDiagram.findNodeForKey(key);
return node
}
$getLink(key) {
return this.myDiagram.findLinkForKey(key);
}
getNode(key) {
return this.nodes[key]
}
getNodes() {
return Object.keys(this.nodes).map(key => this.nodes[key])
}
getLinks() {
return Object.keys(this.links).map(key => this.links[key])
}
getSelectedNodes() {
const nodes = this.myDiagram.selection;
const list = [];
nodes.each((node) => {
list.push(node);
})
return list
}
getSelectedLinks() {
const links = this.myDiagram.selection;
const list = [];
links.each((link) => {
list.push(link);
})
return list
}
getLinkData(key) {
return getFormatData(this.$getLink(key));
}
getNodeData(key) {
return getFormatData(this.$getNode(key));
}
clear() {
this.myDiagram.clear();
}
setModel(model) {
console.log(model,' opopopo++++')
try {
if (typeof model == 'string') {
model = JSON.parse(model);
}
} catch (e) {
console.error(e);
}
if (typeof model == 'object') {
model = formateModelData({
"class": "go.GraphLinksModel",
"linkFromPortIdProperty": "fromPort",
"linkToPortIdProperty": "toPort",
...model
});
model = JSON.stringify(model);
}
model = go.Model.fromJson(model);
model.linkKeyProperty = 'key';
this.myDiagram.model = model;
}
mergeModel(data){
this.myDiagram.model.mergeModel(data);
}
getModel(toJson = true) {
const json = this.myDiagram.model;
return toJson ? JSON.parse(json.toJson()) : json;
}
setNodeProperty(nodeId, key, value) {
let node = this.$getNode(nodeId);
if (node) {
this.myDiagram.startTransaction('set node property' + nodeId);
this.myDiagram.model.setDataProperty(node.data, key, value);
this.myDiagram.commitTransaction('set node property' + nodeId);
}
}
getNodeProperty(nodeId, key) {
let node = this.$getNode(nodeId);
if (node) {
return this.myDiagram.model.getDataProperty(node.data, key);
}
}
setLinkProperty(linkId, key, value) {
let link = this.$getLink(linkId);
if (link) {
this.myDiagram.startTransaction('set link property' + linkId);
this.myDiagram.model.setDataProperty(link.data, key, value);
this.myDiagram.commitTransaction('set link property' + linkId);
}
}
getLinkProperty(linkId, key) {
let link = this.$getLink(linkId);
if (link) {
return this.myDiagram.model.getDataProperty(link.data, key);
}
}
setNodeStyle(nodeId, style) {
let node = this.$getNode(nodeId);
if (node) {
this.myDiagram.startTransaction('set node style' + nodeId);
node.style = style;
this.myDiagram.commitTransaction('set node style' + nodeId);
}
}
setLinkStyle(linkId, style) {
let link = this.$getLink(linkId);
if (link) {
this.myDiagram.startTransaction('set link style' + linkId);
link.style = style;
this.myDiagram.commitTransaction('set link style' + linkId);
}
}
addEventListener(event, listener) {
if (Array.isArray(event)) {
return event.forEach(name => {
this.addEventListener(name, listener);
})
}
if (typeof event == 'string') {
this.events[event].add(listener);
} else if (typeof event == 'function') {
listener = event;
for (let k in this.events) {
this.events[k].add(listener);
}
}
}
removeEventListener(event, listener) {
if (typeof event == 'string') {
this.events[event].delete(listener);
} else if (typeof event == 'function') {
listener = event;
for (let k in this.events) {
this.events[k].delete(listener);
}
}
}
select(key, type = 'node') {
if (type == 'node') {
return this.myDiagram.select(this.myDiagram.findNodeForKey(key));
}
return this.myDiagram.select(this.myDiagram.model.findLinkDataForKey(key));
}
unselect(key, type = 'node') {
if (key) {
if (type == 'node') {
return this.myDiagram.unselect(this.myDiagram.findNodeForKey(key));
}
return this.myDiagram.unselect(this.myDiagram.model.findLinkDataForKey(key));
} else {
this.myDiagram.clearSelection();
}
}
selectAll() {
this.myDiagram.selectAll();
}
unselectAll() {
this.myDiagram.clearSelection();
}
dispose() {
this.links = null;
this.nodes = null;
this.myDiagram.clear();
this.myDiagram = null;
this.myPalette.clear();
this.myPalette = null;
this.events = null;
}
getAllLinksArroundNode(key) {
let node = this.$getNode(key);
if (node) {
let returnLinks = [];
node.findLinksConnected().each((link) => {
returnLinks.push(link);
})
return returnLinks
}
return []
}
getAllLinksArroundNodeData(key) {
return this.getAllLinksArroundNode(key).map((link) => {
return getFormatData(link)
})
}
getAllNodesArroundNode(key) {
let node = this.$getNode(key);
let from = [],
to = [];
if (node) {
node.findLinksConnected().each((link) => {
if (link.fromNode.key == key) {
to.push(link.toNode);
}
if (link.toNode.key == key) {
from.push(link.fromNode);
}
})
}
return {
from,
to,
self: node,
}
}
getAllNodesArroundNodeData(key) {
const data = this.getAllNodesArroundNode(key)
return {
from: data.from.map((node) => {
return getFormatData(node)
}),
to: data.to.map((node) => {
return getFormatData(node)
}),
self: getFormatData(data.self),
}
}
getAllNodesArroundLink(key) {
let link = this.$getLink(key);
let from = [],
to = [];
if (link) {
from.push(link.fromNode);
to.push(link.toNode);
}
return {
self: link,
from,
to,
}
}
getAllNodesArroundLinkData(key) {
const data = this.getAllNodesArroundLink(key)
if (data) {
return {
from: data.from.map((node) => {
return getFormatData(node);
})[0],
to: data.to.map((node) => {
return getFormatData(node);
})[0],
self: getFormatData(data.self)
}
}
return {
from: [],
to: [],
self: null,
}
}
watch(fn) {
this.watchers.add(fn);
}
unwatch(fn) {
this.watchers.delete(fn);
}
moveNode(key, x, y) {
let node = this.$getNode(key);
if (node) {
this.myDiagram.startTransaction('move node' + key);
node.location = new go.Point(x, y);
this.myDiagram.commitTransaction('move node' + key);
}
}
getElementById(id) {
return {
node: this.nodes[id],
link: this.links[id]
};
}
getElementsByData(prop, val) {
return [...Object.keys(this.nodes).filter((key) => {
return this.nodes[key][prop] === val
}).map(id=>this.nodes[id]), ...Object.keys(this.links).filter((key) => {
return this.links[key][prop] === val;
}).map(id=>this.links[id])]
}
removeCategoryTemplate(category) {
if (!this.myPalette.model.nodeDataArray.find((node) => {
return node.category == category
})) {
return
}
this.myPalette.model.nodeDataArray = this.myPalette.model.nodeDataArray.filter((node) => {
return node.category != category;
})
this.myPalette.layoutDiagram();
}
addCategoryTemplate(category) {
if (category) {
if (this.myPalette.model.nodeDataArray.find((node) => {
return node.category == category
})) {
return
}
this.myPalette.model.nodeDataArray = [...this.myPalette.model.nodeDataArray, {
category,
key: category,
text: category,
}]
this.myPalette.layoutDiagram();
}
}
getNodePorts(nodeId) {
let node = this.$getNode(nodeId);
if (node) {
let ports = {};
node.ports.each((port) => {
ports[port.portId] = port;
})
return ports;
}
return {};
}
enlargetCanvas() {
this.myDiagram.scale = this.myDiagram.scale * 1.1;
}
reduceCanvas() {
this.myDiagram.scale = this.myDiagram.scale * 0.9;
}
scrollNodeToCenter(nodeId) {
let node = this.$getNode(nodeId);
if (node) {
this.myDiagram.scrollToRect(node.actualBounds);
}
}
}