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.lengthindexMedianCustomers

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 回答