javascript - 对 d3 堆积条形图的数据进行排序

标签 javascript sorting d3.js

我正在尝试创建 d3 堆积条形图。数据格式如下

  var dataset = [{
    "effort": "initial",
        "co": [{
        "number": "123",
            "act_effort": 10
    },{
        "number": "456",
            "act_effort": 10
    }, {
        "number": "678",
            "act_effort": 0
    }]
    }, {
        "effort": "scope_creep",
           "co": [{
        "number": "456",
            "act_effort": 5
    }, {
        "number": "123",
            "act_effort": 0
    }, {
        "number": "678",
            "act_effort": 15
    }]
},{
    "effort": "qc_support",
           "co": [{
            "number": "456",
               "act_effort": 5
        },{
        "number": "678",
            "act_effort": 15
    }, {
        "number": "123",
            "act_effort": 5
    }]
    }, {
    "effort": "uat_support",
        "co": [{
        "number": "456",
            "act_effort": 0
    },  {
        "number": "678",
            "act_effort": 15
    },{
        "number": "123",
            "act_effort": 0
    }]
}];

由于数据未排序,我的堆叠栏中的条之间存在中断。

如果我将数据更改为下面的内容,它就可以工作

var dataset = [{
    "effort": "initial",
        "co": [{
        "number": "123",
            "act_effort": 10
    },{
        "number": "456",
            "act_effort": 10
    }, {
        "number": "678",
            "act_effort": 0
    }]
}, {
    "effort": "scope_creep",
        "co": [
            {
        "number": "123",
            "act_effort": 0
    },{
        "number": "456",
            "act_effort": 5
    }, {
        "number": "678",
            "act_effort": 15
    }]
},{
    "effort": "qc_support",
        "co": [{
        "number": "123",
            "act_effort": 5
    },{
        "number": "456",
            "act_effort": 5
    },{
        "number": "678",
            "act_effort": 15
    }]
},{
    "effort": "uat_support",
        "co": [{
        "number": "456",
            "act_effort": 0
    },  {
        "number": "678",
            "act_effort": 15
    },{
        "number": "123",
            "act_effort": 0
    }]
}];

这是工作的 jsfiddle

我尝试使用 d3.sort() 函数,但没有成功。

