2012-08-02 155 views
7

我試圖在D3.js中繪製我們客戶的平均生存期。我有數據繪製出來,但我無法弄清楚如何繪製顯示中值壽命的參考線。我想要垂直和水平參考線與我的數據相交於y軸的50%值。折線圖的參考線

這是我目前有: median lifetime

垂直基準線需要交叉在同一地點爲水平基準線數據。

這裏是我的代碼:

d3.json('data.json', function(billingData) { 
    var paying = billingData.paying; 
    var w = 800; 
    var h = 600; 
    var secondsInInterval = 604800000; // Seconds in a week 

    var padding = 50; 

    var age = function(beginDate, secondsInInterval) { 
     // Calculate how old a subscription is given it's begin date 

     var diff = new Date() - new Date(beginDate); 
     return Math.floor(diff/secondsInInterval); 
    } 

    var maxAge = d3.max(paying, function(d) { return age(d.subscription.activated_at, secondsInInterval); }); 

    var breakdown = new Array(maxAge); 

    $.each(paying, function(i,d) { 
     d.age = age(d.subscription.activated_at, secondsInInterval); 
     for(var i = 0; i <= d.age; i++) { 
      if (typeof breakdown[i] == 'undefined') breakdown[i] = 0; 
      breakdown[i]++; 
     } 
    }); 

    // Scales 
    var xScale = d3.scale.linear().domain([0, maxAge]).range([padding,w-padding]); 
    var yScale = d3.scale.linear().domain([0, 1]).range([h-padding,padding]); 

    // Axes 
    var xAxis = d3.svg.axis().scale(xScale).tickSize(6,3).orient('bottom'); 
    var yAxis = d3.svg.axis().scale(yScale).tickSize(6,3).tickFormat(d3.format('%')).orient('left'); 

    var graph = d3.select('body').append('svg:svg') 
      .attr('width', 800) 
      .attr('height', 600); 

    var line = graph.selectAll('path.line') 
      .data([breakdown]) 
      .enter() 
      .append('svg:path') 
      .attr('fill', 'none') 
      .attr('stroke', 'blue') 
      .attr('stroke-width', '1') 
      .attr("d", d3.svg.line() 
      .x(function(d,i) { 
       return xScale(i); 
      }) 
      .y(function(d,i) { 
       return yScale(d/paying.length); 
      }) 
    ); 

    var xMedian = graph.selectAll('path.median.x') 
      .data([[[maxAge/2,0], [maxAge/2,1]]]) 
      .enter() 
      .append('svg:path') 
      .attr('class', 'median x') 
      .attr("d", d3.svg.line() 
      .x(function(d,i) { 
       return xScale(d[0]); 
      }) 
      .y(function(d,i) { 
       return yScale(d[1]); 
      }) 
    ); 

    var yMedian = graph.selectAll('path.median.y') 
      .data([[[0,.5], [maxAge,0.5]]]) 
      .enter() 
      .append('svg:path') 
      .attr('class', 'median y') 
      .attr("d", d3.svg.line() 
      .x(function(d,i) { 
       return xScale(d[0]); 
      }) 
      .y(function(d,i) { 
       return yScale(d[1]); 
      }) 
    ); 

    graph.append('g').attr('class', 'x-axis').call(xAxis).attr('transform', 'translate(0,' + (h - padding) + ')') 
    graph.append('g').attr('class', 'y-axis').call(yAxis).attr('transform', 'translate(' + padding + ',0)'); 
    graph.append('text').attr('class', 'y-label').attr('text-anchor', 'middle').text('customers').attr('transform', 'translate(10,' + (h/2) + '), rotate(-90)'); 
    graph.append('text').attr('class', 'x-label').attr('text-anchor', 'middle').text('lifetime (weeks)').attr('transform', 'translate(' + (w/2) + ',' + (h - padding + 40) + ')'); 
}); 

回答

4

您需要的搜索中,客戶在你的線(約7周)爲50%的點,就是這樣,搜索索引i其中breakdown[i]/paying.length接近0.5,保存該索引爲indexMedianCustomers(例如)並修改您的代碼

var xMedian = graph.selectAll('path.median.x') 
     .data([[[indexMedianCustomers,0], [indexMedianCustomers,1]]]) 
     .enter() 
     .append('svg:path') 
     .attr('class', 'median x') 
     .attr("d", d3.svg.line() 
     .x(function(d,i) { 
      return xScale(d[0]); 
     }) 
     .y(function(d,i) { 
      return yScale(d[1]); 
     }) 
);