How i can make a circle with port in joint JS - javascript

i wanna create an application for drawing graph is comprised of circle and arrows exactly like this :http://jointjs.com/demos/shortest-path so how can i make a circle with ports
in that code i make a application for making graph with rectangle and arrows i can't make circle instead of rectangle ?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="joint.css" />
<script src="joint.js"></script>
</head>
<body>
<div id="myholder"></div>
<script type="text/javascript">
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#myholder'),
width: 10000,
height: 600,
model: graph
/* defaultLink: new joint.dia.Link({
attrs: { '.marker-target': { d: 'M 10 0 L 0 5 L 10 10 z' } }*/
});
var MyElementWithPorts = joint.shapes.basic.Generic.extend({
defaults: joint.util.deepSupplement({
markup: [
'<g class="rotatable">',
'<g class="scalable">',
'<rect/>',
'</g>',
'<g class="inPorts">',
'<g class="port1"><circle/><text/></g>',
'</g>',
'<g class="outPorts">',
'<g class="port3"><circle/><text/></g>',
'</g>',
'</g>'
].join(''),
type: 'basic.Generic',
attrs: {
'.': { magnet: false },
rect: {
width: 150, height: 250,
stroke: 'black'
},
circle: {
r: 5,
magnet: true,
stroke: 'black'
},
text: {
fill: 'black',
'pointer-events': 'none'
},
'.label': { text: 'Model', dx: 5, dy: 5 },
'.inPorts text': { dx:-15, 'text-anchor': 'end' },
'.outPorts text':{ dx: 15 },
'.inPorts circle': { fill: 'PaleGreen' },
'.outPorts circle': { fill: 'Tomato' }
}
}, joint.shapes.basic.Generic.prototype.defaults)
});
var rect = new MyElementWithPorts({
position: { x: 100, y: 30 },
size: { width: 100, height: 30 },
attrs: {
'.port1 text': { text: 'port1' },
'.port2 text': { text: 'port2' },
'.port3 text': { text: 'port3' },
'.port4 text': { text: 'port4' },
'.port1': { ref: 'rect', 'ref-y': .2 },
'.port2': { ref: 'rect', 'ref-y': .4 },
'.port3': { ref: 'rect', 'ref-y': .2, 'ref-dx': 0 },
'.port4': { ref: 'rect', 'ref-y': .4, 'ref-dx': 0 }
}
});
var rect2 = rect.clone();
rect2.translate(600);
rect2.attr({
rect: { fill: 'red' },
text: { fill: 'white', 'font-size': 15 ,text: 'noeud2'},
'.myrect2': { fill: 'red' }
});
//rect2.rotate(30);
//rect2.toFront();
//rect2.embed (rect);
var link = new joint.dia.Link({
source: { id: rect.id },
target: { id: rect2.id }
});
graph.addCells([rect, rect2, link]);
link.attr({
'.connection': { stroke: 'blue' },
'.marker-source': { fill: 'red', d: 'M 10 0 L 0 5 L 10 10 z' },
'.marker-target': { fill: 'yellow', d: 'M 10 0 L 0 5 L 10 10 z' }
});
paper.on('blank:pointerdblclick', function(evt, x, y) {
//alert('pointerdown on a blank area in the paper.')
var rect3 = rect.clone();
rect3.translate(x-80,y-80);
rect3.attr({
rect: { fill: 'red' },
text: { fill: 'white', 'font-size': 15 ,text: 'noeud3'},
'.myrect2': { fill: 'red' }
});
graph.addCells([rect, rect2,rect3,link]);
//graph.addCells(rect3);
});
</script>
</body>
</html>
in that code i make a application for making graph with rectangle and arrows i can't make circle instead of rectangle

The snippet below shows a circle element with rectangular ports.
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#paper'),
width: 400,
height: 200,
gridSize: 20,
model: graph
});
joint.shapes.devs.CircleModel = joint.shapes.devs.Model.extend({
markup: '<g class="rotatable"><g class="scalable"><circle class="body"/></g><text class="label"/><g class="inPorts"/><g class="outPorts"/></g>',
portMarkup: '<g class="port port<%= id %>"><rect class="port-body"/><text class="port-label"/></g>',
defaults: joint.util.deepSupplement({
type: 'devs.CircleModel',
attrs: {
'.body': {
r: 50,
cx: 50,
stroke: 'blue',
fill: 'lightblue'
},
'.label': {
text: 'Circle Model',
'ref-y': 0.5,
'y-alignment': 'middle'
},
'.port-body': {
width: 10,
height: 10,
x: -5,
stroke: 'gray',
fill: 'lightgray',
magnet: 'active'
}
}
}, joint.shapes.devs.Model.prototype.defaults)
});
joint.shapes.devs.CircleModelView = joint.shapes.devs.ModelView;
var circleModel = new joint.shapes.devs.CircleModel({
position: {
x: 150,
y: 100
},
size: {
width: 100,
height: 100
},
inPorts: ['a'],
outPorts: ['b']
});
graph.addCell(circleModel);
#paper {
display: inline-block;
border: 1px solid gray;
}
<script src="https://code.jquery.com/jquery-2.2.3.min.js" integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/0.9.7/joint.min.js"></script>
<div id="paper"></div>

