2013-04-08 109 views
1

我是D3新手,我實際上正在嘗試水平平移選項的條形圖。我嘗試過以下example,其中水平平移完美,但我可以看到某些問題。因爲我想限制關於圖中特定邊界內存在的數據的平移(不想平移到無窮大)請幫助我完成此操作。網上有沒有可用的實例?謝謝。水平平移D3.js

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(); 

回答

0

要限制平移,在應​​用之前簡單地檢查翻譯的價值。請注意,平移值將與您正在平移的方向相反。也就是說,如果您以正向x方向平移,則x的平移值將爲負值。

代碼看起來像這樣。

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

上面的實際值(-100)將取決於您實際需要的值。您可能想要在輸入網域中傳遞值以限制平移到圖的邊緣。

+0

是的,謝謝,像一些基本的數學的魅力工作 – Logan 2013-04-10 06:12:11

1

以下是針對任何需要它的人的通用解決方案。通過查看X範圍的範圍而不是X範圍的域,它也可以使用日期/時間軸。

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(); 
    });