简体   繁体   中英

how to enter 2d data into d3 and access the handle of each subarray to manipulate its elements?

Say, I am having a 2d arr = [[1,2,3],[100,200],['A','B'...'Z']] . As you can see, arr[0].length!=arr[1].length!=arr[2].length .

I want to respresent them as text-tags within an svg.

Moreover, I want to be flexible as in where each subarray starts in terms of (x,y) and how wide the spaces are between each element of a subarray (x, y).

d3.select('svg').selectAll('g').data(arr).enter().append('g').selectAll('text').data((d)=>d).enter().append('text').text(d=>d)

But this way I am losing information within each g. I tried setting .attr('x', (d,i) => (i+1)*20) before .selectAll('text'), but it only adds the 'x'-attr to g and has no effect on the text (ie elements of the array) displayed on the page.

The thing is that I put all them into the DOM. But then how can I adjust their .attr('x'), .attr('y') in a group (without hardcoding) like in lines, but each line can have its own spacing between elements?

You can try to use "getBBox" or getBoundingClientRect to get node width, then make a herizontal layout.

 var arr = [[1,2,3],[100,200],['A','B', 'C', 'D', 'E', 'Z']] var container = d3.select("#box") .append("g") .attr("transform", "translate(10, 50)"); container .selectAll("text") .data(arr) .enter() .append("text") .text(d => d); /* Using "getBBox" or "getBoundingClientRect" method to get each text node's width, then move them one another. You must make sure the svg element and its parent elements are visible, which means "display: none" is should not applied on them. */ var xInit = 0, padding = 15; container .selectAll("text") .each(function (d, i) { d3.select(this).attr("x", xInit); xInit += this.getBBox().width + padding; }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script> <svg id="box" width="500" height="300"></svg> 

I think I have got it. Not sure if that's a clear-cut solution but it works. First, adding ids after creating g s. Then writing functions for x and y coordinates based on the ids (ie rows).

function x(d,i,j){
  let node_id = j[0].parentNode.id; // allows to dynamically access the ids of every text element
  //calculate x_value here
  return x_value;
}

And that function can be passed into the original chain.

d3.select('svg').selectAll('g').data(arr).enter().append('g')
    .attr('id', (d,i)=>i) // adding ids to every g based on the array index
    .selectAll('text').data((d)=>d).enter().append('text').text(d=>d)
    .attr('x', x) // here

If anyone knows a leaner solution, it would be much appreciated as I am new to Javascript and d3.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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