Cytoscape.js, position label text on top of edge - cytoscape.js

I have a label which is painted inline with edge and by this is not rendered well.
Is there a way to add something like background shape to the edge text, so that edge line is not visible at the label area?

You can add classes to labels when initializing the cytoscape stylesheet:
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
boxSelectionEnabled: false,
autounselectify: true,
style: [{
selector: "node",
css: {
"label": "data(label)",
"text-valign": "center",
"text-halign": "center",
"height": "60px",
"width": "60px"
}
},
{
selector: "edge",
css: {
"target-arrow-shape": "triangle"
}
},
{
selector: "edge[label]",
css: {
"label": "data(label)",
"text-rotation": "autorotate",
"text-margin-x": "0px",
"text-margin-y": "0px"
}
},
{
selector: ".background",
css: {
"text-background-opacity": 1,
"color": "#fff",
"text-background-color": "#000"
}
},
{
selector: ".outline",
css: {
"color": "#fff",
"text-outline-color": "#000",
"text-outline-width": 3
}
},
{
selector: ".top-center",
style: {
"text-valign": "top",
"text-halign": "center"
}
}
],
elements: {
nodes: [{
data: {
id: '1',
label: 'outline'
},
classes: 'outline'
},
{
data: {
id: '2',
label: 'background'
},
classes: 'background'
},
{
data: {
id: '3',
label: 'top-center'
},
classes: 'top-center'
},
{
data: {
id: '4',
label: 'none'
}
}
],
edges: [{
data: {
source: "1",
target: "2",
label: "outline"
},
classes: "outline"
},
{
data: {
source: "2",
target: "3",
label: "background"
},
classes: "background"
},
{
data: {
source: "3",
target: "4",
label: "top-center"
},
classes: "top-center"
},
{
data: {
source: "4",
target: "1",
label: "none"
}
}
]
},
layout: {
name: "circle"
}
}));
cy.ready(function() {
cy.layout({
name: "circle"
}).run();
});
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 75%;
position: absolute;
left: 0;
top: 0;
float: left;
}
<html>
<head>
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.2.17/cytoscape.min.js"></script>
<script src="https://unpkg.com/jquery#3.3.1/dist/jquery.js"></script>
</head>
<body>
<div id="cy"></div>
</body>
</html>

Related

How to make a treeview recursive menu in Vue.js but every branch is filled by an API request via Axios?

I need to make a treeview recursive menu in vue.js and i want every branch to be filled with a spefic array collected by an API call with Axios. I found already on the web some examples of this specific menu but i didnt manage put in the data the response from the axios call.
Here there is an example of the aformentioned menu
Menu.vue component
<template>
<div class="menu" :class="{ 'small-menu': smallMenu }">
<MenuItem
v-for="(item, index) in menuTree"
:key="index"
:data="item.children"
:label="item.label"
:icon="item.icon"
:depth="0"
:smallMenu="smallMenu"
/>
<i #click="smallMenu = !smallMenu" class="material-icons">menu</i>
</div>
</template>
<script>
import MenuItem from './MenuItem.vue';
export default {
name: 'recursive-menu',
data: () => ({
smallMenu: false,
menuTree: [
{
label: "Home",
icon: "home",
children: [
{
label: "level 1.1",
children: [
{
label: "level 1.1.1",
children: [
{
label: "level 1.1.1.1"
}
]
}
]
},
{
label: "level 1.2"
}
]
},
{
label: "Dashboard",
icon: "dashboard",
children: [
{
label: "level 2.1",
},
{
label: "level 2.2"
},
{
label: "level 2.3"
}
]
},
{
label: "Settings",
icon: "settings"
}
]
}),
components: {
MenuItem
}
}
</script>
<style lang="scss" scoped>
.menu {
position: fixed;
height: 100vh;
width: 240px;
left: 0;
top: 0;
border-right: 1px solid #ececec;
transition: all .3s ease;
overflow: auto;
i {
position: fixed;
left: 250px;
font-size: 20px;
top: 15px;
user-select: none;
cursor: pointer;
transition: all .3s ease;
}
&.small-menu {
overflow: inherit;
width: 60px;
padding-top: 50px;
i {
left: 20px;
}
}
}
</style>
Here is the response from the API
{
"success": 1,
"numElements": 6,
"data": [
{
"id": "1",
"categoryName": "Fatturato",
"fkParent": null,
"hasChild": "1"
},
{
"id": "2",
"categoryName": "Fatturato Clienti",
"fkParent": "1",
"hasChild": "0"
},
{
"id": "3",
"categoryName": "Fatturato Fornitori",
"fkParent": "1",
"hasChild": "0"
},
{
"id": "4",
"categoryName": "Scaduto",
"fkParent": null,
"hasChild": "1"
},
{
"id": "5",
"categoryName": "Scaduto Clienti",
"fkParent": "4",
"hasChild": "0"
},
{
"id": "6",
"categoryName": "Scaduto Fornitori",
"fkParent": "4",
"hasChild": "0"
}
]
}

