Can ports be changed from circle to rectangle? - javascript

I am working with JointJS ports. By default ports are displayed as circles:
https://resources.jointjs.com/tutorial/ports
Is there any way to format the style from circle to rectangle? Please suggest any class names where I can override this.

the tutorial there is using the devs.Model shapes and it's a bit outdated approach...
There is a markup option in the port configuration, see more at https://resources.jointjs.com/docs/jointjs/v2.1/joint.html#dia.Element.ports
I'd recommend a port demo (https://github.com/clientIO/joint/tree/master/demo/ports). There is even a shape you're might be looking for:
var g6 = new joint.shapes.basic.Circle({
position: { x: 50, y: 50 },
size: { width: 500, height: 300 },
attrs: {
text: { text: 'compensateRotation: true', fill: '#6a6c8a' },
circle: { stroke: '#31d0c6', 'stroke-width': 2 }
},
ports: {
groups: {
'a': {
position: {
name: 'ellipseSpread',
args: { startAngle: 0, dr: 0, compensateRotation: true }
},
label: {
position: 'radial'
},
attrs: {
rect: {
stroke: '#31d0c6',
'stroke-width': 2,
width: 20,
height: 20,
x: -10,
y: -10
},
'.dot': {
fill: '#fe854f',
r: 2
},
text: {
fill: '#6a6c8a'
}
},
markup: '<g><rect/><circle class="dot"/></g>'
}
}
}
});

Related

JointJS ports are non-functional

