I am working with a svg element which has few g
elements.
The basic markup is following
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g class="smGrp0" opacity="0" transform="translate(0.5,0)">
</g>
<g class="smGrp1" opacity="1" transform="translate(101.33333333333333,0)">
</g>
<g class="smGrp2" opacity="1" transform="translate(202.16666666666666,0)">
</g>
<g class="smGrp3" opacity="1" transform="translate(303,0)">
</g>
</svg>
<script src="jsx3.js"></script>
</body>
</html>
I want to create a rect
forEach g
element with fixed x,y,height,width
but want to grab the transform property from each g
element and pass on to each rect
. If I use vanilla javascript, I can achieve the task as follows
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g class="smGrp0" opacity="0" transform="translate(0.5,0)">
</g>
<g class="smGrp1" opacity="1" transform="translate(101.33333333333333,0)">
</g>
<g class="smGrp2" opacity="1" transform="translate(202.16666666666666,0)">
</g>
<g class="smGrp3" opacity="1" transform="translate(303,0)">
</g>
</svg>
<script type="text/javascript">
const data = document.querySelectorAll("[class^=smGrp]");
const svgns = 'http://www.w3.org/2000/svg';
data.forEach(
(a, i) => {
const rect = document.createElementNS(svgns, 'rect');
rect.setAttribute('x', '0');
rect.setAttribute('y', '0');
rect.setAttribute('height', `670`)
rect.setAttribute('width', `110`)
rect.style.setProperty('fill', 'none');
rect.style.setProperty('stroke', 'black')
rect.setAttribute('transform', `${a.getAttribute('transform')}`)
document.querySelector('svg').appendChild(rect);
}
);
</script>
</body>
</html>
It generates this
How can I achieve the same using d3?
So far, I tried this which did not work.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g class="smGrp0" opacity="0" transform="translate(0.5,0)">
</g>
<g class="smGrp1" opacity="1" transform="translate(101.33333333333333,0)">
</g>
<g class="smGrp2" opacity="1" transform="translate(202.16666666666666,0)">
</g>
<g class="smGrp3" opacity="1" transform="translate(303,0)">
</g>
</svg>
<script type="text/javascript">
const dataset = d3.selectAll("[class^=smGrp]");
d3.select('svg').selectAll('smGrp').data(dataset).enter()
.append('rect')
.attr('x', '0')
.attr('y', '0')
.attr('height', `670`)
.attr('width', `110`)
.style('fill', 'none')
.style('stroke', 'black')
.attr('transform', (d, i) => { return `${d.attr('transform')}` });
</script>
</body>
</html>
Thank you in advance.