Multi-line label for node

1,060 views
Skip to first unread message

Valentin

unread,
Nov 24, 2013, 1:32:06 PM11/24/13
to cytoscap...@googlegroups.com
Hello, dear Cytoscape.js developers and users.

I've found a lot of messages on the problem of wrapping text in label for cytoscape core, and all answers pointed to the complexity of line break implementation since canvas does not understand /n or <br/> (or something like that).
I found a link and a code for fixing line width in HTML5 and would like to know, is there a way to use this code in cytoscape.js for label text wrapping?


Code:
function wrapText(context, text, x, y, maxWidth, lineHeight) {
        var words = text.split(' ');
        var line = '';
        for(var n = 0; n < words.length; n++) {
          var testLine = line + words[n] + ' ';
          var metrics = context.measureText(testLine);
          var testWidth = metrics.width;
          if (testWidth > maxWidth && n > 0) {
            context.fillText(line, x, y);
            line = words[n] + ' ';
            y += lineHeight;
          }
          else {
            line = testLine;
          }
        }
        context.fillText(line, x, y);
      }
      
      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
      var maxWidth = 400;
      var lineHeight = 25;
      var x = (canvas.width - maxWidth) / 2;
      var y = 60;
      var text = 'All the world \'s a stage, and all the men and women merely players. They have their exits and their entrances; And one man in his time plays many parts.';
      context.font = '16pt Calibri';
      context.fillStyle = '#333';
      wrapText(context, text, x, y, maxWidth, lineHeight); 

Valentin

unread,
Nov 25, 2013, 2:45:19 PM11/25/13
to cytoscap...@googlegroups.com
As far as nobody answered, I tried to implement label text wrapping by myself and reached a success. This function should be inserted into textDraw function instead of simple fillText using, and then maxWidth and lineHeight can be defined as constants as good as appropriate property and necessary defaults can be inserted in core to make text wrapping user-friendly.
Also I faced with the problem of autosizing width and height of node solving the question above. The fact is that you can wrap text by splitting it in words, but the length of word can also be longer then the node width defined during CY initialization. In that case a width of the node should be changed to the width of word plus some fixed field width.

The problem is that I don't know is it possible to change width of node during graph initialization without refreshing all the graph ele's. Is it possible? And I have another question to ask: how can I set node width after graph was initialized? I found getNodeWidth function, but can't find setNodeWidth one. Is there a way to do it or can I directly access this property from drawText and change it?

воскресенье, 24 ноября 2013 г., 22:32:06 UTC+4 пользователь Valentin написал:

Max Franz

unread,
Dec 3, 2013, 4:29:43 PM12/3/13
to cytoscap...@googlegroups.com
Hi —

On Monday, 25 November 2013 at 14:45, Valentin wrote:

As far as nobody answered, I tried to implement label text wrapping by myself and reached a success. This function should be inserted into textDraw function instead of simple fillText using, and then maxWidth and lineHeight can be defined as constants as good as appropriate property and necessary defaults can be inserted in core to make text wrapping user-friendly.
As noted in the previous discussions on this topic, the larger concern is performance rather than complexity.  Each successive call to context.fillText() will impact performance, and so making multiple calls for line splitting etc will exasperate this performance issue.

We are planning to try to use an alternative HTML implementation for the labels, because text rendering should be a lot faster — though of course empirical testing of an actual implementation will let us know the true performance difference.

This would also allow for much more customisable content in the labels.  You could imagine font icons, embedded <span>s, etc.

So, if you’re looking for these kinds of features, it would probably be best to wait for — or even help out with — the alternative implementation rather than modifying the old implementation that will likely be discarded in favour of the new one.
Also I faced with the problem of autosizing width and height of node solving the question above. The fact is that you can wrap text by splitting it in words, but the length of word can also be longer then the node width defined during CY initialization. In that case a width of the node should be changed to the width of word plus some fixed field width.

Cy.js uses a styling model similar to HTML+CSS — and just as in the case of HTML+CSS — you would need to either tightly control text size and container (in Cy.js’ case, node) size or you would need to introduce special CSS values for autosizing.  The second approach is the more general one, and it is the strategy used for compound parent node autosizing.  This same approach would then carry over to labels.
The problem is that I don't know is it possible to change width of node during graph initialization without refreshing all the graph ele's. Is it possible? And I have another question to ask: how can I set node width after graph was initialized? I found getNodeWidth function, but can't find setNodeWidth one. Is there a way to do it or can I directly access this property from drawText and change it?

Again, you can not set style programmatically: It’s a function of style.  You can sort of do this via eles.css(), but this is just an override similar to the `style` tag in HTML, and would not be appropriate for your usecase.  

Once we have the alternate label implementation, it will make sense to add new features like this.  If you would like to help accelerate the implementation via pull requests, that would be greatly appreciated.  In either case, you can follow the progress of new features and bug fixes etc in the issue tracker on Github. https://github.com/cytoscape/cytoscape.js/issues

-M
Reply all
Reply to author
Forward
0 new messages