2013-02-14 23 views
6

Sto lavorando a un grafico a dispersione d3.js e voglio che sia zoomabile senza ridimensionare i punti. L'ho basato su http://static.cybercommons.org/js/d3/examples/zoom-pan/zoom-pan.html che ha linee di griglia zoomabili funzionanti, ma finora ho problemi a ottenere i punti da ingrandire. Quando eseguo lo zoom/panoramica, ciascun punto restituisce il seguente avviso della console:d3.js zoom/trascina diagramma di dispersione

Valore inatteso tradurre (NaN, 0) attributo di trasformazione di parsing.

si può vedere la cosa completa, con screenshot del disegno di sotto di essa (fare clic su 'Apri in una nuova finestra' per vedere il tutto): http://bl.ocks.org/242dcfc83d98743d8589

versione semplificata del JS qui:

d3.csv("js/AllOccupations.csv", function(data) { 

    var margin = {top: 30, right: 10, bottom: 50, left: 60}, 
     width = 960 - margin.left - margin.right, 
     height = 500 - margin.top - margin.bottom; 

    var xMax = d3.max(data, function(d) { return +d.TotalEmployed2011; }), 
     xMin = 0, 
     yMax = d3.max(data, function(d) { return +d.MedianSalary2011; }), 
     yMin = 0; 

    //Define scales 
    var x = d3.scale.linear() 
     .domain([xMin, xMax]) 
     .range([0, width]); 

    var y = d3.scale.linear() 
     .domain([yMin, yMax]) 
     .range([height, 0]); 

    var colourScale = function(val){ 
     var colours = ['#9d3d38','#c5653a','#f9b743','#9bd6d7']; 
     if (val > 30) { 
      return colours[0]; 
     } else if (val > 10) { 
      return colours[1]; 
     } else if (val > 0) { 
      return colours[2]; 
     } else { 
      return colours[3]; 
     } 
    }; 


    //Define X axis 
    var xAxis = d3.svg.axis() 
     .scale(x) 
     .orient("bottom") 
     .tickSize(-height) 
     .tickFormat(d3.format("s")); 

    //Define Y axis 
    var yAxis = d3.svg.axis() 
     .scale(y) 
     .orient("left") 
     .ticks(5) 
     .tickSize(-width) 
     .tickFormat(d3.format("s")); 

    var svg = d3.select("#chart").append("svg") 
     .attr("width", width + margin.left + margin.right) 
     .attr("height", height + margin.top + margin.bottom) 
     .append("g") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
     .call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom)); 

    svg.append("rect") 
     .attr("width", width) 
     .attr("height", height); 

    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 

    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis); 

    // Create points 
    svg.selectAll("polygon") 
     .data(data) 
     .enter() 
     .append("polygon") 
     .attr("transform", function(d, i) { 
      return "translate("+x(d.TotalEmployed2011)+","+y(d.MedianSalary2011)+")"; 
     }) 
     .attr('points','4.569,2.637 0,5.276 -4.569,2.637 -4.569,-2.637 0,-5.276 4.569,-2.637') 
     .attr("opacity","0.8") 
     .attr("fill",function(d) { 
      return colourScale(d.ProjectedGrowth2020); 
     }); 

    // Create X Axis label 
    svg.append("text") 
     .attr("class", "x label") 
     .attr("text-anchor", "end") 
     .attr("x", width) 
     .attr("y", height + margin.bottom - 10) 
     .text("Total Employment in 2011"); 

    // Create Y Axis label 
    svg.append("text") 
     .attr("class", "y label") 
     .attr("text-anchor", "end") 
     .attr("y", -margin.left) 
     .attr("x", 0) 
     .attr("dy", ".75em") 
     .attr("transform", "rotate(-90)") 
     .text("Median Annual Salary in 2011 ($)"); 


    function zoom() { 
     svg.select(".x.axis").call(xAxis); 
     svg.select(".y.axis").call(yAxis); 
    } 
}); 

Qualsiasi aiuto sarebbe enormemente apprezzato.

risposta

6

Le linee della griglia nell'esempio sono, infatti, le tacche degli assi! Quindi noterai che la tua funzione di zoom li aggiorna sugli eventi del mouse, ma non aggiorni mai le posizioni dei punti. Dovresti copiare le linee di posizionamento del punto nella funzione di zoom (o scomporle in una funzione separata).

Questo è ciò che il mio appare come:

function zoom() { 
    svg.select(".x.axis").call(xAxis); 
    svg.select(".y.axis").call(yAxis); 
    svg.selectAll("polygon") 
     .attr("transform", function(d, i) { 
      return "translate("+x(d.TotalEmployed2011)+","+y(d.MedianSalary2011)+")"; 
     }) 
     .attr('points','4.569,2.637 0,5.276 -4.569,2.637 -4.569,-2.637 0,-5.276 4.569,-2.637'); 
} 

Si può provare here

+0

Perfetto! Ho pensato che avevo bisogno di aggiungere qualcosa alla funzione zoom ma non potevo pensare a cosa. Grazie mille! di riferimento futuro: La soluzione avete proposto lascia i puntini fuoriuscire dalla griglia e sopra gli assi, così li ho avvolto in uno SVG per contenerli come segue: \t \t svg.append ("SVG") \t \t \t .attr ("classe", "punti") \t \t \t .attr ("larghezza", larghezza) \t \t \t .attr ("altezza", altezza) \t \t \t .selectAll ("poligono") \t \t \t .data (dati) \t \t \t .enter() \t \t \t .Append ("poligono") \t \t \t ... – richardwestenra