How can I change the color an individual node in a grid of Cytoscape.js
Asked Answered
C

1

7

How can I change the color to a node or edge that already exists on a layout (without deleting/adding it)?

I've got a layout of nodes with preselected positions which I want to change the color (nodes and also edges), but not of every node (or edge). I already tried

cy.style('background-color', 'color');

, that allows to change the color but it changes the color of every node.

I only want to change the style of one node.

Thanks a lot

Robert

Canonry answered 24/1, 2019 at 17:11 Comment(1)
Welcome to Stack Overflow! Please read what this site is about and "How to ask" before asking a question. Please provide a minimal reproducible example which shows your problem.Heartstricken
E
12

Explanation:

Hi Robert, you are right, that cy.style() changes the style of the whole graph. What you probably didn't notice is, that you can specify really specifically, which element you want to execute this funtion on.

About cytoscape selectors:

If you want to select every element of a specific type, you can call this:

cy.elements(); // this returns all edges and nodes
cy.nodes(); // this returns all nodes
cy.edges(); // this returns all edges

If you want to get a specific group of elements or one in particular, you can perform a query like this:

cy.elements/nodes/edges('[selector =/!= "property"]');   // selector can be id and the property the actual id

Solution:

To get to the solution, here is what you can do:

cy.nodes('[id = "yourId"]').style('background-color', 'desiredColor');

Or binding it to an event, idk what your use-case is:

cy.unbind('click);  // always unbind before binding an event to prevent binding it twiche/multiple times
cy.bind('click', 'node, edge', function(event) {
    let target = event.target;
  if (target.isEdge()) {
    target.style('line-color', 'green');
  } else {
    target.style({
      'background-color': 'white',
      'border-color': 'blue'
    });
  }
});

Code example:

Here is a working example of this method:

var cy = (window.cy = cytoscape({
  container: document.getElementById("cy"),

  boxSelectionEnabled: false,
  autounselectify: true,

  style: [{
      selector: "node",
      css: {
        content: "data(id)",
        "text-valign": "center",
        "text-halign": "center",
        height: "60px",
        width: "60px",
        "border-color": "black",
        "background-color": "gray",
        "border-opacity": "1",
        "border-width": "10px"
      }
    },
    {
      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: ":selected",
      css: {
        "background-color": "black",
        "line-color": "black",
        "target-arrow-color": "black",
        "source-arrow-color": "black"
      }
    }
  ],
  layout: {
    name: "circle"
  }
}));

var info = [{
    name: "Peter",
    next_op_name: "Claire"
  },
  {
    name: "Claire",
    next_op_name: "Mike"
  },
  {
    name: "Mike",
    next_op_name: "Rosa"
  },
  {
    name: "Rosa",
    next_op_name: "Peter"
  }
];

cy.ready(function() {
  var array = [];
  // iterate over info once
  for (var i = 0; i < info.length; i++) {
    array.push({
      group: "nodes",
      data: {
        id: info[i].name, // id is name!!!
        label: info[i].name
      }
    });
    array.push({
      group: "edges",
      data: {
        id: "e" + i,
        source: info[i].name,
        target: info[i].next_op_name,
        label: "e" + i
      }
    });
  }
  cy.add(array);
  cy.layout({
    name: "circle"
  }).run();
});
cy.on("mouseover", "node", function(event) {
  var node = event.target;
  node.qtip({
      content: "hello",
      show: {
        event: event.type,
        ready: true
      },
      hide: {
        event: "mouseout unfocus"
      }
    },
    event
  );
});

cy.unbind('click');
cy.bind('click', 'node, edge', function(event) {
  let target = event.target;
  if (target.isEdge()) {
    target.style('line-color', 'green');
  } else {
    target.style({
      'background-color': 'white',
      'border-color': 'blue'
    });
  }
});
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://unpkg.com/[email protected]/dist/cytoscape.min.js"></script>
  <!-- qtip imports -->
  <script src="https://unpkg.com/[email protected]/dist/jquery.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.min.js"></script>
  <link href="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.min.css" rel="stylesheet" type="text/css" />
  <script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-qtip/2.7.0/cytoscape-qtip.js"></script>

  <!-- dagre imports -->
  <script src="https://unpkg.com/[email protected]/dist/dagre.js"></script>
  <script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-dagre/1.5.0/cytoscape-dagre.js"></script>
</head>

<body>
  <div id="cy"></div>
</body>

</html>
Eudemon answered 24/1, 2019 at 17:46 Comment(1)
It would be a bit better to use a mappers in the stylesheet with ele.data().Poinsettia

© 2022 - 2024 — McMap. All rights reserved.