简体   繁体   中英

Adding text to rectangle elements using D3 / SVG

I'm loading an external SVG file as below and need to add text to each rect that I can reference and manipulate. To do this I understand that I need to put each rect inside a group and insert the text element inside the same group. If possible I would like to do this through code as changing the structure of the SVG file would take forever as there will potentially be 100s of rects.

What is the best way to go about achieving this? I did look through some of the other questions however couldn't find the answer I need.

The best that I can assume at the moment is that I'll need to either select all rects and append the group or either loop through and select each rect individually?

floor.svg

    <rect id="SR001" x="288.62" y="220.7" class="st10" width="25.74" height="46.08"/>
<rect id="SR002" x="288.62" y="266.7" class="st10" width="25.74" height="46.08"/>
<rect id="SR003" x="288.62" y="312.49" class="st10" width="25.74" height="46.08"/>
<rect id="SR004" x="288.62" y="375.62" class="st10" width="25.74" height="46.08"/>
<rect id="SR005" x="288.62" y="421.7" class="st10" width="25.74" height="46.08"/>
<rect id="SR006" x="288.62" y="467.49" class="st10" width="25.74" height="46.08"/>
<rect id="SR007" x="288.62" y="513.62" class="st10" width="25.74" height="46.08"/>

This is how the SVG file is loaded which seems to work fine. I have other functions that enable me to interact with the rectangles on certain mouse events etc.

javascript

d3.xml("floor.svg", function(xml) {
  document.body.appendChild(xml.documentElement);});

The approach I'd take is first extract data from rects, then remove all of the rects, and then recreate it all in structure you want it to be. To extract, you can use selection.each(callback) . Inside callback this points to the element, thus you can do eg d3.select(this).attr('x') to get its x attribute

 <!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { margin: 0; position: fixed; top: 0; right: 0; bottom: 0; left: 0; } </style> </head> <body> <svg> <rect id="SR001" x="288.62" y="220.7" class="st10" width="25.74" height="46.08"/> <rect id="SR002" x="288.62" y="266.7" class="st10" width="25.74" height="46.08"/> <rect id="SR003" x="288.62" y="312.49" class="st10" width="25.74" height="46.08"/> <rect id="SR004" x="288.62" y="375.62" class="st10" width="25.74" height="46.08"/> <rect id="SR005" x="288.62" y="421.7" class="st10" width="25.74" height="46.08"/> <rect id="SR006" x="288.62" y="467.49" class="st10" width="25.74" height="46.08"/> <rect id="SR007" x="288.62" y="513.62" class="st10" width="25.74" height="46.08"/> </svg> <script> var rectData = []; var svg = d3.select("svg") .attr('width', 600) .attr('height', 600); svg.selectAll("rect") .each(function() { var r = d3.select(this); rectData.push({ id: r.attr('id'), x: r.attr('x'), y: r.attr('y'), class: r.attr('class'), width: r.attr('width'), height: r.attr('height') }); }).remove(); var g = svg.selectAll('g') .data(rectData) .enter() .append('g') .attr('id', function(d) { return d.id; }); g.append('rect') .attr('class', function(d) { return d.class; }) .attr('x', function(d) { return dx; }) .attr('y', function(d) { return dy; }) .attr('width', function(d) { return d.width; }) .attr('height', function(d) { return d.height; }); g.append('text') .attr('y', function(d) { return dy; }) .attr('x', function(d) { return dx; }) .text(function(d) { return d.id; }) </script> </body> 

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