How to avoid edges overlap in multigraph when using taxi edges?

let styleJson = JSON.parse(`
[{
"selector": "node",
"style": {
"label": "data(id)",
"height": "data(height)",
"width": "data(width)",
"text-valign": "center",
"text-halign": "center"
}
}, {
"selector": "node.begin-end",
"style": {
"shape": "ellipse",
"width": "70",
"height": "30"
}
}, {
"selector": "node.if",
"style": {
"shape": "diamond"
}
}, {
"selector": "edge",
"style": {
"width": 2,
"label": "data(id)",
"curve-style": "taxi"
}
}, {
"selector": "edge.true",
"style": {
"taxi-direction": "rightward"
}
}, {
"selector": "edge.false",
"style": {
"taxi-direction": "leftward"
}
}]
`);
let cy = cytoscape({
container: document.getElementById('cy'),
style: styleJson,
elements: {
nodes: [{
data: {
id: 'begin'
},
classes: 'begin-end'
},
{
data: {
id: 'if',
width: "70",
height: "30"
},
classes: 'if'
},
{
data: {
id: 'end',
width: "70",
height: "30"
},
classes: 'begin-end'
}
],
edges: [{
data: {
id: 'n1',
source: 'begin',
target: 'if'
}
},
{
data: {
id: 'n2',
source: 'if',
target: 'end'
},
classes: 'true'
},
{
data: {
id: 'n3',
source: 'if',
target: 'end'
},
classes: 'false'
}
]
}
});
doLayout();
function doLayout() {
let layoutOpts = {
name: 'breadthfirst',
directed: true
};
cy.layout(layoutOpts).run();
}
#cy {
width: 400px;
height: 400px;
display: block;
border: 1px solid black;
margin: 0 auto;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cytoscape</title>
</head>
<body>
<div id="cy"></div>
<script src="https://cdn.jsdelivr.net/npm/cytoscape#3.17.1/dist/cytoscape.min.js"></script>
</body>
</html>
I just want to split the 2 edges coming from IF node.
The direction is specified (leftward/rightward), but I don't know how to make it working...

Put nodes on the border of the parent in cytoscape

I want to put the child nodes on the very border of the parent node (evenly distributed if possible) instead of inside the parent node.
Can this be achieved? Assuming that I could somehow get the position and size of the parent and set the position of the children based on this?
Still I would like the edges to be as short as possible, and as I add more nodes and edges it will be a mess to try to set coordinates myself
So it would be best if the layout algorithm did the job of distributing the nodes, just want them moved out on the border.
<style>
body {
font-family: helvetica;
font-size: 14px;
}
#cy {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 999;
}
h1 {
opacity: 0.5;
font-size: 1em;
}
</style>
<script>
$(function(){
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
layout: {
name: 'cose-bilkent'
},
style: [
{
selector: 'node',
style: {
shape: 'roundrectangle',
width: 10,
height: 10,
'background-color': '#ad1a66',
label: function (ele) { return (ele.data('id')) }
}
},
{
selector: ':parent',
style: {
width: 80,
height: 120,
'background-opacity': 0.333
}
},
{
selector: 'edge',
style: {
'width': 3,
'line-color': '#ad1a66'
}
}
],
elements: [
{ "data": { "id": "n2" }},
{ "data": { "id": "p6", "parent": "n2" }},
{ "data": { "id": "p1", "parent": "n2" }},
{ "data": { "id": "p4", "parent": "n2" }},
{ "data": { "id": "p7", "parent": "n2" }},
{ "data": { "id": "n3" }},
{ "data": { "id": "p2", "parent": "n3" }},
{ "data": { "id": "p5", "parent": "n3" }},
{ "data": { "id": "p8", "parent": "n3" }},
{ "data": { "id": "e46", "source": "p7", "target": "p2" }, "position": {}},
]
});
});
</script>
A compound parent node does not have an independent position or size. It just fits to its children.
So, you can put a child node at the parent's edge -- but not beyond it -- by positioning the child relative to its siblings. Make sure to set the padding to zero on the parent.
Force-directed layouts will try to minimise the area taken up by each parent node, as this is a highly desirable property. This means that for groups of three or more siblings a layout will tend to put nodes in the middle.
Your criterion is at odds with the general goal of compound force-directed layout, so you could try setting the repulsion forces really high or you could write an extension with your own custom logic.

