score:0

Accepted answer

Ok so I figured it out after multiple manual tests. Not sure it is the most efficient formula but at least it works! Hope it helps someone in the same case!

    //Draw initial svg
    const svg = d3.select('body').append('svg').attr('width', 1000).attr('height', 1000)

    // Data for the initial group with one rectangle inside
    const groupData = {width: 200, height: 100, translateX: 200, translateY: 150, rotation: 45}

    //Create the initial group
    let group1 = svg.append('g').attr('id', 'group1')

    //Append a rect to the initial group, translate and rotate
    group1.append('rect').attr('width', groupData.width).attr('height', groupData.height).attr('fill', 'blue')

    group1.attr('transform', `translate(${groupData.translateX}, ${groupData.translateY}) rotate(${groupData.rotation}, ${groupData.width / 2}, ${groupData.height / 2})`)

    const rows = 3
    const columns = 2
    // Create row and column array to dynamically split the initial group based on the rows and columns numbers
    const rowArray = [...Array(+rows).keys()]
    const columnArray = [...Array(+columns).keys()]

    rowArray.forEach(row => {
      columnArray.forEach( column => {
          
      let newGroup = svg.append('g').attr('id', `group${column}${row}`)

      newGroup.append('rect')
        .attr('width', groupData.width / columns)
        .attr('height', groupData.height / rows)
        .attr('fill', 'orange')

        const cx = groupData.translateX + (groupData.width / columns / 2) * (columns - 1);
        const cy = groupData.translateY + (groupData.height / rows / 2) * (rows - 1);
        const tmpX = groupData.translateX + (groupData.width / columns) * column - cx;
        const tmpY = groupData.translateY + (groupData.height / rows) * row - cy;
        const pointX = tmpX * Math.cos((groupData.rotation * Math.PI) / 180) - tmpY * Math.sin((groupData.rotation * Math.PI) / 180) + cx;
        const pointY = tmpX * Math.sin((groupData.rotation * Math.PI) / 180) + tmpY * Math.cos((groupData.rotation * Math.PI) / 180) + cy;


        newGroup.attr('transform', `translate(${groupData.rotation != 0 ? pointX : groupData.translateX + (groupData.width / columns) * column}, ${groupData.rotation != 0 ? pointY : groupData.translateY + (groupData.height / rows) * row}) rotate(${groupData.rotation}, ${groupData.width / columns / 2}, ${groupData.height  / rows / 2})`)
          
      })
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>


Related Query