just change the markup. but this time change rect for circle and change the attrs accordingly to the new shape.

Related

Tool tip for static plotline in y-axis

I have drawn two static lines in my chart to indicate high and low range. I could keep labels for the line but I can't keep a tooltip for the the static line. Is there any way I can do this?
yAxis: {
plotLines: [{
value: 70,
width: 1,
color: '#68AF46'
label: {
style: {
color: '#FE7246',
fontWeight: 'bold'
},
text: '70',
align: 'right',
x: -10,
y: 16
},
},
{
value: 180,
width: 1,
color: '#FE7246',
label: {
text: '180',
align: 'right',
style: {
color: '#FE7246',
fontWeight: 'bold'
},
},
}]
}
I find no property to keep tooltip for plotlines.
I don't think this functionality exists by default in Highcharts, but you could create it by listening for the mouseover event on your plotLine and creating the tooltip manually. Then, on mouseout, just dismiss the tooltip.
Here's an example with a plotLine with tooltip on y = 50:
Highcharts.chart('container', {
chart: {
styledMode: true
},
title: {
text: 'Tooltip On PlotLine'
},
yAxis: {
plotLines: [{
value: 50,
width: 1,
color: '#68AF46',
label: {
style: {
color: '#FE7246',
fontWeight: 'bold'
},
text: '50',
align: 'right',
x: -10,
y: 16
},
events: {
mouseover: function(e) {
var series = this.axis.series[0];
var chart = series.chart;
var PointClass = series.pointClass;
var tooltip = chart.tooltip;
var point = (new PointClass()).init(
series, ['PlotLine', this.options.value]
);
var normalizedEvent = chart.pointer.normalize(e);
point.tooltipPos = [
normalizedEvent.chartX - chart.plotLeft,
normalizedEvent.chartY - chart.plotTop
];
tooltip.refresh(point);
},
mouseout: function(e) {
this.axis.chart.tooltip.hide();
}
}
}, ]
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May']
},
series: [{
data: [10, 30, 20, 60, 80]
}]
});
#import 'https://code.highcharts.com/css/highcharts.css';
#container {
height: 400px;
max-width: 800px;
margin: 0 auto;
}
.highcharts-tooltip-box {
fill: black;
fill-opacity: 0.6;
stroke-width: 0;
}
.highcharts-tooltip text {
fill: white;
text-shadow: 0 0 3px black;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
You can also add two additional dummy series and hide them under the plot lines:
series: [{
data: [1, 50, 100, 200]
}, {
data: [70, 70, 70, 70],
showInLegend: false,
lineWidth: 0.5,
color: 'transparent',
marker: {
radius: 0
},
tooltip: {
pointFormat: 'plotLine1'
}
}, {
data: [180, 180, 180, 180],
showInLegend: false,
color: 'transparent',
marker: {
radius: 0
},
tooltip: {
pointFormat: 'plotLine2'
}
}]
Live demo: http://jsfiddle.net/BlackLabel/2Ln05yes/
API Reference: https://api.highcharts.com/highcharts/series.line.tooltip

Two Ports positions in JointJS

I'm new to JointJS and I'm having trouble working with door positions.
I have 3 ports, 1 of type, 'Out', and 2 of type 'in'.
I'd like to change the position of only one of the 'in' type ports, but I'm not getting it.
Here I leave an image and a link of the code. Thanks for the help right away.
var m1 = new joint.shapes.devs.Model({
position: { x: 50, y: 50 },
size: { width: 100, height: 30 },
inPorts: ['in1','in2'],
outPorts: ['out'],
ports: {
groups: {
'in': {
position: "top",
attrs: {
'.port-body': {
r: "6",
fill: 'blue',
magnet: 'passive'
},
'.port-label': {
fill: "transparent"
}
}
},
'out': {
position: "bottom",
portLabelMarkup: '<text fill="yellow"/>',
attrs: {
'.port-body': {
r: "6",
fill: 'red'
},
'.port-label': {
fill: "transparent"
}
}
}
}
},
attrs: {
'.label': { text: 'node 1', 'ref-x': .5, 'ref-y': .2 },
rect: { fill: 'LightGrey', rx: 15, ry: 15 }
}
}).addTo(graph);
Link of the code
I'd suggest NOT to use the shapes based on the devs.Model as it's a legacy implementation of ports. Since the JointJS v1.0 you can add ports to any shape.
for example:
var m1 = new joint.shapes.standard.Rectangle({
position: { x: 425, y: 60 },
size: { width: 200, height: 100 },
ports: {
groups: {
'in': {
position: {
name: 'top',
args: { dr: 0, dx: 0, dy: -9 }
},
}
},
items: [
{ group: 'in', args: { y: -10 }, id: 'portId'}
]
}
});
Port positions is set using the layout functions. In your example there is the top layout - it means port positions is computed using the joint.layout.Port.top implementation. You can override the result using the args properties on a port:
// set args on newly added
m1.addPort({ group: 'in', args: { y: -20 } });
// update existing
m1.portProp('portId', 'args/y', -20)
for more information see the layout docs: https://resources.jointjs.com/docs/jointjs/v2.2/joint.html#layout.Port

How to Add an image in the center of an Atomic shape in jointJS-Rappid

Is there any way I can add an image in the center of an Atomic shape which has 3 in-ports and 3 out-ports?
I don't want a solution exclusively for an Atomic shape. It could be a custom shape but in case of a custom shape I want it to have in-ports and out-ports.
My so far code (without adding this image) is:
new joint.shapes.devs.Atomic({
size: { width: 4, height: 3 },
inPorts: ['in1','in2','in3'],
outPorts: ['out1','out2','out3'],
attrs: {
rect: { fill: '#ffffff', rx: 2, ry: 2 },
text: { text: 'Workitem', fill: '#000000', 'font-size': 10, stroke: '#000000', 'stroke-width': 0 },
'.inPorts circle': { fill: '#dddddd', opacity: 0.9 },
'.outPorts circle': { fill: '#dddddd', opacity: 0.9 },
'.inPorts text, .outPorts text': { 'font-size': 9 }
}
})
please try the below, i added an image to the attrs {} The image attribute works for joint.shapes.basic.device. Hoping it works for Atomic as well.
new joint.shapes.devs.Atomic({
size: { width: 4, height: 3 },
inPorts: ['in1','in2','in3'],
outPorts: ['out1','out2','out3'],
attrs: {
rect: { fill: '#ffffff', rx: 2, ry: 2 },
image: { xlink:href: '/path to image' },
text: { text: 'Workitem', fill: '#000000', 'font-size': 10, stroke: '#000000', 'stroke-width': 0 },
'.inPorts circle': { fill: '#dddddd', opacity: 0.9 },
'.outPorts circle': { fill: '#dddddd', opacity: 0.9 },
'.inPorts text, .outPorts text': { 'font-size': 9 }
}
})
It was a very complex solution but finally I came up with the following code which works great and it's stable:
/*Code to create a new Workitem Shape with an image inside it*/
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#paper'),
width: 600,
height: 600,
gridSize: 20,
model: graph
});
joint.shapes.devs.MyImageModel = joint.shapes.devs.Model.extend({
markup: '<g class="rotatable"><g class="scalable"><rect class="body"/></g><image/><text class="label"/><g class="inPorts"/><g class="outPorts"/></g>',
defaults: joint.util.deepSupplement({
type: 'devs.MyImageModel',
size: {
width: 80,
height: 80
},
attrs: {
rect: {
stroke: '#d1d1d1',
fill: {
type: 'linearGradient',
stops: [{
offset: '0%',
color: 'white'
}, {
offset: '50%',
color: '#d1d1d1'
}],
attrs: {
x1: '0%',
y1: '0%',
x2: '0%',
y2: '100%'
}
}
},
circle: {
stroke: 'gray'
},
'.label': {
text: 'My Workitem',
'ref-y': +65,
'font-size': 14
},
'.inPorts circle': {
fill: '#dddddd', opacity: 0.9
},
'.outPorts circle': {
fill: '#dddddd', opacity: 0.9
},
'.inPorts text, .outPorts text': { 'font-size': 9 },
image: {
'xlink:href': 'img/person.png',
width: 80,
height: 50,
'ref-x': .5,
'ref-y': .5,
ref: 'rect',
'x-alignment': 'middle',
'y-alignment': 'middle'
}
}
}, joint.shapes.devs.Model.prototype.defaults)
});
joint.shapes.devs.MyImageModelView = joint.shapes.devs.ModelView;
// Usage:
var imageModel = new joint.shapes.devs.MyImageModel({
position: {
x: 200,
y: 250
},
size: {
width: 150,
height: 100
},
inPorts: ['in1', 'in2','in3'],
outPorts: ['out1', 'out2', 'out3']
});
graph.addCell(imageModel);

