使用 Cytoscape JS 突出显示边缘不起作用

Highlighting edges with Cytoscape JS doesn't work

我想在单击节点后突出显示出边。现在,我有这样的代码:

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');
});

当 'edge' 选择器未设置线条颜色时,它工作正常,但如果我为边缘设置了一些颜色 - 单击节点后新颜色不适用。

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');
   }
});

我认为这应该可以正常工作,您同时调用了两个点击方法,这可能导致了一些问题,请告诉我这是否解决了问题:)。

如果你想有两个单独的点击事件,你可以这样写:

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');
});

可以为 line-color 添加特殊选择器:

.selector('edge.lines')
    .css({
      'line-color': '#4286f4',
      'target-arrow-color': '#4286f4'
    })

然后使用 cy.edges().classes('highlighted') 将边缘的 class 替换为突出显示的 class,或使用 cy.edges().classes('lines') 将 class 设置为 'lines'

我在工作中为我的代码添加了一些重要的东西,为我解决了这个问题:

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() 是bind操作的同义词,所以这会导致很多错误,即使你的问题仍然存在,你也必须取消绑定以前的绑定,否则代码会执行两次或更多

这是整个 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');
 });

您可以通过执行此操作突出显示所选节点以及所有出边和连接到所选节点的节点

 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');


    });

您可以通过执行以下操作单击 cy(图外)来取消选择所有节点和边

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');      
})

style/css详情供您参考

{
    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' }
}