简体   繁体   English

如何为arbor js中的每个节点文本添加换行符

[英]How to add new line character for each node text in arbor js

I have a network,with 14 nodes, and each node has a label, and also edges for connecting these nodes to each other. 我有一个网络,有14个节点,每个节点都有一个标签,还有用于将这些节点相互连接的边。 I tried to enter a long label for one of these nodes, and unfortunatly it seems that arborjs show labels on nodes just horizontally, so I tried to put a new line character in a label text "\\n" and it will render it as an space, so I was wondering if anybody knows how to have multiple line label for a node in arbor js? 我试图为其中一个节点输入一个长标签,不幸的是,似乎arborjs只在水平方向上显示节点上的标签,所以我试图在标签文本“\\ n”中添加一个新的行字符并将其渲染为空间,所以我想知道是否有人知道如何在arbor js中为节点设置多个线路标签? Here is the code : 这是代码:

<script language="javascript" type="text/javascript">
    var sys = arbor.ParticleSystem(1000, 700,0.01);
    sys.parameters({gravity:false});
    sys.renderer = Renderer("#viewport") ;
    var data = {
    nodes:{
    STRUCTURE:{'color':'black','shape':'rect','label':'STRUCTURE', },
    Engineering:{'color':'salmon','shape':'rect','label':'Engineering'},
    Architecture:{'color':'salmon','shape':'rect','label':'Architecture'},
    ArtsSciences:{'color':'salmon','shape':'rect','label':'Arts & Sciences'},
    EarthEnergy:{'color':'salmon','shape':'rect','label':'Earth & Energy'},
    SustainableDesign:s{'color':'lightskyblue','shape':'rect','label':'Sustainable Design'},
    sutabledesignleaf1:{'color':'lawngreen','shape':'rect','label':'Earthen Structures'},
    MaterialsStructures:{'color':'lightskyblue','shape':'rect','label':'Materials & Structures'},
    MaterialsStructuresleaf1:{'color':'lawngreen','shape':'rect','label':'AEROSPACE/MECH. ENGINEERING'},
    LithosphereDynamics:{'color':'lightskyblue','shape':'rect','label':'Lithosphere Dynamics'},
    Energy:{'color':'lightskyblue','shape':'rect','label':'Energy'},
    LithosphereDynamicsleaf1:{'color':'lawngreen','shape':'rect','label':'Structure/Tectonophy'},
    Energyleaf1:{'color':'lawngreen','shape':'rect','label':'Structural Control on Reservoirs'},
    ArtsSciencesleaf1:{'color':'lawngreen','shape':'rect','label':'VARIOUS THEMES Market Structure'},
    },
    edges:{
    STRUCTURE:{ Engineering:{}, Architecture:{} , ArtsSciences:{}, EarthEnergy:{}},
    ArtsSciences:{ArtsSciencesleaf1:{}},
    EarthEnergy:{Energy:{},LithosphereDynamics:{}},
    Energy:{Energyleaf1:{}},
    LithosphereDynamics:{LithosphereDynamicsleaf1:{}},
    Engineering:{MaterialsStructures:{}},
    MaterialsStructures:{MaterialsStructuresleaf1:{}},
    Architecture:{SustainableDesign:{}},
    SustainableDesign:{sutabledesignleaf1:{}}
    }
    };
    sys.graft(data);
        var canvas =  document.selectElementById('viewport') ;  
    var context  =  canvas.getContext('2d');
      context.font = '40pt Calibri';
    context.fillStyle = 'blue';
</script>

suppose in this code, for STRUCTURE node's label we have "STRUCTURE" but when I want to have like a long text lie "kaskdjhkjahdkjhaskjdhjkahskjdhakjshdkjahdkjhaskjdhkjahsdkjhakjsdhkjashdkjhasdkjhkajshdkjhakjdhkajshdk" it doesn't break it to two lines, it will show up as one line, and even if I put a new line character, it will consider it as a space and it will show that again in one line, any help is appreciated. 假设在这段代码中,对于STRUCTURE节点的标签,我们有“STRUCTURE”但是当我想要一个长文本谎言“kaskdjhkjahdkjhaskjdhjkahskjdhakjshdkjahdkjhaskjdhkjahsdkjhakjsdhkjashdkjhasdkjhkjshdkjhakjdhkajshdk”时它不会将它分成两行,它会显示为一行,即使我添加一个新的行字符,它会将其视为一个空格,它将再次显示在一行中,任何帮助都是值得赞赏的。 Thanks in advance 提前致谢

Thank you for your answer, last night, I figured out that unfortunately there is no way on canvas fillText() to draw text in multiple line, so I had to write my wrapper for that, here is the function that I wrote, and it's working right now, 感谢您的回答,昨晚,我发现不幸的是,在画布上没有办法fillText()在多行中绘制文本,所以我必须为此编写我的包装器,这是我写的函数,它是现在正在工作,

