Search code examples
javascriptsvgscaled3.js

Using d3 SVG Scale without translate


I'm trying to use the scale() transform in SVG and d3. I understand it works by increasing the coordinate scale, but it seems to also be translating my object. When I have a rectangle located at (100,100) and I do a scale(2), the rectangle doubles in size and moves to (0,0). How do I get it to stop moving from (100,100) to (0,0) while scaling. The following is my code:

    var mysvg = d3.select("#viz")
        .append("svg")
        .attr("width", 500)
        .attr("height", 500)
        .attr("class","mylist");  

    var node = mysvg.selectAll("g.node")
        .data(mydata)
        .enter().append("g")
        .attr("class","node")
        .attr("transform", function(d) { return "translate(" + d.xpos + "," + d.ypos + ")"; });         

    node.append("rect")
        .attr("width",tileWidth)
        .attr("height",tileWidth)
        .attr("fill","orange")
        .attr("rx",10)
        .attr("ry",10);

    node.append("text")
        .attr("transform",function(d) { return "translate(" + tileWidth/2 + "," + tileWidth/2 +")" })
        .attr("text-anchor", "middle")
        .attr("dy", ".3em")
        .attr("font-family","serif")
        .text(function(d) { return d.symbol; });

    node.on("mouseover",function(){ d3.select(this).transition().attr("transform","scale(1.2)") });
    node.on("mouseout",function(){ d3.select(this).transition().attr("transform","scale(1)") });

Solution

  • Your mouseover and mouseout events are overriding the original translate(" + d.xpos + "," + d.ypos + ").

    I think the easiest way to work around this would be adding a parent g and translating that, such as...

    var mysvg = d3.select("#viz")
            .append("svg")
            .attr("width", 500)
            .attr("height", 500)
            .attr("class","mylist");  
    
        var parent = mysvg.selectAll("g.parent")
            .data(mydata)
            .enter().append("g")
            .attr("class","parent")
            .attr("transform", function(d) { return "translate(" + d.xpos + "," + d.ypos + ")"; });      
    
        var node = mysvg.selectAll("g.parent")
            .enter().append("g")
            .attr("class","node")
         });         
    
        node.append("rect")
            .attr("width",tileWidth)
            .attr("height",tileWidth)
            .attr("fill","orange")
            .attr("rx",10)
            .attr("ry",10);
    
        node.append("text")
            .attr("transform",function(d) { return "translate(" + tileWidth/2 + "," + tileWidth/2 +")" })
            .attr("text-anchor", "middle")
            .attr("dy", ".3em")
            .attr("font-family","serif")
            .text(function(d) { return d.symbol; });
    
        node.on("mouseover",function(){ d3.select(this).transition().attr("transform","scale(1.2)") });
        node.on("mouseout",function(){ d3.select(this).transition().attr("transform","scale(1)") });