Content and Label on a Node - Cytoscape
Asked Answered
A

2

11

I'm trying to display nodes that have a font icon in the center of the node using 'content' and a text label underneath.

My styling is currently:

{
  'selector': 'node[icon]',
  'style': {
    'content': 'data(icon)',
    'font-family': 'Material Icons',
    'text-valign': 'center',
    'text-halign': 'center'
  }
},
{
  'selector': 'node[label]',
  'style': {
    'label': 'data(label)',
    'text-valign': 'bottom',
    'text-halign': 'center'
  }
}

However, this doesn't work as i assume both of the styles is used on one element (the node).

There are a few solutions I've considered, such as:

  • Putting the label on a parent node
  • Use Popper.js or similar to show the label
  • Use a multi-lined label

The first 2 seem 'hacky', and the third could cause a lot of alignment problems. Is there a better solution to this?

Algebra answered 9/1, 2019 at 17:29 Comment(0)
A
5

I've found a solution using the extension: https://github.com/kaluginserg/cytoscape-node-html-label.

You can create custom HTML labels for nodes which do not interfere with the base Cytoscape labels. An example of using the Material Icons:

// Initialise the HTML Label
this.cy.nodeHtmlLabel([{
  query: '.nodeIcon',
  halign: 'center',
  valign: 'center',
  halignBox: 'center',
  valignBox: 'center',
  tpl: (data) => {
    return '<i class="material-icons">' + data.icon + '</i>';
  }
}]);

// Add the HTML Label to the node:
const node =  {
  group: 'nodes',
  data: {
    id: data.id,
    label: data.label,
    icon: data.icon
  },
  classes: 'nodeIcon' // <---- Add the HTML Label class here
};

With the method you can dynamically create nodes with font icons without the need to download a load of images.

Node Icon

You can even add CSS styling to change the colour of the icon:

enter image description here

Algebra answered 14/1, 2019 at 16:58 Comment(0)
A
3

If you want an icon as the nodes body, you can use it as the background image and define the label like you do:

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

  boxSelectionEnabled: false,
  autounselectify: true,

  style: [{
      selector: 'node',
      css: {
        'label': 'data(id)',
        'text-valign': 'bottom',
        'text-halign': 'center',
        'height': '60px',
        'width': '60px',
        'border-color': 'black',
        'border-opacity': '1',
        'background-image': 'https://farm8.staticflickr.com/7272/7633179468_3e19e45a0c_b.jpg',
        "text-background-opacity": 1,
        "text-background-color": "lightgray"
      }
    },
    {
      selector: ':selected',
      css: {
        'background-color': 'black',
        'line-color': 'black',
        'target-arrow-color': 'black',
        'source-arrow-color': 'black'
      }
    }
  ],

  elements: {
    nodes: [{
        data: {
          id: 'n0'
        }
      },
      {
        data: {
          id: 'n1'
        }
      },
      {
        data: {
          id: 'n2'
        }
      },
      {
        data: {
          id: 'n3'
        }
      },
      {
        data: {
          id: 'n4'
        }
      },
      {
        data: {
          id: 'n5'
        }
      },
      {
        data: {
          id: 'n6'
        }
      },
      {
        data: {
          id: 'n7'
        }
      },
      {
        data: {
          id: 'n8'
        }
      },
      {
        data: {
          id: 'n9'
        }
      },
      {
        data: {
          id: 'n10'
        }
      },
      {
        data: {
          id: 'n11'
        }
      },
      {
        data: {
          id: 'n12'
        }
      },
      {
        data: {
          id: 'n13'
        }
      },
      {
        data: {
          id: 'n14'
        }
      },
      {
        data: {
          id: 'n15'
        }
      },
      {
        data: {
          id: 'n16'
        }
      }
    ],
    edges: [{
        data: {
          source: 'n0',
          target: 'n1'
        }
      },
      {
        data: {
          source: 'n1',
          target: 'n2'
        }
      },
      {
        data: {
          source: 'n1',
          target: 'n3'
        }
      },
      {
        data: {
          source: 'n2',
          target: 'n7'
        }
      },
      {
        data: {
          source: 'n2',
          target: 'n11'
        }
      },
      {
        data: {
          source: 'n2',
          target: 'n16'
        }
      },
      {
        data: {
          source: 'n3',
          target: 'n4'
        }
      },
      {
        data: {
          source: 'n3',
          target: 'n16'
        }
      },
      {
        data: {
          source: 'n4',
          target: 'n5'
        }
      },
      {
        data: {
          source: 'n4',
          target: 'n6'
        }
      },
      {
        data: {
          source: 'n6',
          target: 'n8'
        }
      },
      {
        data: {
          source: 'n8',
          target: 'n9'
        }
      },
      {
        data: {
          source: 'n8',
          target: 'n10'
        }
      },
      {
        data: {
          source: 'n11',
          target: 'n12'
        }
      },
      {
        data: {
          source: 'n12',
          target: 'n13'
        }
      },
      {
        data: {
          source: 'n13',
          target: 'n14'
        }
      },
      {
        data: {
          source: 'n13',
          target: 'n15'
        }
      },
    ]
  },

  layout: {
    name: 'dagre',
    padding: 5
  }
});
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/[email protected]/dist/jquery.js"></script>
  <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>
Aesculapius answered 9/1, 2019 at 18:50 Comment(4)
Problem here is I would like to use Font Icons to prevent the need to download a bunch of icon images.Algebra
You can download them and crate an image folder and just use them as pictures, so you don‘t have to download them whilst loading the page?Aesculapius
Other reason such as being able to customise the text-background-color styling and using font icon allows for more dynamic code. Background image is a workaround i agree, but not a solution unfortunately.Algebra
What do you mean by customising the text-background-color? The label's bg-color?Aesculapius

© 2022 - 2024 — McMap. All rights reserved.