src/focalLayout.worker.js
// rotate one group within a bbox.  Results are recorded in newCoords in place.
rotate one group within a bbox.  Results are recorded in newCoords in place.
rotate one group within a bbox . Results are recorded in newCoords in place .
function rotateGroup(nodes, oldCoords, newCoords, degree, bbox) {
        if (nodes.length === 1) {
            newCoords[nodes[0]] = { ...oldCoords[nodes[0]] };
            return;
        }
        const r = (degree / 180) * Math.PI;
        const transMatrix = [
            [Math.cos(r), -Math.sin(r)],
            [Math.sin(r), Math.cos(r)],
        ];
        const tempCoords = [];
        const centerX = bbox.x + bbox.width / 2,
            centerY = bbox.y + bbox.height / 2;
        for (let nid of nodes) {
            const c = oldCoords[nid];
            tempCoords.push({
                x: transMatrix[0][0] * (c.x - centerX) + transMatrix[0][1] * (c.y - centerY) + centerX,
                y: transMatrix[1][0] * (c.x - centerX) + transMatrix[1][1] * (c.y - centerY) + centerY,
            });
        }
        if ([0, 90, 180, 270].indexOf(degree) === -1) {
            const xExtent = extent(tempCoords.map((t) => t.x)),
                yExtent = extent(tempCoords.map((t) => t.y));
            const xScale = scaleLinear()
                    .domain(xExtent)
                    .range([bbox.x + padding, bbox.x + bbox.width - padding]),
                yScale = scaleLinear()
                    .domain(yExtent)
                    .range([bbox.y + padding, bbox.y + bbox.height - padding]);
            for (let i = 0; i < nodes.length; i++) {
                newCoords[nodes[i]] = {
                    x: xScale(tempCoords[i].x),
                    y: yScale(tempCoords[i].y),
                };
            }
        } else {
            for (let i = 0; i < nodes.length; i++) {
                newCoords[nodes[i]] = {
                    x: tempCoords[i].x,
                    y: tempCoords[i].y,
                };
            }
        }
    }
function rotateGroup ( nodes , oldCoords , newCoords , degree , bbox ) { if ( nodes . length === 1 ) { newCoords [ nodes [ 0 ] ] = { ... oldCoords [ nodes [ 0 ] ] } ; return ; } const r = ( degree / 180 ) * Math . PI ; const transMatrix = [ [ Math . cos ( r ) , - Math . sin ( r ) ] , [ Math . sin ( r ) , Math . cos ( r ) ] , ] ; const tempCoords = [ ] ; const centerX = bbox . x + bbox . width / 2 , centerY = bbox . y + bbox . height / 2 ; for ( let nid of nodes ) { const c = oldCoords [ nid ] ; tempCoords . push ( { x : transMatrix [ 0 ] [ 0 ] * ( c . x - centerX ) + transMatrix [ 0 ] [ 1 ] * ( c . y - centerY ) + centerX , y : transMatrix [ 1 ] [ 0 ] * ( c . x - centerX ) + transMatrix [ 1 ] [ 1 ] * ( c . y - centerY ) + centerY , } ) ; } if ( [ 0 , 90 , 180 , 270 ] . indexOf ( degree ) === - 1 ) { const xExtent = extent ( tempCoords . map ( ( t ) => t . x ) ) , yExtent = extent ( tempCoords . map ( ( t ) => t . y ) ) ; const xScale = scaleLinear ( ) . domain ( xExtent ) . range ( [ bbox . x + padding , bbox . x + bbox . width - padding ] ) , yScale = scaleLinear ( ) . domain ( yExtent ) . range ( [ bbox . y + padding , bbox . y + bbox . height - padding ] ) ; for ( let i = 0 ; i < nodes . length ; i ++ ) { newCoords [ nodes [ i ] ] = { x : xScale ( tempCoords [ i ] . x ) , y : yScale ( tempCoords [ i ] . y ) , } ; } } else { for ( let i = 0 ; i < nodes . length ; i ++ ) { newCoords [ nodes [ i ] ] = { x : tempCoords [ i ] . x , y : tempCoords [ i ] . y , } ; } } }
rotate one group within a bbox.
rotate one group within a bbox .
// No change // Change in place // rescale since nodes might go out of bbox // console.log({ degree, nodes, newCoords });