我有一个 JointJS 代码的 jsFiddle,它给了我想要的东西: https ://jsfiddle.net/RaymondMH/s46uyq8v/156/
但是,当我尝试在我的实际应用程序中使用此代码时,调用中定义的任何函数ElementView.extend()
都不会被调用,并且不会像我想要的那样创建元素。
这就是我把它放在我的代码中的方式:
import { Injectable } from '@angular/core';
import * as joint from '@clientio/rappid';
import * as _ from 'lodash';
import * as V from 'jquery';
@Injectable({
providedIn: 'root'
})
export class SchematicElementService {
private SystemElement: any;
constructor() {
}
public GetNodeElement(): { node: joint.dia.Element, embedId: number } {
let element: joint.dia.Element;
element = new this.SystemElement();
element
.prop('numberOfComponents', 4)
.position(150, 150);
return { node: element, embedId: null };
}
public InitializeDefinitions() {
let componentOutlineRect = {
x: 0, y: 0, width: 215, height: 24,
fill: '#fafafa', stroke: '#000000', 'stroke-width': '0.1'
}
let componentText = {
x: 0, y: 0,
fill: 'black',
'font-size': 13, 'font-family': 'Arial', 'font-weight': 'normal'
}
let componentStatusText = {
x: 14, y: 18,
'font-size': 13, 'font-family': 'Arial', 'font-weight': '600',
fill: 'green'
}
let componentIconRect = {
x: 34, y: 5, width: 16, height: 16,
fill: '#565656'
}
this.SystemElement = joint.dia.Element.extend({
defaults: joint.util.defaultsDeep({
type: 'custom.Element',
outlineColor: 'black',
numberOfComponents: 1,
size: {
width: 215,
height: 24
},
attrs: {
body: {
...componentOutlineRect,
fill: '#bebebe'
},
bodytitle: {
...componentText
},
components: {
...componentOutlineRect,
y: 24,
}
}
}),
markup: [
{ tagName: 'rect', selector: 'body' },
{ tagName: 'text', selector: 'bodytitle' },
{ tagName: 'rect', selector: 'components' },
{ tagName: 'text', selector: 'componentStatus' },
{ tagName: 'rect', selector: 'componentIcons' },
{ tagName: 'text', selector: 'text' }
]
});
this.SystemElement.ElementView = joint.dia.ElementView.extend(
{
events: {
'dblclick': 'onDblClick',
'click .components': 'onComponentClick'
},
init: function () {
console.log('************* init() function called!');
var model = this.model;
this.listenTo(model, [
'change:fillColor',
'change:outlineColor',
].join(' '), this.update);
this.listenTo(model, 'change:numberOfComponents', this.render);
},
render: function () {
console.log('**************** render function called!');
var markup = this.constructor.markup;
var body = this.vBody = markup.body.clone();
var bodyTitle = this.vBodyTitle = markup.bodytitle.clone().text('A - Static Structural');
var components = this.vComponents = [];
var componentStatus = this.vComponentStatus = [];
var componentIcons = this.vComponentIcons = [];
var componentLabels = this.vComponentLabels = [];
for (var i = 0, n = this.model.prop('numberOfComponents'); i < n; i++) {
components.push(markup.components.clone());
componentStatus.push(markup.componentStatus.clone().text('✓'));
componentIcons.push(markup.componentIcons.clone());
componentLabels.push(markup.text.clone().text('Component ' + (i + 1)));
}
this.vel.empty().append(
_.flatten([
body,
components
])
);
this.translate();
this.update();
},
update: function () {
this.updateBody();
this.updateComponents();
},
updateBody: function () {
var model = this.model;
var bodyAttributes = {
...componentOutlineRect,
fill: '#aaaaaa',
};
this.vBody.attr(bodyAttributes);
var bodyTitle = this.vBodyTitle;
bodyTitle.attr({
...componentText,
'font-weight': '600',
transform: 'translate(14,16)'
});
this.vel.append(bodyTitle);
},
updateComponents: function () {
console.log('************** updateComponents called!');
var model = this.model;
var numberOfComponents = model.prop('numberOfComponents');
var vComponents = this.vComponents;
for (var i = 0; i < numberOfComponents; i++) {
vComponents[i].attr({
...componentOutlineRect,
y: 24 * (i + 1),
'data-index': i
});
}
var vComponentStatus = this.vComponentStatus;
for (var i = 0; i < numberOfComponents; i++) {
var vStatus = vComponentStatus[i];
var tx = 14;
var ty = 24 * (i + 1);
vStatus.attr({
...componentStatusText,
transform: 'translate(' + tx + ',' + ty + ')'
});
this.vel.append(vStatus);
}
var vComponentIcons = this.vComponentIcons;
for (var i = 0; i < numberOfComponents; i++) {
var vIcon = vComponentIcons[i];
vIcon.attr({
...componentIconRect,
x: 34,
y: 24 * (i + 1) + 4
});
this.vel.append(vIcon);
}
var vComponentLabels = this.vComponentLabels;
for (var i = 0; i < numberOfComponents; i++) {
var vText = vComponentLabels[i];
var tx = 58;
var ty = 24 * (i + 2) - 8;
vText.attr({
...componentText,
transform: 'translate(' + tx + ',' + ty + ')'
});
this.vel.append(vText);
}
},
onComponentClick: function (evt) {
var index = +V(evt.target).attr('data-index');
var model = this.model;
var numberOfComponents = model.prop('numberOfComponents');
var vComponents = this.vComponents;
for (var i = 0; i < numberOfComponents; i++) {
vComponents[i].attr({
fill: i === index ? '#dddddd' : "#fafafa"
});
}
},
onDblClick: function () {
this.model.prop('faded', !this.model.prop('faded'));
}
});
// SEE COMMENTS BELOW REGARDING THIS COMMENTED CODE:
//}, {
// markup: {
// body: V('rect').addClass('body'),
// bodytitle: V('text').addClass('bodytitle'),
// components: V('rect').addClass('components'),
// componentStatus: V('text').addClass('componentStatus'),
// componentIcons: V('rect').addClass('componentIcons'),
// text: V('text').addClass('text')
// }
//});
}
}
元素初始化如下:
ngOnInit(): void {
this.schematicElementService.InitializeDefinitions();
this.graph = new joint.dia.Graph();
this.paper = new joint.dia.Paper({
model: this.graph,
cellViewNamespace: joint.shapes.basic,
el: $('#paper'),
width: 2400,
height: 2400,
origin: { x: 600, y: 600 },
gridSize: 1,
// interactive: { addLinkFromMagnet: false },
linkPinning: false
});
}
元素被添加到图表中,如下所示:
let nodeData = this.schematicElementService.GetNodeElement();
this.graph.addCell(nodeData.node);
与 jsFiddle 不同的方式是,Markup 被放置在Element.extend()
函数中而不是在ElementView.extend()
(如 中的注释代码所示ElementView.extend()
)中。
如上所述实现,我得到了几个“框”,但由于没有使用 ElementView 中的功能,它不会像我期望的那样处理事情。即没有文本,也没有多个框,因为这些是在函数中处理的。
当我从 中删除标记Element.extend()
并将其放入ElementView.extend()
(即取消注释上面的注释代码)时,处理此错误时出现以下错误:
ERROR Error: dia.ElementView: markup required
at child.renderMarkup (rappid.js:19452)
at child.render (rappid.js:19483)
at child.protoProps.render (rappid.js:18246)
at child.confirmUpdate (rappid.js:19372)
at child.updateView (rappid.js:29615)
at child.updateViewsBatch (rappid.js:29812)
at child.updateViews (rappid.js:29668)
at child.requestViewUpdate (rappid.js:29539)
at child.renderView (rappid.js:30305)
at child.onCellAdded (rappid.js:29261)
我添加到函数中的console.log()
所有调用都不会写入控制台,因此这些函数都不会被调用。在联合数据结构中定义我的自定义元素,如 injoint.shapes.custom = {}
并没有什么区别。使用 JointJS 或 Rappid 库时,我遇到了同样的问题。
有人看到我在这里做错了吗?我无法弄清楚如何使这项工作。
提前感谢您提供的任何帮助。