2012-08-02 22 views
7

Sto provando a rappresentare graficamente la durata media dei nostri clienti in D3.js. Ho i dati tracciati, ma non riesco a capire come disegnare le linee di riferimento che mostrano la durata media. Voglio linee di riferimento verticali e orizzontali che intersecano i miei dati al valore del 50% dell'asse y.Linea di riferimento per il grafico lineare

Ecco quello che ho attualmente: median lifetime

La linea verticale di riferimento deve intersecare i dati nello stesso luogo, come la linea di riferimento orizzontale.

Ecco il mio codice:

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) + ')'); 
}); 

risposta

4

È necessario cercare il punto in cui i clienti sono il 50% in linea (circa 7 settimane), il gioco è fatto, cercare l'indice i dove breakdown[i]/paying.length è vicino a 0.5, salvo tale indice come indexMedianCustomers (ad esempio) e modificare il codice in

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]); 
     }) 
); 
Problemi correlati