我正在尝试绘制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) + ')');
});

最佳答案

您需要搜索行中有50%客户的点(大约7周),就是这样,搜索i接近0.5的索引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]);
        })
);

关于d3.js - 折线图的引用线,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11785086/

10-12 20:11