dataset = dataset.sort(function(a,b) { return d3.ascending(a.y, b.y);  }

有人可以建议我如何实现这一目标吗?提前致谢。

最佳答案

尝试如下所示对数据进行排序。

var dataset = dataset.map(function (d) {
    var sortedData = d.co.sort(function(a,b){ return d3.ascending(a.number, b.number); });
    return sortedData.map(function (o, i) {         
        return {
            y: o.act_effort,
            x: o.number
        };
    });
});

var dataset = [{
    "effort": "initial",
        "co": [{
        "number": "123",
            "act_effort": 10
    },{
        "number": "456",
            "act_effort": 10
    }, {
        "number": "678",
            "act_effort": 0
    }]
    }, {
        "effort": "scope_creep",
           "co": [{
        "number": "456",
            "act_effort": 5
    }, {
        "number": "123",
            "act_effort": 0
    }, {
        "number": "678",
            "act_effort": 15
    }]
},{
    "effort": "qc_support",
           "co": [{
            "number": "456",
               "act_effort": 5
        },{
        "number": "678",
            "act_effort": 15
    }, {
        "number": "123",
            "act_effort": 5
    }]
    }, {
    "effort": "uat_support",
        "co": [{
        "number": "456",
            "act_effort": 0
    },  {
        "number": "678",
            "act_effort": 15
    },{
        "number": "123",
            "act_effort": 0
    }]
}];

var margin = {
    top: 50,
    right: 30,
    bottom: 50,
    left: 50
},

lagendPanel = {
    width: 180
},
width = 960 - margin.left - margin.right - lagendPanel.width,
    height = 500 - margin.top - margin.bottom;
var barPadding = 2;

d3.select("#main")
    .append("h4")
    .text("CO v/s Actual Effort Graph");
var effortTyp = dataset.map(function (d) {
    return d.effort;
});
var dataset = dataset.map(function (d) {
    var sortedData = d.co.sort(function(a,b){ return d3.ascending(a.number, b.number); });
    return sortedData.map(function (o, i) {
        // Structure it so that your numeric
        // axis (the stacked amount) is y
        return {
            y: o.act_effort,
            x: o.number
        };
    });
});
console.log(dataset);
var stack = d3.layout.stack();

stack(dataset);

var dataset = dataset.map(function (group) {
    return group.map(function (d) {
        // Invert the x and y values, and y0 becomes x0
        return {
            x: d.y,
            y: d.x,
            x0: d.y0

        };

    });

});
console.log(dataset);
var svg = d3.select("#main")
    .append('svg')
    .attr("width", width + (2 * margin.left) + margin.right + lagendPanel.width)
    .attr('height', height + margin.top + margin.bottom)
    .append('g')
    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

var xMax = d3.max(dataset, function (group) {
    return d3.max(group, function (d) {
        return d.x + d.x0;
    });
});

var xScale = d3.scale.linear()
    .domain([0, xMax])
    .range([0, width]);

var numbers = "";

numbers = dataset[0].map(function (d) {
    console.log(d.y);
    return d.y;
});
var yScale = d3.scale.ordinal()
    .domain(numbers)
    .rangeRoundBands([0, height], .1);


//Axis

var xAxis = d3.svg.axis()
    .scale(xScale)
    .orient('bottom'),

    yAxis = d3.svg.axis()
        .scale(yScale)
        .orient('left'),

    colours = d3.scale.category10();

var groups = svg.selectAll('g')
    .data(dataset)
    .enter()
    .append('g')
    .style('fill', function (d, i) {
    return colours(i);
}),

    rects = groups.selectAll('rect')
        .data(function (d) {
        return d;
    })
        .enter()
        .append('rect')
        .attr('x', function (d) {
        return xScale(d.x0);

    })
        .attr('y', function (d, i) {
        return yScale(d.y);
    })
        .attr('height', function (d) {
        return yScale.rangeBand();
    })
        .attr('width', function (d) {
        return xScale(d.x);
    });

svg.append('g')
    .attr('class', 'axis')
    .attr('transform', 'translate(0,' + height + ')')
    .call(xAxis);

svg.append('g')
    .attr('class', 'axis')
    .call(yAxis);

svg.append('g')
    .attr('class', 'axis')
    .call(yAxis);

svg.append('rect')
    .attr('fill', 'yellow')
    .attr('width', 160)
    .attr('height', 30 * dataset.length)
    .attr('x', width + margin.left)
    .attr('y', 0);

effortTyp.forEach(function (s, i) {
    svg.append('text')
        .attr('fill', 'black')
        .attr('x', width + margin.left + 8)
        .attr('y', i * 24 + 24)
        .text(s);
    svg.append('rect')
        .attr('fill', colours(i))
        .attr('width', 60)
        .attr('height', 20)
        .attr('x', width + margin.left + 90)
        .attr('y', i * 24 + 6);
});
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<div id="main"></div>

关于javascript - 对 d3 堆积条形图的数据进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29339828/

相关文章:

jquery - 用于触摸设备的 D3 树中的拖放功能

javascript - 在 Rails 3 中使用 AJAX 删除记录

javascript - 选择选项时为图像指定类别

sorting - 为什么插入排序 O(n^2) 在排序小数组 ~ 7 元素时更好。与 Quick Sort 和 Merge Sort 等 O(nlogn) 排序算法相比?

c# - 使用 LINQ 自定义排序

php - MySQL 查询用数字排序

javascript - d3 中的圆环图

javascript - 如何在 docuSign 中签名完成后重定向到后面

javascript - 检查 WebSocket 服务器是否可用且不出错

javascript - 使用 d3 自定义气泡位置