function wrap_text(var rawstring,var line_width)
                {
                    var strarray  = new Array() ;  
                    var temp_str = new Array() ; 
                    var j = 0 ;var i = 0 ;  
                    strarray = text.split(' ');                 
                    var temp = strarray[j] ;
                    j++;
                    while(j < strarray.length)
                    {
                        while(temp.length <30)
                        {
                            temp = temp+" "+strarray[j];
                            j++;
                        }   
                        temp_str[i]=temp ; i++;
                        var temp = "" ;
                    }
                    return temp_str; 
                }
                var wrap_result = wrap_text('kjakjhkjashd kajasd asdmbdmnad nmauhiqwe kbawem mnbasdm',20);

                for (var i = 0; i <wrap_result.length ; i--) 
                {
                    console.log(wrap_result[i]);
                }

I know this post is 2 year too late, though I was still having the same issue and unable to find the solution anywhere. 我知道这篇帖子已经晚了2年,虽然我仍然遇到同样的问题但无法在任何地方找到解决方案。 The main problem is the canvas fillText does not support multiple lines. 主要问题是canvas fillText不支持多行。 So you have to add multiple lines to the label. 所以你必须在标签上添加多行。 The trick is to split out the returns into an array and loop over the array for each new line. 诀窍是将返回分解为数组并为每个新行循环遍历数组。

To keep the code clean, I prefer to not to directly edit the function in the files. 为了保持代码清洁,我宁愿不直接编辑文件中的函数。 To get the multiple lines to work add to your custom JS the below function which will override the Cytoscape internal label rendering. 要使多行工作,请将以下函数添加到自定义JS中,该函数将覆盖Cytoscape内部标签呈现。 Works for both cytoscape.js & cytoscape.min.js 适用于cytoscape.js和cytoscape.min.js

//function to override the default label rending to support multiple lines
;(function($$){ 'use strict';
  var CanvasRenderer = $$('renderer', 'canvas');
    CanvasRenderer.prototype.drawText = function(context, element, textX, textY) {
    var style = element._private.style;
    var parentOpacity = element.effectiveOpacity();
    if( parentOpacity === 0 ){ return; }

    var text = this.setupTextStyle( context, element );

    if ( text != null && !isNaN(textX) && !isNaN(textY) ) {

      var lineWidth = 2  * style['text-outline-width'].value; // *2 b/c the stroke is drawn centred on the middle
      if (lineWidth > 0) {
        context.lineWidth = lineWidth;
        context.strokeText(text, textX, textY);
      }

      //START NEW CODE
      //remove old label rendinging
      //context.fillText(text, textX, textY);

      //explode the text into an array split up by line returns
      var lines = text.split("\n");

      //loop through each of the lines
      for (var index = 0; index < lines.length; ++index) {
        //render the multiple lines
        context.fillText(lines[index], textX, (textY + (style['font-size'].pxValue * 1.2 * index)));
      }
      //END NEW CODE
    }
  };

})( cytoscape );

This question really concerns canvas.fillText() , not arbor.js, see this question . 这个问题确实涉及canvas.fillText() ,而不是arbor.js,请看这个问题 In short, this is a limitation of the fillText function. 简而言之,这是fillText函数的限制。

That said, you can solve this problem relatively simply. 也就是说,你可以相对简单地解决这个问题。 The following all assumes you are basing your rendering on the "atlas" example , but you can figure it out from the idea anyway I think. 以下都假设您将渲染基于“atlas”示例 ,但无论如何我都可以从想法中找到它。

      // draw the text
      if (label){
        ctx.font = "bold 11px Arial"
        ctx.textAlign = "center"

        // if (node.data.region) ctx.fillStyle = palette[node.data.region]
        // else ctx.fillStyle = "#888888"
        ctx.fillStyle = "#888888"

        // ctx.fillText(label||"", pt.x, pt.y+4)
        ctx.fillText(label||"", pt.x, pt.y+4)
      }

Check out the code above to see how the text is rendered. 查看上面的代码,了解文本的呈现方式。 We can replace the line ctx.fillText(label||"", pt.x, pt.y+4) with a loop based on multiple lines you want to render. 我们可以用基于你想渲染的多行的循环替换行ctx.fillText(label||"", pt.x, pt.y+4) Make your label value something like line 1\\nline 2\\nline 3 , then use String.split() to make it into an array like so: 使您的标签值类似于line 1\\nline 2\\nline 3 ,然后使用String.split()使其成为一个数组,如下所示:

var lines = label.split("\n");

Now, loop through lines and render a ctx.fillText() for each one. 现在,遍历lines并为每个lines渲染ctx.fillText() If you are basing your project closely on the examples you may need to adjust the layout to make it look right, but hopefully this has put you on the right track. 如果您将项目基于示例,则可能需要调整布局以使其看起来正确,但希望这会让您走上正确的轨道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM