Reputation: 260
I want to highlight outgoing edges after clicking on node. Now, I have such code:
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(id)',
'background-color': '#4286f4'
})
.selector('edge.highlighted')
.css({
'line-color': 'black',
'target-arrow-color': '#b830f7'
})
.selector('edge')
.css({
'curve-style': 'bezier',
'target-arrow-shape': 'triangle',
'width': 4,
'line-color': '#4286f4',
'target-arrow-color': '#4286f4'
}),
//else parameters
});
cy.on('click', function(e){
var edges = cy.edges();
edges.removeClass('highlighted');
});
cy.on('click', 'node', function(e){
var id = e.target.id();
var outgoing = cy.edges("[source='" + id + "']")
outgoing.addClass('highlighted');
});
And when line-color isn't set by 'edge' selector it works fine, but if I set some color to edges - new color doesn't apply after clicking on node.
Upvotes: 3
Views: 3467
Reputation: 1387
You can highlight the selected node and all outgoing edges and connecting nodes to selected node by doing this
cy.on('tap', 'node', function(evt) {
const target: any = evt.target;
const node = target[0]._private.data;
console.log( 'tapped ' , node.name);
cy.elements().difference(target.outgoers()).not(target).addClass('semitransp');
target.addClass('highlight').outgoers().addClass('highlight');
});
You can deselect all nodes and edges by clicking on the cy (outside the graph) by doing the below
cy.on('click',function(evt){
//select either edges or nodes to remove the styles
//var edges = cy.edges();
//var nodes = cy.nodes()
// edges.removeClass('semitransp');
// nodes.removeClass('semitransp');
//you can select all elements and remove the styles
cy.elements().removeClass('semitransp');
})
The style/css details for your reference
{
selector: 'node.highlight',
style: {
'border-color': '#FFF',
'border-width': '2px'
}
},
{
selector: 'node.semitransp',
style: { 'opacity': '0.5' }
},
{
selector: 'edge.highlight',
style: { 'mid-target-arrow-color': '#FFF' }
},
{
selector: 'edge.semitransp',
style: { 'opacity': '0.2' }
}
Upvotes: 0
Reputation: 6074
I added something crucial to my code at work that solved the problem for me:
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(id)',
'background-color': '#4286f4'
})
.selector('edge.highlighted')
.css({
'line-color': 'black',
'target-arrow-color': '#b830f7'
})
.selector('edge')
.css({
'curve-style': 'bezier',
'target-arrow-shape': 'triangle',
'width': 4,
'line-color': '#4286f4',
'target-arrow-color': '#4286f4'
}),
});
cy.unbind('click');
cy.bind('click', function(e){
if (e.target === cy || e.target.group() == "edges") {
cy.edges().removeClass('highlighted');
}
else {
cy.edges("[source='" + e.target.id() + "']").addClass('highlighted');
}
});
cy.on() is a synonym for the bind operation, so this can cause a lot of errors, even if your problem still exists, you have to unbind previous binds, otherwhise the code is executed twice or more.
Here is the whole init of cytoscape:
// Initialize cytoscape
cy = window.cy = cytoscape({
container: $('.cy'),
boxSelectionEnabled: false,
autounselectify: true,
layout: {
name: 'grid'
},
style: [
{
selector: 'node',
style: {
'shape': 'data(faveShape)',
'content': 'data(DisplayName)',
'height': 'data(faveHeight)',
'width': 'data(faveWidth)',
'background-color': 'data(faveColor)',
'line-color': '#a8eae5',
'font-family': 'Segoe UI,Helvetica Neue,Helvetica,Arial,Verdana',
'font-size': '15px',
}
},
{
selector: 'edge',
style: {
'label': 'data(myLabel)',
'curve-style': 'bezier',
'width': 5,
'opacity': 0.5,
'line-color': '#a8eae5',
'font-size': '12px',
'target-arrow-shape': 'triangle',
'target-arrow-color': '#a8eae5'
}
},
{
selector: '.autorotate',
style: {
'edge-text-rotation': 'autorotate'
}
},
{
selector: ".center-center",
style: {
"text-valign": "center",
"text-halign": "center"
}
},
{
selector: 'edge.highlighted',
style: {
'line-color': '#2a6cd6',
'target-arrow-color': '#2a6cd6',
'opacity': 0.7,
}
},
{
selector: 'edge.deactivate',
style: {
'opacity': 0.1,
}
},
{
selector: 'node.deactivated',
style: {
'opacity': 0.1,
}
}
],
});
// After some other functions where I select the nodes I want to display I
// empty the graph and then:
cy.add(jsonNew);
layout = cy.elements().layout({
name: 'concentric'
}).run();
cy.fit(cy.elements());
cy.center();;
cy.unbind('click');
cy.unbind('tapstart');
cy.unbind('tapend');
cy.bind('click ', 'node', function (evt) {
onTap(evt);
});
cy.bind('tapstart ', 'node', function (evt) {
cy.edges("[source = '" + evt.target.id()+"']").addClass('highlighted');
cy.edges("[source !='" + evt.target.id()+"']").addClass('deactivate');
// Here is a complicated algorithm to get all nodes not connected to the
// node which is currently held, I get all these nodes and then make
// them almost invisible. When the node is released I set remove the
// node.deactivated class from all nodes
});
cy.bind('tapend ', 'node', function (evt) {
cy.edges("[source ='"+evt.target.id()+"']").removeClass('highlighted');
cy.edges("[source !='"+evt.target.id()+"']").removeClass('deactivate');
});
Upvotes: 0
Reputation: 260
It is possible to add special selector for line-color:
.selector('edge.lines')
.css({
'line-color': '#4286f4',
'target-arrow-color': '#4286f4'
})
And then use cy.edges().classes('highlighted') to replace edges' class with highlighted class, or use cy.edges().classes('lines') to set class to 'lines'
Upvotes: 0
Reputation: 6074
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(id)',
'background-color': '#4286f4'
})
.selector('edge.highlighted')
.css({
'line-color': 'black',
'target-arrow-color': '#b830f7'
})
.selector('edge')
.css({
'curve-style': 'bezier',
'target-arrow-shape': 'triangle',
'width': 4,
'line-color': '#4286f4',
'target-arrow-color': '#4286f4'
}),
});
cy.on('click', function(e){
if (e.target === cy || e.target.group() == "edges") {
cy.edges().removeClass('highlighted');
}
else {
cy.edges("[source='" + e.target.id() + "']").addClass('highlighted');
}
});
I think this should work fine, you calles two click methods at the same time, that may have caused some problems, please let me know if this fixed it or not :) .
If you want to have two seperate click events, you can write this:
cy.on('click', function(e){
if (e.target === cy || e.target.group() == "edges") {
cy.edges().removeClass('highlighted');
});
cy.on('click', 'node', function(e){
cy.edges("[source='" + e.target.id() + "']").addClass('highlighted');
});
Upvotes: 2