1

I have a scenario where I am displaying the svg which has 5 rect and I want to add the delete icon (import DeleteIcon from '@mui/icons-material/Delete';) from material ui for each of the rect in front of the rect box, so total there should be 5 delete icon.

Material UI: https://mui.com/material-ui/material-icons/?query=delete&selected=Delete

Here is the code :

function svg() {
g.selectAll("g.legendCells")
.data(data)
.enter()
.append("g")
.append("rect")
g.selectAll("rect")
.attr("height", 1)
.attr("width", 1)
.style("fill", function (data) {
return data["color"];
});
g.selectAll("rect")
.attr("x", function (_d: number, i: number) {
return i;
})
.attr("y", 0);
}

Jsfiddle : https://jsfiddle.net/b2motr3c/2/

Eric
  • 123
  • 9
  • You can put the path in a symbol `` and then ypu can use the symbol with the same x y width and height as the – enxaneta Dec 29 '22 at 14:00
  • 1
    Is it possible for you to explain it using some fiddle examples or altering my fiddle? I tried to add the icon using image like "g.selectAll("g"). append("image").attr("xlink:href", DeleteIcon)" but href gives me like "xlink:href="[object Object]"" – Eric Dec 29 '22 at 14:16

2 Answers2

2

The svg for the deleteIcon looks like this:

 <svg viewBox="0 0 24 24" data-testid="DeleteIcon">
    <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"></path>
  </svg>

You can put it inside the main svg element and transform it in a symbol with the same viewBox attribute. Since the symbol has a vieawBox the use element can take not only a x and y but also a width and height attributes.

As I've commented you can give the use the same x y width and height as the <rect>. This will position (x y) and resize (width, height) the symbol as you need.

Please observe that once you have a symbol you can reuse it (with <use>) as many times you need.

<svg width="300" height="200" style="outline: 5px dotted green">

  <symbol viewBox="0 0 24 24" id="DeleteIcon">
    <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"></path>
  </symbol>
  
  <rect x="70" y="10" width="20" height="20" style="fill:green" />
  
  <use href="#DeleteIcon" x="70" y="10" width="20" height="20" fill="white"/>

</svg>
enxaneta
  • 31,608
  • 5
  • 29
  • 42
  • I was playing around with your solution, but I see that the icon comes on top of rect cells, and I need the rect cells and icon to be placed side by side, I tried adjusting viewbox and also x y, but it gets hidden behind the rect https://jsfiddle.net/1bz3yco2/ – Eric Dec 29 '22 at 15:19
  • 1
    In this case you need to change the x to a bigger value. Try for example 70 + 20 = 90. And do not forgrt to use a different fill. Now it's white – enxaneta Dec 29 '22 at 16:32
  • Thanks, it worked but just wondering if it's possible to append click event to the delete icon, because my requirement is to do some action on the particular selected rect on clicking the delete icon. Is it possible to append the click event for the "symbol" or "use" ? – Eric Dec 30 '22 at 10:47
  • I tried like g.selectAll("g"). append("use").attr("href", "#DeleteIcon").attr("height", 1).attr("width", 1).attr("onclick", handleClick()) , but handleClick do not get called on clicking the DeleteIcon. Also when I do inspect element, the onClick attr is not shown inside "use" – Eric Dec 30 '22 at 10:55
  • It can be the way you create the element in SVG. Please read about [Creating SVG elements dynamically with javascript inside HTML](https://stackoverflow.com/questions/20539196/creating-svg-elements-dynamically-with-javascript-inside-html) – enxaneta Dec 30 '22 at 12:49
  • Also you may want to read about [How to add event listeners to objects in a svg](https://stackoverflow.com/questions/12451855/how-to-add-event-listeners-to-objects-in-a-svg) – enxaneta Dec 30 '22 at 12:54
0

How I would approach it is encapsulating each of the rects in group elements and placing a 'DeleteIcon' (from import) component inside it, take for instance:

<g>
  <rect x="70" y="10" width="20" height="20" style="fill: green" />
  <DeleteIcon />
</g>

Then adjust the x/y attributes and any other relevant properties to fit your desired look.

Xephoriath
  • 121
  • 4
  • Yes, even I have that solution in my mind, but the thing is I add rectangle to the svg something like this ". append("g"). append("rect")" and now if i want to add the icon means how can I append it? – Eric Dec 29 '22 at 14:02
  • I tried to add the icon using image like "g.selectAll("g"). append("image").attr("xlink:href", DeleteIcon)" but href gives me like "xlink:href="[object Object]"" – Eric Dec 29 '22 at 14:20
  • I would try adding "g.selectAll("g.legendCells") .append("use") .attr("href", DeleteIcon.url) /* DeleteIcon.url being the url of the file w the image */ .attr("x", function (_d: number, i: number) { return i; }) .attr("y", 0);" – Xephoriath Dec 29 '22 at 14:23
  • Tried your solution as well but DeleteIcon.url(throws error as it cannot find url) and then i gave only DeleteIcon, but it gives href as [object object] – Eric Dec 29 '22 at 14:33