D3 the zoom only affects the axes

2

I'm using the library D3.js , and I'm creating a scatter-type chart divided into four quadrants. For now I have managed to divide the scatter in the quadrants and paint each quadrant of a color and insert the data.

I have started to apply the zoom function and it works more or less. I zoom in on the axes (change the scale), but the data points remain fixed and the color of the quadrants also.

I guess I'm missing a line of code to define the changes in points and quadrants but I do not know how to enter them since I'm very new in D3.js .

Here you have the code:

            //Alto y ancho
            var w = 500;
            var h = 500;
            var padding = 0;

            var maxx = 0.30
            var minx = -0.30
            var maxy = 6
            var miny = -6
            //Static dataset
            var dataset = [
                            [0.12, 4], [0.05, 3], [0.15, -3], [-0.20, -5], [-0.10, 3]
                          ];

            //Dynamic, random dataset
            /*var dataset = [];                 //Initialize empty array
            var numDataPoints = 50;             //Number of dummy data points to create
            var xRange = Math.random() * 0.25;  //Max range of new x values
            var yRange = Math.random() * 5; //Max range of new y values
            for (var i = 0; i < numDataPoints; i++) {                   //Loop numDataPoints times
                var newNumber1 = Math.round(Math.random() * xRange);    //New random integer
                var newNumber2 = Math.round(Math.random() * yRange);    //New random integer
                dataset.push([newNumber1, newNumber2]);                 //Add new number to array
            }*/

            //Funciones de escala
            var xScale = d3.scaleLinear()
                                 .domain([minx, maxx])
                                 .range([padding, h]);

            var yScale = d3.scaleLinear()
                                 .domain([miny, maxy])
                                 .range([h, padding]);

            var rScale = d3.scaleLinear()
                                 .domain([0, d3.max(dataset, function(d) { return d[1]; })])
                                 .range([2, 6]);

            //Eje x
            var xAxis = d3.axisBottom()
                .scale(xScale);;

            //Eje y
            var yAxis = d3.axisLeft()
                .scale(yScale);

            //Crear el elemento svg
            var svg = d3.select("#linegraph")
                        .append("svg")
                        .attr("width", w)
                        .attr("height", h);



            /*
            //Create labels
            svg.selectAll("text")
               .data(dataset)
               .enter()
               .append("text")
               .text(function(d) {
                    return d[0] + "," + d[1];
               })
               .attr("x", function(d) {
                    return xScale(d[0]);
               })
               .attr("y", function(d) {
                    return yScale(d[1]);
               })
               .attr("font-family", "sans-serif")
               .attr("font-size", "11px")
               .attr("fill", "red");
            */

            //Colores
            var c1 = svg.append("rect")
                .attr("width", (w/2) - padding)             
                .attr("height", (h/2)- padding)
                .attr("transform", "translate("+padding+","+padding+")")
                .attr("fill", "yellow");

            var c2 = svg.append("rect")
                .attr("width", (w/2) - padding)             
                .attr("height", (h/2)- padding)
                .attr("transform", "translate("+w/2+","+padding+")")
                .attr("fill", "green");

            var c3 = svg.append("rect")
                .attr("width", (w/2) - padding)             
                .attr("height", (h/2)- padding)
                .attr("transform", "translate("+padding+","+h/2+")")
                .attr("fill", "red");

            var c4 = svg.append("rect")
                .attr("width", (w/2) - padding)             
                .attr("height", (h/2)- padding)
                .attr("transform", "translate("+w/2+","+h/2+")")
                .attr("fill", "orange");

            //Añadimos el eje x
            var gX = svg.append("g")
                .attr("class", "axis")
                .attr("transform", "translate(0," + (h/2) + ")")
                .call(xAxis);

            //Añadimos el eje y
            var gY = svg.append("g")
                .attr("class", "axis")
                .attr("transform", "translate(" + (w/2)  + ",0)")
                .call(yAxis);

            //Creamos los puntos
            var datos = svg.selectAll("circle")
               .data(dataset)
               .enter()
               .append("circle")
               .attr("cx", function(d) {
                    return xScale(d[0]);
               })
               .attr("cy", function(d) {
                    return yScale(d[1]);
               })
               .attr("r", function(d) {
                    return 5;
               });


//--------------------------------- ZOOM---------------------------------------------------------------------              
            var zoom = d3.zoom()
                .scaleExtent([1, 40])
                .translateExtent([[-100, -100], [w + 90, h + 100]])
                .on("zoom", zoomed);

            svg.call(zoom);
            function zoomed() {
                svg.attr("transform", d3.event.transform);
                gX.call(xAxis.scale(d3.event.transform.rescaleX(xScale)));
                gY.call(yAxis.scale(d3.event.transform.rescaleY(yScale)));        
            }  
    
asked by Lombarda Arda 16.03.2017 в 10:37
source

1 answer

0

You have to do a couple of things to make it work for you. The first as you add a reference to the axes when you zoom you have to make it to the data.

datos.attr("transform",d3.event.transform);

The second is to apply it to the quadrants. Right here, you do not have to add a reference to each quadrant.

c1.attr("transform",d3.event.transform);
c2.attr("transform",d3.event.transform);
c3.attr("transform",d3.event.transform);
c4.attr("transform",d3.event.transform);

Since all would go to the position of the first and would mount one on top of another.

You have to put them in a group, and apply the transformation to it in this way:

grupo = svg.append("svg:g");

            var c2 = grupo.append("rect")
                .attr("width", (w/2) - padding)             
                .attr("height", (h/2)- padding)
                .attr("transform", "translate("+w/2+","+padding+")")
                .attr("fill", "green");

            var c1 = grupo.append("rect")
                .attr("width", (w/2) - padding)             
                .attr("height", (h/2)- padding)
                .attr("transform", "translate("+padding+","+padding+")")
                .attr("fill", "yellow");


            var c3 = grupo.append("rect")
                .attr("width", (w/2) - padding)             
                .attr("height", (h/2)- padding)
                .attr("transform", "translate("+padding+","+h/2+")")
                .attr("fill", "red");

            var c4 = grupo.append("rect")
                .attr("width", (w/2) - padding)             
                .attr("height", (h/2)- padding)
                .attr("transform", "translate("+w/2+","+h/2+")")
                .attr("fill", "orange");

And the zoom function should look something like this:

    function zoomed() {
        var posicionIni = w/2;              
        svg.attr("transform", d3.event.transform);
        gX.call(xAxis.scale(d3.event.transform.rescaleX(xScale)));
        gY.call(yAxis.scale(d3.event.transform.rescaleY(yScale)));        
        datos.attr("transform",d3.event.transform);
        grupo.attr("transform",d3.event.transform);


    }  
    
answered by 17.03.2017 / 13:26
source