javascript - d3.js - Text position based on text width -


i'm working d3.js generate visualization represents different hypotheses. since hypotheses made of different parts , each word / part gets own text element.

i want base x-position of each text element on text width of previous word including offset. having hypothesis "if x y" need 4 text elements "if" having x=0, , since "if" has width of 10 , use offset of 5 "x" x=15 , on.

i'm using json data this:

{[     {"id" : "id0",     "elements" : [       {          "text" : "if",          "type" : "conditional"       },       {          "text" : "x",          "type" : "variable"       },       {          "text" : "then",          "type" : "conditional"},       {          "text" : "y",          "type" : "variable"       }     ]},    {"id" : "id1",     "elements" : [       {          "text" : "if",          "type" : "conditional"       },       {          "text" : "abc",          "type" : "variable"       },       {          "text" : "then",          "type" : "conditional"},       {          "text" : "xyz",          "type" : "variable"       }     ]} ]} 

the code using generate text elements far (each hypothesis in g-element is

 var svg = d3.select("#viewport")             .append("svg")             .attr("width", 1200)             .attr("height", 800);          var content = svg.append("g").attr("id", "drawing");          var groups = content.selectall().data(arr)             .enter()             .append("g")             .attr("class", function (d) {                 return "hypothesis " + d["id"];             })             .each(function (d, i) {                 d3.select(this).selectall("text")                     .data(d["elements"])                     .enter()                     .append("text")                     .attr("class", function (d) {                         return d.type;                     })                     .text(function (d) {                         return d.text;                     })                     .attr("font-family", "sans-serif")                     .attr("font-size", "20px")                     .attr("x", function (d, j) {                         return j++ * 100;                     })                     .attr("y", 50 * (i + 1));             }); 

when setting x position want width of current text element , push onto variable can next new x-coordinate instead of using random offset of 100 px per word.

so question how can calculated text width (have seen things on getbbox or similar, didn't work me since don't know use them) , how apply text elements. or if there better way create elements, maybe not in single run.

the different elements need styled in different colors , have react mouse-over later, that's why have single text elements.

thanks in advance.

i use getcomputedtextlength these sorts of things, although getbbox work:

.each(function(d, i) {   var runningwidth = 0; //<-- keep running total   ...   .attr("x", function(d, j) {     var w = this.getcomputedtextlength(), //<-- length of node         x = runningwidth; //<-- previous length return     runningwidth += w; //<-- total     return x;   })   ... 

full code:

<!doctype html>  <html>    <head>    <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>    <link rel="stylesheet" href="style.css" />    <script src="script.js"></script>  </head>    <body>    <div id="viewport"></div>    <script>      var arr =        [{          "id": "id0",          "elements": [{            "text": "if",            "type": "conditional"          }, {            "text": "x",            "type": "variable"          }, {            "text": "then",            "type": "conditional"          }, {            "text": "y",            "type": "variable"          }]        }, {          "id": "id1",          "elements": [{            "text": "if",            "type": "conditional"          }, {            "text": "abc",            "type": "variable"          }, {            "text": "then",            "type": "conditional"          }, {            "text": "xyz",            "type": "variable"          }]        }];        var svg = d3.select("#viewport")        .append("svg")        .attr("width", 1200)        .attr("height", 800);        var content = svg.append("g").attr("id", "drawing");        var groups = content.selectall().data(arr)        .enter()        .append("g")        .attr("class", function(d) {          return "hypothesis " + d["id"];        })        .each(function(d, i) {          var runningwidth = 0;                    d3.select(this).selectall("text")            .data(d["elements"])            .enter()            .append("text")            .attr("class", function(d) {              return d.type;            })            .text(function(d) {              return d.text;            })            .attr("font-family", "sans-serif")            .attr("font-size", "20px")            .attr("x", function(d, j) {              var w = this.getcomputedtextlength(),                  x = runningwidth;              runningwidth += w;              return x;            })            .attr("y", 50 * (i + 1));        });    </script>  </body>    </html>


Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -