7

D3.js で顧客の寿命の中央値をグラフ化しようとしています。データをグラフ化しましたが、寿命の中央値を示す参照線を引く方法がわかりません。Y 軸の 50% の値でデータと交差する垂直および水平の基準線が必要です。

これが私が現在持っているものです: 寿命の中央値

垂直基準線は、水平基準線と同じ場所でデータと交差する必要があります。

これが私のコードです:

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

1 に答える 1

4

ラインで顧客が 50% になるポイント (約 7 週間) を検索する必要があります。それだけです。0.5 に近いインデックスを検索し、iそのbreakdown[i]/paying.lengthインデックスを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]);
        })
);
于 2012-08-02T20:33:03.233 に答える