Sencha Touch: avoiding blank line while combining Carousel and Toolbar

I'm having an issue while scrolling between items in the vertical carousel:
The blank division has the same height as the toolbar. Is there any way to avoid the blank line? This is my current code:
Ext.define('eltirabuzon.view.Main', {
extend: 'Ext.Container',
xtype: 'main',
requires: [
'Ext.TitleBar',
'Ext.Video',
'Ext.carousel.Carousel'
],
config: {
cls: 'cards',
layout: {
type: 'vbox',
align: 'stretch'
},
defaults: {
flex: 1
}
}
});
Ext.create('Ext.Carousel',{
fullscreen: true,
height: '100%',
direction: 'vertical',
directionLock: true,
indicator: false,
defaults: {
directionLock: true,
styleHtmlContent: true,
margin: 0,
padding: 0
},
items: [
{
xtype: 'toolbar',
dock: 'top',
ui: 'dark',
title: 'El Tirabuzon',
items: [{
xtype: 'button',
text: '',
docked: 'left',
ui: 'action',
cls: 'button-options'
}]
},
{
html: 'rtutorial',
style: {
'color': '#FFF',
'background-color': '#BBB',
'background-image': 'url(http://gastonbercun.com/wp-content/uploads/2011/08/steve-jobsNews.jpg)',
'background-size': 'cover'
}
},
{
html: 'noticia',
style: {
'color': '#FFF',
'background-color': '#BBB',
'background-image': 'url(http://blog.ciencianueva.com/wp-content/uploads/2011/10/steve-jobs-renuncia-a-apple.jpeg)',
'background-size': 'cover'
}
},
{
html: 'lista',
style: {
'color': '#FFF',
'background-color': '#BBB',
'background-image': 'url(http://www.biography.com/imported/images/Biography/Images/Galleries/Steve%20Jobs/steve-jobs-photo-NeXT-intro-07-sized.jpg)',
'background-size': 'cover'
}
},
{
html: 'resena',
style: {
'color': '#FFF',
'background-color': '#CCC',
'background-image': 'url(http://3.bp.blogspot.com/-HRJITwGr_Vk/TlYaxYFxoKI/AAAAAAAAAPI/3ofib-Z1VgI/s1600/ipadjobsjpg-1426c786c4434809.jpg)',
'background-size': 'cover'
}
}
]
});

How can I get these three buttons to centered and evenly spaced within the container?

Just wondering if anyone can let me know how I can get these three buttons to centered and evenly spaced within the container?
Ext.define('rpc.view.home.indexView', {
extend: 'Ext.Panel',
alias: 'widget.homeView',
config: {
items: [{
xtype: 'panel',
layout: {
type: 'vbox',
pack: 'center'
},
defaults: {
xtype: 'button',
margin: '10 10 0 10'
},
items: [{
text: 'Videos',
cls: 'x-button-quicknav'
}, {
text: 'Events',
cls: 'x-button-quicknav'
}, {
text: 'Sites',
cls: 'x-button-quicknav'
}]
}]
},
initialize: function () {
console.log('rpc.view.home.index ~ initialize');
}
});
Nailed it
JS
xtype: 'container',
layout: {
type: 'hbox',
pack: 'center'
},
defaults: {
xtype: 'button',
ui: 'plain',
style: 'margin-top: 5px;'
},
items: [{
text: 'Videos',
cls: 'x-button-rpc',
flex: 1
}, {
xtype: 'container',
cls: 'x-button-rpc-spacer'
}, {
text: 'Events',
cls: 'x-button-rpc',
flex: 1
}, {
xtype: 'container',
cls: 'x-button-rpc-spacer'
}, {
text: 'Sites',
cls: 'x-button-rpc',
flex: 1
}]
CSS
.x-button-rpc{
border-radius: 5px;
border:1px solid #c4c4c4 !important;
background-color: White !important;
}
.x-button-rpc-spacer{
display: inline-block;
width: 5px;
}