Here is a JSFiddle showing the issue: https://jsfiddle.net/Bronzdragon/xpvt214o/399003/
graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: document.getElementById('myholder'),
model: graph,
width: 800,
height: 600,
});
var rect = new joint.shapes.basic.Rect({
attrs: {rect: {fill: 'lightblue'}},
size: { width: 200, height: 100 },
ports: {
groups: {
'inputs': {
position: { name: 'left' },
attrs: {circle: {fill: 'lightgreen'}},
magnet: 'passive'
},
'outputs': {
position: { name: 'right' },
attrs: {circle: {fill: 'pink'}},
magnet: true,
}
},
items:[ { group: 'inputs' }, { group: 'outputs' } ]
}
});
rect.position(100, 50);
rect.addTo(graph);
var rect2 = rect.clone();
rect2.position(400, 100);
rect2.addTo(graph);
I'm defining an JointJS element (called rect), with two ports on it, and adding them to the graph. The elements themselves are functional, but the ports aren't. When dragging off of an active magnet (the pink circle), it should create a link. Instead it moves the element.
I've followed the JointJS guide in creating a shape, and adding ports. These ports I've added seem to be completely inactive though. I do not know what I'm doing wrong.
I have emailed the JointJS team, and they came back to me with the following (Thank you very much, Roman!):
Thank you for reaching out to us! You were nearly there. The magnet attribute meant to be set on a specific shape DOM element. Similar to fill, refX, xlinkHref etc.
var rect = new joint.shapes.basic.Rect({
attrs: {rect: {fill: 'lightblue' }, root: { magnet: false }},
size: { width: 200, height: 100 },
ports: {
groups: {
'inputs': {
position: { name: 'left' },
attrs: {circle: {fill: 'green', magnet: 'passive' }},
},
'outputs': {
position: { name: 'right' },
attrs: {circle: {fill: 'red', magnet: true }},
}
},
items:[ { group: 'inputs' }, { group: 'outputs' } ]
}
});
Also, If you are new to JointJS I recommend you to read our online tutorials (https://resources.jointjs.com/tutorial). I suggest using standard shapes over basic, as the standard shapes are newer and reflecting the best JointJS techniques.

awe.js Augmented Reality adding text

I'm trying to add text to awe.js project, using this tutorial I have came up with an attempt, https://www.sitepoint.com/augmented-reality-in-the-browser-with-awe-js/.
awe.projections.add({
id: 'text',
geometry: {shape: 'text', text: 'Hello World', font: 'times new roman', weight: 'normal', style: 'normal'},
rotation: {y: 45},
position: {x: -5, y: -31, z: -5},
material: {
type: 'phong',
color: 0xFF0000
}
}, {poi_id: 'marker'});
Then I have done some more research on the subject and tried in different way yet still not succeeded.
awe.pois.add({ id:'fixed_poi', position: { x:70, y:0, z:-250 }, visible: true });
awe.projections.add({
id:'fixed_projection',
geometry: { shape: 'text', text: "My Text", parameters:{font: 'optimer', size: 50}},
position: { x:0, y:0, z:0 },
rotation: { x:0, y:0, z:0 },
material:{ type: 'phong', color: 0xFFFFFF },
}, { poi_id: 'fixed_poi' });
You could create text model separately (an .obj 3D model) for example in 3D builder in Windows 10, and then add that to awe.js in following way:
awe.pois.add({ id:'jsartoolkit_marker_64', position: { x:0, y:0, z:0 }, scale: { x: 1, y: 1, z: 1 } });
awe.projections.add({
id:'marker_projection',
geometry: { path: 'models/obj/example.obj' }, // path to your model
position: { x: 0, y: 0, z: 0 },
rotation: { x: 0, y: 180, z: 0 },
material:{ path: 'models/obj/example.mtl' }, // path to material if you're using one
visible: false,
}, { poi_id: 'jsartoolkit_marker_64' }); // common point of interest, in this case the marker
Hope this helps

Joint.js add custom ports with path class. for custom elements

What I am trying to do is make a element with custom class for ports and path so that I can add an element with custom path and my own markup for ports.This way when I create an element I will pass dynamic path for its shape just like elements of path class behave and as I have also extended from PortsModelInterface I will also have my own markup for ports.
This whole effort is to make svg scalable for zomming. Previously I was using html custom element with my custom ports which was working fine but html of custom elements wasn't scaling on zooming
var graph = new joint.dia.
var paper = new joint.dia.Paper({
el: $('#paper'),
width: 800,
height: 600,
gridSize: 1,
model: graph,
snapLinks: true,
embeddingMode: true
});
joint.shapes.custom1={};
joint.shapes.custom1.Element = joint.shapes.basic.Generic.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {
markup: '<g class="rotatable"><g class="scalable"><rect class = "myrect"/></g><g class="inPorts"/><g class="outPorts"/></g>',
portMarkup: '<g class="port<%= id %>"><circle class="port-body"/></g>',
defaults: joint.util.deepSupplement({
type: 'html.Element',
size: { width: 200, height: 110 },
inPorts: [],
outPorts: [],
attrs: {
'.': { magnet: true},
rect: {
stroke: 'none', 'fill-opacity': 0, width: 300, height: 210,
},
circle: {
r: 6, //circle radius
magnet: true,
left:0,
stroke: 'gray'
},
'.inPorts circle': { fill: 'gray', magnet: 'passive', type: 'input', y: 0},
'.outPorts circle': { fill: 'gray', type: 'output' }
}
}, joint.shapes.basic.Generic.prototype.defaults),
getPortAttrs: function (portName, index, total, selector, type) {
var attrs = {};
var portClass = 'port' + index;
var portSelector = selector + '>.' + portClass;
var portCircleSelector = portSelector + '>circle';
attrs[portCircleSelector] = { port: { id: portName || _.uniqueId(type), type: type } };
attrs[portSelector] = { ref: 'rect', 'ref-x': (index + 1) * (0.55 / total)};
if (selector === '.outPorts') {
attrs[portSelector]['ref-dy'] = 15;
}
return attrs;
}
}));
joint.shapes.custom1.Atomic = joint.shapes.custom1.Element.extend({
markup: '<g class="rotatable"><g class="scalable"><path/></g><text/></g>',
defaults: joint.util.deepSupplement({
type: 'basic.Path',
size: { width: 60, height: 60 },
attrs: {
'path': { fill: '#FFFFFF', stroke: 'black' },
'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-dy': 20, ref: 'path', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
}
}, joint.shapes.basic.Generic.prototype.defaults)
});
var a2 = new joint.shapes.custom1.Atomic({
position: { x: 50, y: 260 },
size: { width: 100, height: 100 },
attrs: {
path: { d: 'M 30 0 L 60 30 30 60 0 30 z' },
text: {
text: 'Diamond',
'ref-y': .5 // basic.Path text is originally positioned under the element
}
},
inPorts: ['in'],
outPorts: ['out']
});
graph.addCells([a2])
The element is added in graph but some how the ports don't show up.
I don't have proper concept of adding classes so please any help will be greatly appreciated. Thanks.
Fiddle example
I suggest to define an element with custom markup for the shape and ports. Both markups should contain an SVG path, so you can set an arbitrary path data d via model.attr() on them.
joint.shapes.devs.GenericModel = joint.shapes.devs.Model.extend({
markup: '<g class="rotatable"><g class="scalable"><path class="body"/></g><text class="label"/><g class="inPorts"/><g class="outPorts"/></g>',
portMarkup: '<g class="port port<%= id %>"><path class="port-body"/><text class="port-label"/></g>',
defaults: joint.util.deepSupplement({
type: 'devs.GenericModel'
}, joint.shapes.devs.Model.prototype.defaults)
});
Tell the paper to use devs.ModelView for rendering.
joint.shapes.devs.GenericModelView = joint.shapes.devs.ModelView;
Now you can set or change d attribute for the shape and ports anytime you wish.
var model = new joint.shapes.devs.GenericModel({
attrs: {
'.body': { d: 'M 0 0 0 50 50 50 z'},
'.port-body': { d: 'M 0 0 10 0 10 10 0 10 z'}
}
});
model.attr('.body/d', 'M 25 0 50 50 0 50 z');
JS Fiddle: http://jsfiddle.net/kumilingus/kge023bc/

