I'm new with jointjs and I try to constraint a rectangle with ports to a line.
I tried to reproduce tutorial, that works with a basic.Circle, with a basic.Rect but not with devs.Model
Could someone explian me why and how to solve this problem?
Many thanks in advance!
Here is my code :
var width=400, height=1000;
var ConstraintElementView = joint.dia.ElementView.extend({
pointermove: function(evt, x, y) {
joint.dia.ElementView.prototype.pointermove.apply(this, [evt, 100, y]);
}
});
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({ el: $('#myholder'), width: width, height: height, gridSize: 1, model: graph, elementView: ConstraintElementView});
var m1 = new joint.shapes.devs.Model({
position: { x: 20, y: 20 },
size: { width: 90, height: 90 },
inPorts: [''],
outPorts: [''],
attrs: {
'.label': { text: 'Model', 'ref-x': .4, 'ref-y': .2 },
rect: { fill: '#2ECC71' },
'.inPorts circle': { fill: '#16A085' },
'.outPorts circle': { fill: '#E74C3C' }
}
});
var m2=m1.clone();
m2.translate(0,300);
var earth = new joint.shapes.basic.Circle({
position: { x: 100, y: 20 },
size: { width: 20, height: 20 },
attrs: { text: { text: 'earth' }, circle: { fill: '#2ECC71' } },
name: 'earth'
});
graph.addCell([m1, m2, earth]);
Why does it not work?
devs.Model is not rendered via ContraintElementView to the paper.
devs.Model uses devs.ModelView for rendering, basic.Circle and basic.Rect use ContraintElementView.
JointJS dia.Paper searches for a view defined in the same namespace as the model first. If found, it uses it. It uses one from the paper elementView option otherwise. i.e. joint.shapes.devs.ModelView found for devs.Model but no view found for basic.Circle (no joint.shapes.basic.RectView is defined)
How to make it work?
define elementView paper option as a function. In that case paper don't search the namespace and uses the result of the function first.
Note that in order to render ports devs.ModelView is still required.
i.e.
var paper = new joint.dia.Paper({
elementView: function(model) {
if (model instanceof joint.shapes.devs.Model) {
// extend the ModelView with the constraining method.
return joint.shapes.devs.ModelView.extend({
pointermove: function(evt, x, y) {
joint.dia.ElementView.prototype.pointermove.apply(this, [evt, 100, y]);
}
});
}
return ConstraintElementView;
}
});
http://jsfiddle.net/kumilingus/0bjqg4ow/
What is the recommended way to do that?
JointJS v0.9.7+
not to use custom views that restrict elements movement
use restrictTranslate paper option instead.
i.e.
var paper = new joint.dia.Paper({
restrictTranslate: function(elementView) {
// returns an area the elementView can move around.
return { x: 100, y: 0, width: 0, height: 1000 }
};
});
http://jsfiddle.net/kumilingus/atbcujxr/
I think this could help you :
http://jointjs.com/demos/devs
Related
I use Ports API and JointJS 2.0. The problem is that i created ports, but they are not active. Port just become part of rect. I can't drag a link from it. Sorry, but i can't setup fiddle link with joint 2.0. I have "joint is not defined" in console.
Here is code:
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#myholder'),
width: 600,
height: 200,
model: graph,
gridSize: 1
});
var port = {
args: {},
markup: '<rect width="10" height="10" stroke="red"/>'
};
var rect = new joint.shapes.basic.Rect({
position: { x: 100, y: 30 },
size: { width: 100, height: 30 },
attrs: { rect: { fill: 'blue' }, text: { text: 'my box', fill: 'white' } },
ports: {
groups: {},
items: [ port ]
}
});
graph.addCells([rect]);
Here is jsfiddle with old joint
In stencils we have png, on drop to paper we replace cell[png] with svg.
cell - represents png
vectorString - markup of png
var currentSvg = new joint.shapes.basic.pwmeter({
position: { x: bbox.x, y: bbox.y },
size: { height: cell.attributes.minHeight, width: cell.attributes.minWidth },
minWidth: cell.attributes.minWidth,
minHeight: cell.attributes.minHeight,
markup: vectorString,
type: cell.attributes.type,
fileName: cell.attributes.fileName,
isInteractive: true,
elementClassName: cell.attributes.elementClassName,
isAnimatedDevice: cell.attributes.isAnimatedDevice,
attrs: {
'.myClass': {
fill: '#ffffff',
stroke: '#000000'
}
}
});
currentSvg.addTo(Rappid.graph);
we are making pwmeter by extending Image
joint.shapes.basic.pwmeter = joint.shapes.basic.Image.extend({
type: 'basic.pwmeter',
initialize: function () {
return joint.shapes.basic.Image.prototype.initialize.apply(this, arguments);
}
});
We drop png from stencils to paper, and get svg markup for corresponding png,
we call currentSvg.addTo(Rappid.graph), during execution of this, all text in meter [svg] are replaced by blank.
our text - 0
auto generated code replaces my text, we are not able to figure out why this is happening
-
above is the generated text
We are new to jointjs, we think we are doing something wrong during extending.
I can see there is a markup in you settings. Make sure there is a text 'placeholder' in the markup.
in this example attr text is tied with the <text/> element
new joint.shapes.basic.pwmeter({
markup: '<g><image/><text/></g>',
attrs: {
text: { text: '48x48' },
image: { 'xlink:href': 'http://placehold.it/48x48', width: 48, height: 48 }
},
size: { width : 50, height: 50 },
position: { x:200, y: 50},
}).addTo(graph)
but in here, attr text has no matching element in the markup, therefore it won't be rendered.
new joint.shapes.basic.pwmeter({
markup: '<g><image/></g>',
attrs: {
text: { text: '90x90' },
image: { 'xlink:href': 'http://placehold.it/90x90', width: 90, height: 90 }
},
size: { width : 90, height: 90 },
position: { x:50, y: 50},
}).addTo(graph)
more information about attr property could be found here http://resources.jointjs.com/docs/jointjs/v1.0/joint.html#joint.dia.Element.presentation
I have created a DrawContainer and I want to add a sprite with a tooltip to it, ideally with dynamic content. Unfortunately, the tooltip does not appear at all. How can the code below be corrected?
Thanks in advance.
var r = this.getSurface().add({
type: "rect", strokeStyle: "#9090f0", x: 10, y: 10, width: 40, height: 40
});
var tip = Ext.create('Ext.tip.ToolTip', {
html: "Tooltip"
});
r.on("mouseover", function() {
tip.show();
});
You could try using spriteevents plugin on the draw container, like so
var tip = Ext.create('Ext.tip.ToolTip', {
html: "Tooltip"
});
var s = Ext.create({
xtype: 'draw',
renderTo: document.body,
width: 400,
height: 400,
plugins: ['spriteevents'],
sprites: [
{
type: "rect",
strokeStyle: "#9090f0",
x: 10,
y: 10,
width: 100,
height: 100
}
],
listeners: {
spritemouseover: function (item, event) {
tip.show();
},
spritemouseout: function (item, event) {
tip.hide()
}
}
});
I'm trying to create graph using JointJS, where Link starts from output port od 1 element and can be connected with whole other element (or current element itself) - not only with input port.
My idea is to modify input port style, to cover element it belongs to, but I have problems to change port shape in any way, it's always a little circle on left side of element and none of my css works.
Can someone give any advice?
you can update the port attrib0utes as follows:
var a = new joint.shapes.devs.Model({
position: { x: 50, y: 50 },
size: { width: 100, height: 100 },
attrs: {
'.port-label': {
fill: 'red'
},
// change position and size of the 'a' port
'.inPorts .port0 circle': {
r: 15,
'ref-x': -20,
'ref-y': 10,
stroke: 'red',
'stroke-width': 5
},
// change color on a single port
'.inPorts .port0 .port-label': {
fill: 'blue',
}
},
inPorts: ['a', 'aa', 'aaa'],
outPorts: ['b']
https://jsfiddle.net/vtalas/43sthc6g/
However, you don't need to use ports to achieve this, you can connect to the whole element directly like this:
var a = new joint.shapes.basic.Rect({
size: { width: 100, height: 100 },
position: { x: 300, y: 300 },
attrs: {
'rect': { magnet: true }
}
}).addTo(graph);
var b = new joint.shapes.basic.Rect({
size: { width: 100, height: 100 },
position: { x: 100, y: 100 },
attrs: {
'rect': { magnet: true }
}
}).addTo(graph);
new joint.dia.Link({ source: { id: b.id }, target: { id: a.id } }).addTo(graph);
result: https://jsfiddle.net/vtalas/davLzsng/
I have an FSA in joint.js, and I need to make the states (circles) semi-filled to specific ratios, like 1/2 or 1/6, starting from the bottom of the circle. The tricky part is that it needs to be done twice - A larger semi-fill and a smaller semi-fill over it.
This is what i am trying to do:
I'm lost as to how to accomplish this.
The trick is to create three SVG circles and define clip paths for them. The following example creates a custom JointJS shape (inheriting from fsa.State) with custom SVG markup that enables the coloring that you have shown in the image:
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({ el: $('#paper'), width: 650, height: 400, model: graph });
joint.shapes.fsa.MyState = joint.shapes.fsa.State.extend({
markup: [
'<g class="rotatable"><g class="scalable">',
'<clipPath id="clip-top1"><rect x="-30" y="0" width="60" height="30"/></clipPath>',
'<clipPath id="clip-top2"><rect x="-30" y="15" width="60" height="30"/></clipPath>',
'<circle class="a"/><circle class="b"/><circle class="c"/>',
'</g><text/></g>'
].join(''),
defaults: joint.util.deepSupplement({
type: 'fsa.MyState',
size: { width: 60, height: 60 },
attrs: {
'circle': { fill: 'white' },
'.b': { fill: 'red', 'clip-path': 'url(#clip-top1)' },
'.c': { fill: 'blue', 'clip-path': 'url(#clip-top2)' }
}
}, joint.shapes.fsa.State.prototype.defaults)
});
var mystate1 = new joint.shapes.fsa.MyState({
position: { x: 50, y: 50 },
size: { width: 100, height: 100 },
attrs: { text: { text: 'my state 1' } }
});
graph.addCell(mystate1);
var mystate2 = new joint.shapes.fsa.MyState({
position: { x: 50, y: 160 },
size: { width: 50, height: 50 }
});
graph.addCell(mystate2);