В моем проекте я определяю пользовательскую форму - toolElement
- которая инкапсулирует это поведение, а затем расширяет его с помощью других настраиваемых фигур по мере необходимости.
Полное раскрытие: Эта техника сильно опирается на код jointjs для ссылок - я просто адаптировал его: о)
Вот является jsfiddle показывая его работать:
http://jsfiddle.net/kj4bqczd/3/
toolElement
определяется следующим образом:
joint.shapes.tm.toolElement = joint.shapes.basic.Generic.extend({
toolMarkup: ['<g class="element-tools">',
'<g class="element-tool-remove"><circle fill="red" r="11"/>',
'<path transform="scale(.8) translate(-16, -16)" d="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z"/>',
'<title>Remove this element from the model</title>',
'</g>',
'</g>'].join(''),
defaults: joint.util.deepSupplement({
attrs: {
text: { 'font-weight': 400, 'font-size': 'small', fill: 'black', 'text-anchor': 'middle', 'ref-x': .5, 'ref-y': .5, 'y-alignment': 'middle' },
},
}, joint.shapes.basic.Generic.prototype.defaults)
});
Вы можете добавить дополнительную разметку если вам нужны другие инструменты, а также кнопка удаления.
Поведение удалить воплощен в настраиваемое представление:
joint.shapes.tm.ToolElementView = joint.dia.ElementView.extend({
initialize: function() {
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
},
render: function() {
joint.dia.ElementView.prototype.render.apply(this, arguments);
this.renderTools();
this.update();
return this;
},
renderTools: function() {
var toolMarkup = this.model.toolMarkup || this.model.get('toolMarkup');
if (toolMarkup) {
var nodes = V(toolMarkup);
V(this.el).append(nodes);
}
return this;
},
pointerclick: function (evt, x, y) {
this._dx = x;
this._dy = y;
this._action = '';
var className = evt.target.parentNode.getAttribute('class');
switch (className) {
case 'element-tool-remove':
this.model.remove();
return;
break;
default:
}
joint.dia.CellView.prototype.pointerclick.apply(this, arguments);
},
});
Вы можете расширить их, чтобы сделать свои собственные формы. В моем проекте, я делаю диаграммы потоков данных и здесь является определение Process
формы:
joint.shapes.tm.Process = joint.shapes.tm.toolElement.extend({
markup: '<g class="rotatable"><g class="scalable"><circle class="element-process"/><title class="tooltip"/></g><text/></g>',
defaults: joint.util.deepSupplement({
type: 'tm.Process',
attrs: {
'.element-process': { 'stroke-width': 1, r: 30, stroke: 'black', transform: 'translate(30, 30)' },
text: { ref: '.element-process'}
},
size: { width: 100, height: 100 }
}, joint.shapes.tm.toolElement.prototype.defaults)
});
и вид:
joint.shapes.tm.ProcessView = joint.shapes.tm.ToolElementView;
Я показать и скрыть разметку инструмента, в зависимости от того, элемент является с использованием CSS. Вы могли бы сделать то же самое, когда парящий (как ссылки делать), если вы хотите:
.element .element-tools {
display: none;
cursor: pointer
}
.element.highlighted .element-tools {
display: inline;
}
Когда оказывается, это выглядит следующим образом (примечание: в моем случае, у меня есть другая кнопка в инструментах, а не только удалить - это то, что зеленая кнопка шеврон я удалил это из образцов кода выше, чтобы сделать их более простыми):
Когда элемент не выделен:
![element tool unhighlighted render](https://i.stack.imgur.com/K6eXE.png)
Когда подсвечивается:
.
![rendering of the tool element](https://i.stack.imgur.com/shgN8.png)
Я могу определить другие формы очень легко, расширяя toolElementВот диаграмма потоков данных формы для хранилищ данных:
![enter image description here](https://i.stack.imgur.com/ThZ0G.png)
и внешние актеры:
![enter image description here](https://i.stack.imgur.com/D1S9s.png)
Здравствуйте, Майк. Возможно ли загрузить код где-нибудь? Я не совсем уверен, как собрать все вместе. – Alexey
Выполнено. См. Jsfiddle здесь: http://jsfiddle.net/kj4bqczd/3/ –
Работает потрясающе! Возможно ли каким-то образом расширить все элементы, чтобы эта подсказка была наверху? Удивительно, что это работает, но мне не нравится идея, что все мои объекты должны иметь Actor в качестве родителя. – Alexey