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
Related
I'm using rappidjs 3.2 and I'm trying to make a stencil shape that changes shape when I drop it to the paper. For testing purposes I want to just print in the console the type of shape throught dragEndClone (As far as I understood from documentation this is what I need to use).
Stencil :
var stencil = new joint.ui.Stencil({
paper: paper,
scaleClones: true,
width: 240,
groups: {
myShapesGroup1: { index: 1, label: 'My Shapes' }
},
dropAnimation: true,
groupsToggleButtons: true,
search: {
'*': ['type', 'attrs/label/text']
},
layout: true, // Use default Grid Layout
dragEndClone: function (el) {
console.log(el.get('type'));
}
});
document.querySelector('.stencil-container').appendChild(stencil.el);
Shape :
joint.dia.Element.define('standard.Rectangle', {
attrs: {
body: {
refWidth: '100%',
refHeight: '100%',
strokeWidth: 0,
stroke: '#000000',
fill: {
type: 'linearGradient',
stops: [
{ offset: '0%', color: '#FEB663' },
{ offset: '100%', color: '#31D0C6' }
],
// Top-to-bottom gradient.
attrs: { x1: '0%', y1: '0%', x2: '0%', y2: '100%' }
}
},
label: {
textVerticalAnchor: 'middle',
textAnchor: 'middle',
rx: '1%',
refX: '50%',
refY: '50%',
fontSize: 14,
fill: '#333333',
text: 'Siemans'
}
}
}, {
markup: [{ tagName: 'rect', selector: 'body' }, { tagName: 'text', selector: 'label' }]
});
Add shape to stencil :
stencil.render().load({ myShapesGroup1: [{ type: 'standard.Rectangle' }] });
The code previously shown gives me this error :
rappid.js:50779 Uncaught TypeError: Cannot read property 'getBBox' of undefined
at child.drop (rappid.js:50779)
at child.onDragEnd (rappid.js:50638)
at HTMLDocument.dispatch (jquery.js:5429)
at HTMLDocument.elemData.handle
dragEndClone needs to return an element.
dragEndClone: function (el) {
console.log(el.get('type'));
return el.clone();
}
I am trying to create a network graph using visjs but the problem is it works for one set of nodes and edges but doesn't work for the other.
The data (nodes and edges) can vary so is there a way I can provide a generic settings?
As in the given example the graph keeps on moving in a circle and takes forever to stabilize. Can anyone please help me fix this issue?
Example: https://jsfiddle.net/aqarain92/eL1qt58r/16/
I am using the following options
const options = {
nodes: {
shape: "dot",
scaling: {
min: 3,
max: 70
}
},
edges: {
arrows: { to: { enabled: false } },
width: 1,
color: {
color: 'gray',
highlight: 'black'
},
smooth: { type: "continuous", roundness: 0 }
},
groups: {
authentic: { color: 'blue' },
inauthentic: { color: 'purple' },
parent: { color: 'black' }
},
layout: { improvedLayout: false },
physics: {
forceAtlas2Based: {
gravitationalConstant: -26,
centralGravity: 0.005,
springLength: 100,
springConstant: 0.04
},
maxVelocity: 146,
solver: "forceAtlas2Based",
timestep: 0.35,
stabilization: { iterations: 200 }
},
interaction: {
tooltipDelay: 200,
hideEdgesOnDrag: true,
hideEdgesOnZoom: true
}
};
The same options work for different set of nodes and edges.
If it's not too late, here is the stabilized version of your network:
https://jsfiddle.net/8nowe7c4/
I changed your options a little bit:
const options = {
nodes: {
shape: "dot",
scaling: {
min: 3,
max: 70
}
},
edges: {
arrows: { to: { enabled: false } },
width: 1,
color: {
color: 'gray',
highlight: 'black'
},
smooth: { type: "continuous", roundness: 0 }
},
groups: {
authentic: { color: 'blue' },
inauthentic: { color: 'purple' },
parent: { color: 'black' }
},
layout: { improvedLayout: false },
physics: {
forceAtlas2Based: {
gravitationalConstant: -126,
springLength: 200,
springConstant: 0.01
},
maxVelocity: 50,
solver: "forceAtlas2Based",
timestep: 0.35,
stabilization: true
},
interaction: {
tooltipDelay: 200,
hideEdgesOnDrag: true,
hideEdgesOnZoom: true
}
};
You may tune the parameters for your needs.
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' });
}
}
I am very new to data visulizations.
Currently we are having a requirement to draw a chart similar to below using HighChart.js
See jsfiddle: http://jsfiddle.net/rgpz2ru5/22/ for what I tried so far.
I am successfully able to draw chart but facing issue while drawing lines between the datalabel and point (just shown in above image)?
Can you please help?
See below code to draw a chart:
$('#container').highcharts({
chart: {
type: 'scatter',
},
xAxis: {
visible: false
},
yAxis: {
title: {
text: ''
},
labels: {
formatter: function() {
return null
}
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
inside: false,
formatter: function(){
console.log("X"+this.x)
console.log("this.x%2"+this.x%2)
if(this.x%2 == 0){
console.log("in if")
return "<div style='position: relative;height:70px; border-left:solid thin #ff0000;margin-left:10px'><span style='position: absolute;bottom: 0;right: 0;'>hello</span></div>";
}else{
console.log("in else")
return "<span style='color:black'>"+this.key+"</span><div style='height:70px; border-left:solid thin #ff0000;margin-left:10px'/>";
}
},
useHTML:true
}
},scatter: {
marker: {
radius: 5,
states: {
hover: {
enabled: false,
lineColor: "#ffb74d"
}
}
},
states: {
hover: {
marker: {
enabled: false
}
}
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '{point.x} cm, {point.y} kg'
}
}
},
series: [{
data: [{
x: 1,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 3
},
name: 'SDS',
color: "#ffb74d"
}, {
x: 2,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 5
},
name: 'MIP',
color:"#ffe0b2"
}, {
x: 3,
y: 1,
dataLabels: {
y: -80,
distance : 50,
softConnector : false,
connectorColor : '#D0D0D0',
},
marker: {
radius: 7
},
name: 'MDP',
color:"#ff9800"
},{
x: 4,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 9
},
name: 'RAD',
color:"#ffb74d"
},{
x: 5,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 3
},
name: 'SDS',
color: "#ffb74d"
}, {
x: 6,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 5
},
name: 'MIP',
color:"#ffe0b2"
}, {
x: 7,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 7
},
name: 'MDP',
color:"#ff9800"
},{
x: 8,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 9
},
name: 'RAD',
color:"#ffb74d"
},{
x: 9,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 3
},
name: 'SDS',
color: "#ffb74d"
}, {
x: 10,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 5
},
name: 'MIP',
color:"#ffe0b2"
}, {
x: 11,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 7
},
name: 'MDP',
color:"#ff9800"
},{
x: 12,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 9
},
name: 'RAD',
color:"#ffb74d"
}]
}]
});
Can you please help?
Your chart seems to be of a specific kind. I personally have not seen any such visualizations before. Also, having worked with HighCharts, I doubt if any type of highchart can be transformed as yours.
However, on the first look on your figure the following idea appeared in my mind with angular framework.
You can achieve this kind of visualization using basic html and css.
Assuming you are aware with Angular terminology. I suggest having a list of all your values. Loop them in a simple div as follows:
<div ng-repeat = "c in pointsList" > </div>
Next you can use ng-style or ng-class to add dynamic css to your each div.
Seeing your figure, I assume you only following css properties:
1. border-radius
2. background-color
3. width
4. height
Seems like you have fixed categories for each type of bubbles. So you can make few fixed classes in your css and apply them dynamically on the basis of your type of point. Basically, it would look like:
<div ng-repeat = "c in pointsList" ng-class = "{'css1' : c.type1, 'css2' : c.type2}" > </div>
Along with this you will need to apply display: inline-block to bring all divs in a line.
I know, its too naive solution, but if you have limited requirements of such chart, this can help you achieve it with minimal adjustments.
To make similar chart you can use bubble chart: http://jsfiddle.net/rgpz2ru5/
Or standard scatter chart: http://jsfiddle.net/rgpz2ru5/1/
You can change marker size of scatter using marker.radius parameter:
marker: {
radius: 5,
states: {
hover: {
lineColor: "#ffb74d"
}
}
},
You can add your labels using chart.renderer.path and chart.renderer.label:
http://api.highcharts.com/highcharts/Renderer.path
http://api.highcharts.com/highcharts/Renderer.label
var drawLabels = function(chart) {
$('.cLabels').remove();
var series = chart.series,
renderer = chart.renderer,
plotTop = chart.plotTop,
plotLeft = chart.plotLeft;
Highcharts.each(series, function(s) {
Highcharts.each(s.data, function(p) {
renderer.path(['M', p.plotX + plotLeft, p.plotY + plotTop, 'L', p.plotX + plotLeft, p.plotY + plotTop - 30]).attr({
stroke: 'black',
'stroke-width': 1
}).addClass('cLabels').add();
renderer.label(p.name, p.plotX + plotLeft, p.plotY + plotTop - 50).attr({
'text-anchor': 'middle',
padding: 0
}).addClass('cLabels').add();
});
});
}
Here you can see an example how it can work: http://jsfiddle.net/rgpz2ru5/29/
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).