skip to Main Content

In cytoscape.js, I want to position a label at the top left corner of a parent node, with the text starting at the anchor point (i.e. left aligned with the text appearing to run across the top of the parent node).

I have set values for the text-halign, text-valign and text-justification:

'text-halign': 'left',
'text-justification': 'left',
'text-valign': 'top',

However, the text does not always appear. In this jsfiddle the label does not initially appear – you only get a portion of the ‘p’:

Parent node with label cut off

However, if you zoom in on the top left corner of the parent node (using the mousewheel), the label does eventually appear in the correct place:

parent label after zooming in

I’ve also noticed that if I set the text-background properties for the parent node, these get drawn right aligned and not under the actual label:

label background offset

I’ve seen the same problem with child nodes too (though that is not shown in this example).

I have tried with various combinations of the text- properties. Although the label appears fully when zoomed in, it is always cut off at lower zoom levels.

Is there a way of getting the text to appear at the top left of the parent node and displayed in full without having to zoom in?

2

Answers


  1. I am new to this library, so please excuse me if this didnt solve your issue.
    After making some changes and looking into the documentation, I found that 'text-wrap':'wrap' adding this property in the style will solve your issue.

    Please take a look at the code snippet

    var cy = window.cy = cytoscape({
      container: document.getElementById('cy'),
    
      boxSelectionEnabled: false,
    
      style: [
        {
          selector: 'node',
          style: {
            'background-color': 'gray',
            label: 'data(id)',
            'text-margin-y': 1,
            width: 50,
            height: 50
          }
        },
        {
          selector: 'node:parent',
          style: {
            'border-opacity': 0,
            'background-color': 'lightgray',
            'text-halign': 'left',
            'text-valign': 'top',
            'text-margin-x': 45,
            'text-justification': 'left',
            'text-wrap':'wrap'
          }
        }
        ],
    
      elements: {
        nodes: [
          { data: { id: 'parent' } },
          { data: { id: 'child1', parent: 'parent' }, position: { x: 300, y: 85 }},
          { data: { id: 'child2', parent: 'parent' }, position: { x: 400, y: 85 }},
          { data: { id: 'node' }, position: { x: 500, y: 85 }},
        ],
        edges: []
      },
    
      layout: {
        name: 'preset',
        padding: 5
      }
    });
    #cy {
      height: 100%;
      width: 100%;
      position: absolute;
      left: 0;
      top: 0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.23.0/cytoscape.min.js"></script>
    <body>
    <div id="cy"></div>
    </body>
    Login or Signup to reply.
  2. Using a specific private field you can easily get the node label width. I would always prefer to use a normal API method as it is normally not really intended to use these fields. As there is no method to get this data right now, this will get you the width:

    'text-margin-x': (ele) => ele._private.rscratch.labelWidth
    

    This may result in some errors, so I added a case where the labelWidth is null:

    var cy = window.cy = cytoscape({
      container: document.getElementById('cy'),
    
      boxSelectionEnabled: false,
    
      style: [{
          selector: 'node',
          style: {
            'background-color': 'gray',
            label: 'data(id)',
            width: 50,
            height: 50
          }
        },
        {
          selector: 'node:parent',
          style: {
            'border-opacity': 0,
            'background-color': 'lightgray',
            'text-halign': 'left',
            'text-valign': 'top',
            'text-margin-x': (ele) => ele._private.rscratch.labelWidth ? ele._private.rscratch.labelWidth : 0
          }
        }
      ],
    
      elements: {
        nodes: [{
            data: {
              id: 'parent'
            }
          },
          {
            data: {
              id: 'child1',
              parent: 'parent'
            },
            position: {
              x: 300,
              y: 85
            }
          },
          {
            data: {
              id: 'child2',
              parent: 'parent'
            },
            position: {
              x: 400,
              y: 85
            }
          },
          {
            data: {
              id: 'node'
            },
            position: {
              x: 500,
              y: 85
            }
          },
        ],
        edges: []
      },
    
      layout: {
        name: 'preset',
        padding: 5
      }
    });
    #cy {
      height: 100%;
      width: 100%;
      position: absolute;
      left: 0;
      top: 0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.23.0/cytoscape.min.js"></script>
    
    <body>
      <div id="cy"></div>
    </body>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search