2013-04-08 16 views
1

Je suis nouveau sur D3 et j'essaie actuellement des options de panoramique horizontal pour un graphique à barres. J'ai essayé le example suivant où le panoramique horizontal fonctionne parfaitement mais il y a certains problèmes que j'ai pu voir. Comme je veux limiter le panoramique par rapport aux données qui sont présentes dans une limite spécifique dans le graphique (ne veut pas pan horizontalement à l'infini) S'il vous plaît aidez-moi à travers cela. Y a-t-il des exemples de travail disponibles en ligne? Je vous remercie.Horizontal Panning D3.js

Code JS:

var data = [ 
     {"date":"2011-12-31","num":5}, 
     {"date":"2012-01-05","num":10}, 
     {"date":"2012-01-10","num":22}, 
     {"date":"2012-01-15","num":72}, 
     {"date":"2012-01-20","num":87}, 
     {"date":"2012-01-25","num":90} 
]; 


function draw(){ 

    var location = "#post" 
    var month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; 
    var graph_width = 500; 
    var graph_height = 200; 

    var values = _.pluck(data, 'num'); 
    var max_val = d3.max(values); 
    var v_scale = graph_height/max_val; 
    var data_counts = data.length; 
    var bar_width = graph_width/data_counts; 
    var minDate = new Date(data[0]["date"]); 
    var maxDate = new Date(data[data.length - 1]["date"]); 

    var y = d3.scale.linear() 
     .domain([0, max_val]) 
     .range([graph_height, 0]); 

    console.log(minDate); 
    var x = d3.time.scale().domain([minDate, maxDate]).range([0, graph_width]); 


    var chart = d3.select(location).append("svg") 
     .attr("class", "chart") 
     .attr("width", graph_width + 20) 
     .attr("height", graph_height + 20). 
     call(d3.behavior.zoom().x(x).scaleExtent([1, 8]).on("zoom", zoom)); 

    var lines = chart.selectAll("line"); 

    var lines_y = lines 
     .data(x.ticks(5)) 
     .enter().append("line") 
     .attr("x1", x) 
     .attr("x2", x) 
     .attr("y1", function(d) { 
     return graph_height - 20 - d;}) 
     .attr("y2", graph_height) 
     .style("stroke", "#ccc"); 

    var lines_x = lines 
     .data(y.ticks(10)) 
     .enter().append("line") 
     .attr("x1", 0) 
     .attr("x2", graph_width) 
     .attr("y1", y) 
     .attr("y2", y) 
     .style("stroke", "#ccc"); 

    xAxis = d3.svg.axis().scale(x); 
    yAxis = d3.svg.axis().scale(y).orient("left"); 

    chart.append("svg:g") 
     .attr("class", "xaxis") 
     .attr("transform", "translate(0,200)") 
     .call(xAxis); 

    chart.append("svg:g") 
     .attr("class", "yaxis") 
     .attr("transform", "translate(25,0)") 
     .call(yAxis); 

    var rect = chart.selectAll("rect") 
     .data(data).enter() 
     .append("rect") 
     .attr("x", function(d, i) {return x(new Date(d["date"])) + 20;}) 
     .attr("y", function(d, i) {return graph_height - (d["num"] * v_scale);}) 
     .attr("width", x(new Date(data[1]["date"]))) 
     .attr("height", function(d, i) {return d["num"] * v_scale;}); 

    function zoom() { 
     chart.select(".xaxis").call(xAxis); 
     chart.select(".yaxis").call(yAxis); 
     chart.selectAll(".chart rect").attr("transform", "translate(" + d3.event.translate[0] + ",0)scale(" + d3.event.scale + ", 1)"); 
    } 

    } 
draw(); 

Répondre

0

Pour limiter le panoramique, vérifiez simplement la valeur de la traduction avant de l'appliquer. Notez que la valeur de la translation sera l'inverse de la direction dans laquelle vous effectuez le panoramique. Autrement dit, si vous effectuez un panoramique dans la direction positive x, la valeur de traduction pour x sera négative.

Le code ressemblera à ceci.

function zoom() { 
    if(d3.event.translate[0] > -100) { 
     // translate 
    } 
} 

La valeur réelle (-100 ci-dessus) dépendra de ce que vous voulez réellement. Vous pouvez transmettre une valeur dans votre domaine d'entrée pour restreindre le panoramique à, par exemple, le bord du graphique.

+0

Ouais, merci cela a fonctionné comme charme avec quelques notions de base – Logan

1

Voici une solution polyvalente pour tous ceux qui en ont besoin. En regardant la plage plutôt que le domaine de l'échelle X, cela fonctionne aussi avec les axes date/heure.

var zoom = d3.behavior.zoom() 
    .scaleExtent([1,Infinity]) 
    .on("zoom", function() { 
     var t = zoom.translate(), 
      max = d3.max(x.range()), 
      tx = Math.max(Math.min(0, t[0]), width - max * zoom.scale()); 

     zoom.translate([ tx, t[1] ]); 

     draw(); 
    });