How to create a custom shape in JointJs, which consists out of 2 or more basic shapes?

I want to create a shape in Joint JS.
Which I could initialize and lets say have rectangle and circle as one shape.
As far as I know, only path method is something near.
I have just come to an answer. I needed to extend the joint.dia.Element class. Here is how the code looks, which draws a rectangle with two circles(extension):
joint.shapes.basic.myShape = joint.dia.Element.extend({
markup: '<g class="rotatable"><g class="scalable"><rect class="outer"/><circle class="inner"/><circle class="inner1"/></g></g>',
defaults: joint.util.deepSupplement({
type: "basic",
size: {
width: 20,
height: 20
},
attrs: {
".outer": {
stroke: 'black',
'fill-opacity': 1,
width: 10,
height: 15
},
".inner": {
transform: "translate(10, 10)",
r: 8,
fill: "#000000"
},
".inner1": {
transform: "translate(10, 10)",
r: 6,
fill: "#fff"
}
}
}, joint.dia.Element.prototype.defaults)
});
initializing (to stencil, but directly to graph is possible too by using,
graph.addCell):
var r1 = new joint.shapes.basic.myShape({
size: {
width: 60,
height: 60
}
});
stencilData.load([r1], 'basic');

Knockout-kendo radial gauge not drawing correctly when initialized using data-bind

Having issues with the Knockout-Kendo radial gauge in my application.
I'm trying to initialize it via the data-bind property, but it does not appear to be resizing itself correctly.
<div id="speedGauge" data-bind="kendoRadialGauge: $parent.speedGaugeOptions"></div>
...
self.speedGaugeOptions = {
renderAs: 'svg',
value: 0,
gaugeArea: {
background: 'transparent'
},
pointer: {
color: 'lightgray',
animation: {
speed: 100
}
},
scale: {
minorUnit: 75,
majorUnit: 150,
startAngle: -40,
endAngle: 220,
max: 300,
min: -300,
labels: {
position: 'inside',
font: '10px Arial,Helvetica,sans-serif'
},
ranges: [
{
from: -300,
to: -200,
color: "darkgray"
},
{
from: 300,
to: 200,
color: "darkgray"
}
],
rangeSize: 5,
rangeDistance: -5,
rangePlaceholderColor: '#f2f2f2'
}
Here comes the fun part;
When the page has activated (using durandal), the gauges are drawn like this:
In order for the gauge to scale correctly and fit inside the gray circle, I have to redraw it like this (either from the browser console, or in the .js file):
$("#speedGauge").data("kendoRadialGauge").redraw()
When doing so, my gauge looks the way it's suppose to;
Now, I've tried creating it using the regular Kendo implementation - and that works just fine resulting in the gauge to be drawn correctly like in the image above;
<div id="speedGauge"></div>
...
self.activate = function () {
createGauge();
}
...
function createGauge() {
$("#speedGauge").kendoRadialGauge({
renderAs: 'svg',
value: 0,
gaugeArea: {
background: 'transparent'
},
pointer: {
color: 'lightgray',
animation: {
speed: 100
}
},
scale: {
minorUnit: 75,
majorUnit: 150,
startAngle: -40,
endAngle: 220,
max: 300,
min: -300,
labels: {
position: 'inside',
font: '10px Arial,Helvetica,sans-serif'
},
ranges: [
{
from: -300,
to: -200,
color: "darkgray"
},
{
from: 300,
to: 200,
color: "darkgray"
}
],
rangeSize: 5,
rangeDistance: -5,
rangePlaceholderColor: '#f2f2f2'
}
});
}
Does anyone have an idea of what might be wrong here?
A colleague suggested to do a forced redraw of the gauges on durandals attached event, which solved the problem for now. The actual resizing of the gauge is not visible with this solution.
self.attached = function(element) {
$(element).find("[data-role='radialgauge']").each(function () { $(this).data("kendoRadialGauge").redraw(); });
};
I've reported the issue here.

Categories