change port color when cell is moving

I use jointjs / rappid.
I would like to change the attributes of a port (e.g. the color of the inPort: in0_2) when the cell is moved. How can I get access to these attributes?
Example of a cell: http://www.epro.de/exchange/virtual-reality/jointjs/celltest.jpg
I guess it's easy - I have tried different ways but can't find a solution.
Any hints?
I use the following code to create the cell and the ports.
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#paper-container'),
width: 1000,
height: 1000,
gridSize: 10,
drawGrid: true,
model: graph,
});
var l_st0 = myShapes ();
l_st0.set ('inPorts',(['in0_1', 'in0_2']));
l_st0.set ('outPorts',(['outx']));
l_st0.attr ('.label/text','MinTest');
l_st0.position (100,100);
graph.addCell(l_st0);
l_st0.on ('change:position', function() {
console.log (" change port color ");
});
function myShapes (){
joint.shapes.devs.GenericBasic = joint.shapes.devs.Model.extend({
portMarkup: '<rect class="port-body"/>',
defaults: joint.util.deepSupplement({
type: 'devs.GenericBasic',
inPorts: [],
outPorts: [],
attrs: {
'.label': {
'ref-x': .5,
'ref-y': 5,
'font-size': 12,
'text-anchor': 'middle',
fill: '#000'
},
'.body': {
'ref-width': '100%',
'ref-height': '100%',
stroke: '#000'
}
},
ports: {
groups: {
'in': {
attrs: {
'.port-label': {
'font-size': 12,
'text-anchor': 'start',
x: -10,
fill: '#000000'
},
'.port-body': {
stroke: '#000000',
'text-anchor': 'start',
x:-20,
width: 20,
height: 0.5
}
},
label: {
position: {
name: 'right',
args: {
y: 0
}
}
}
},
'out': {
attrs: {
'.port-label': {
'font-size': 12,
fill: '#000',
'text-anchor': 'start',
x: -40
},
'.port-body': {
stroke: '#000000',
width: 20,
height: 0.5
}
},
label: {
position: {
name: 'right',
args: {
y: 0
}
}
}
}
}
}
}, joint.shapes.devs.Model.prototype.defaults)
});
joint.shapes.devs.GenericModelView = joint.shapes.devs.ModelView;
var mx = new joint.shapes.devs.GenericBasic ({
size: { width: 80, height: 100 },
attrs: {
rect: {
stroke: 'black',
'stroke-width': 1
},
}
});
return mx;
}
I solved it this way - like it is described in the jointjs documentation.
l_st0.on ('change:position', function() {
//optimization is missing
var l_portsIn = this.get ('inPorts');
if (l_portsIn.length>0){
this.portProp (l_portsIn[0],'attrs/rect',{stroke: 'red' });
}
}

JointJS Rappid Toolkit Diamond shape?

I want to add a diamond shape to the Rappid stencil like I added the rectangle and the circle.
var r = new joint.shapes.basic.Rect({
position: { x: 10, y: 10 }, size: { width: 50, height: 30 },
attrs: { rect: { fill: '#2ECC71' }, text: { text: 'rect', fill: 'black' } }
});
var c = new joint.shapes.basic.Circle({
position: { x: 70, y: 10 }, size: { width: 50, height: 30 },
attrs: { circle: { fill: '#9B59B6' }, text: { text: 'circle', fill: 'white' } }
});
stencil.load([r, c]);
I tried using new joint.shapes.basic.Diamond but it doesn't seem that there's such object.
You can use the joint.shapes.basic.Path to create an arbitrary shaped element. A diamond, or rhombus, can be defined as:
var rhombus = new joint.shapes.basic.Path({
size: { width: 70, height: 70 },
attrs: {
path: { d: 'M 30 0 L 60 30 30 60 0 30 z', fill: 'blue' },
text: { text: 'Rhombus', 'ref-y': .5, fill: 'white' }
}
})
Note the d attribute which consists of SVG path data (https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d).

Categories

Resources