Home > database >  How to do use getbbox to generate multiple rects
How to do use getbbox to generate multiple rects

Time:07-19

enter image description herei can only generate one rect for the text i have. I dont know how to apply getBBox to multiple text elements so they can all have their own backgrounds. Does anyone know how i can accomplish this?

function jobsCreation() {
        let enteringText = dataJobs
            .enter()
            .append("text")
            .attr("x", function (d) { return d.posX })
            .attr("y", function (d) { return d.posY })
            .attr("id", "jobText")
            .text(function (d) { return d.name });


        let texts = d3.selectAll("#jobText");

        
        let bbox = enteringText.node().getBBox();
        console.log(bbox);



        let rect = svg.append("rect")
            .attr("x", bbox.x)
            .attr("y", bbox.y)
            .attr("width", bbox.width)
            .attr("height", bbox.height)
            .attr("id", "nodeBox")
            .style("fill", "white")
            .style("stroke", "black")
            .style("stroke-width", "1.5px");

        enteringText.raise();




    }

CodePudding user response:

svg.append() will create a single element and selection.node() will only return a single node.

While selection.nodes() will return an array all the nodes in a selection, we still need to append one rectangle for each node. To do this, we can use the array returned by selection.nodes() as a data array for a enter cycle:

let enteringRects = svg.selectAll("rect")
  .data(enteringText.nodes())
  .enter()
  .append("rect")
  .attr("x", function(node) { return node.getBBox().x })
  .attr("y", function(node) { return node.getBBox().y })
  .attr("width", function(node) { return node.getBBox().width })
  .attr("height", function(node) { return node.getBBox().height })
  .style("fill", "white")
  .style("stroke", "black")
  .style("stroke-width", "1.5px")
  .lower();

Now we create one rectangle for every text element we create. As the bound datum in this selection is a DOM element we can access getBBox() easily as it is now a property of the datum itself.

let data = d3.range(15).map(function(d) { return Math.floor(Math.random() * 150) });
let width = 500;
let height = 300;

let svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);
  
let enteringText = svg.selectAll("text")
  .data(data)
  .enter()
  .append("text")
  .attr("x", function (d) { return Math.random() * width })
  .attr("y", function (d) { return Math.random() * height })
  .text(function (d) { return d });


let enteringRects = svg.selectAll("rect")
  .data(enteringText.nodes())
  .enter()
  .append("rect")
  .attr("x", function(node) { return node.getBBox().x })
  .attr("y", function(node) { return node.getBBox().y })
  .attr("width", function(node) { return node.getBBox().width })
  .attr("height", function(node) { return node.getBBox().height })
  .style("fill", "white")
  .style("stroke", "black")
  .style("stroke-width", "1.5px")
  .lower();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

  • Related