D3.js将条形图分组绘制数据多次

时间:2015-12-03 10:17:08

标签: javascript json d3.js bar-chart

我正在尝试使用D3.js创建一个分组的条形图。我已经按照GitHub上D3维基中提供的示例进行操作,并且有一个半工作图。但是,似乎某个值的所有数据点都被绘制在同一位置。

我的数据外观是一个JSON数组,看起来像这样

[{"experiment":30385,"c":1,"ratio":0.022,"stdev":0.363,"median":0.032,"zscore":6.359},
{"experiment":30385,"c":2,"ratio":-0.02,"stdev":0.351,"median":-0.005,"zscore":-4.786},
{"experiment":30385,"c":3,"ratio":0.074,"stdev":0.339,"median":0.089,"zscore":29.036},
{"experiment":30385,"c":4,"ratio":-0.077,"stdev":0.361,"median":-0.065,"zscore":-25.704},
{"experiment":30385,"c":5,"ratio":-0.354,"stdev":0.569,"median":-0.223,"zscore":-145.625},
{"experiment":30385,"c":6,"ratio":-0.02,"stdev":0.352,"median":-0.007,"zscore":-2.545},
{"experiment":30385,"c":7,"ratio":0.018,"stdev":0.346,"median":0.036,"zscore":7.412},
{"experiment":30385,"c":8,"ratio":-0.11,"stdev":0.348,"median":-0.096,"zscore":-37.69},
{"experiment":30385,"c":9,"ratio":-0.012,"stdev":0.357,"median":0.008,"zscore":-4.394},
{"experiment":30385,"c":10,"ratio":-0.054,"stdev":0.366,"median":-0.036,"zscore":-14.158},
{"experiment":30385,"c":11,"ratio":-0.071,"stdev":0.344,"median":-0.044,"zscore":-21.4},
{"experiment":30385,"c":12,"ratio":-0.01,"stdev":0.352,"median":0.002,"zscore":-1.467},
{"experiment":30385,"c":13,"ratio":-0.03,"stdev":0.366,"median":-0.014,"zscore":-2.375},
{"experiment":30385,"c":14,"ratio":-0.039,"stdev":0.339,"median":-0.025,"zscore":-8.816},
{"experiment":30385,"c":15,"ratio":-0.02,"stdev":0.357,"median":0.0065,"zscore":-4.2},
{"experiment":30385,"c":16,"ratio":0.449,"stdev":0.439,"median":0.4215,"zscore":69.859},
{"experiment":30385,"c":17,"ratio":-0.028,"stdev":0.367,"median":-0.007,"zscore":-4.9},
{"experiment":30385,"c":18,"ratio":-0.071,"stdev":0.357,"median":-0.061,"zscore":-17.268},
{"experiment":30385,"c":19,"ratio":0.143,"stdev":0.356,"median":0.1415,"zscore":13.961},
{"experiment":30385,"c":20,"ratio":0.022,"stdev":0.349,"median":0.0405,"zscore":3.462},
{"experiment":30385,"c":21,"ratio":-0.076,"stdev":0.335,"median":-0.086,"zscore":-11.368},
{"experiment":30385,"c":22,"ratio":0.038,"stdev":0.355,"median":0.07,"zscore":3.152},
{"experiment":30385,"c":23,"ratio":0,"stdev":0,"median":0,"zscore":3.152},
{"experiment":30385,"c":24,"ratio":0,"stdev":0,"median":0,"zscore":3.152},
{"experiment":30384,"c":1,"ratio":-0.058,"stdev":0.403,"median":-0.042,"zscore":-14.154},
{"experiment":30384,"c":2,"ratio":-1.017,"stdev":0.418,"median":-0.982,"zscore":-360.857},
{"experiment":30384,"c":3,"ratio":-0.094,"stdev":0.417,"median":-0.074,"zscore":-30.964},
{"experiment":30384,"c":4,"ratio":-0.155,"stdev":0.397,"median":-0.157,"zscore":-54.593},
{"experiment":30384,"c":5,"ratio":-0.024,"stdev":0.381,"median":-0.001,"zscore":-8.125},
{"experiment":30384,"c":6,"ratio":0.013,"stdev":0.37,"median":0.0245,"zscore":7.455},
{"experiment":30384,"c":7,"ratio":-0.2,"stdev":0.434,"median":-0.171,"zscore":-56.706},
{"experiment":30384,"c":8,"ratio":-0.017,"stdev":0.367,"median":0.003,"zscore":-5.621},
{"experiment":30384,"c":9,"ratio":0.025,"stdev":0.365,"median":0.044,"zscore":6.818},
{"experiment":30384,"c":10,"ratio":-0.168,"stdev":0.422,"median":-0.121,"zscore":-44.158},
{"experiment":30384,"c":11,"ratio":-0.073,"stdev":0.382,"median":-0.056,"zscore":-22.067},
{"experiment":30384,"c":12,"ratio":0.002,"stdev":0.379,"median":0.019,"zscore":2.533},
{"experiment":30384,"c":13,"ratio":-0.054,"stdev":0.39,"median":-0.0295,"zscore":-8.375},
{"experiment":30384,"c":14,"ratio":0.019,"stdev":0.376,"median":0.025,"zscore":6.447},
{"experiment":30384,"c":15,"ratio":-0.054,"stdev":0.421,"median":-0.0265,"zscore":-11},
{"experiment":30384,"c":16,"ratio":0.055,"stdev":0.375,"median":0.0695,"zscore":8.297},
{"experiment":30384,"c":17,"ratio":0.024,"stdev":0.394,"median":0.054,"zscore":3.767},
{"experiment":30384,"c":18,"ratio":-0.049,"stdev":0.36,"median":-0.018,"zscore":-11.902},
{"experiment":30384,"c":19,"ratio":0.095,"stdev":0.37,"median":0.1135,"zscore":10.24},
{"experiment":30384,"c":20,"ratio":0.157,"stdev":0.343,"median":0.174,"zscore":29.423},
{"experiment":30384,"c":21,"ratio":-0.091,"stdev":0.407,"median":-0.067,"zscore":-14},
{"experiment":30384,"c":22,"ratio":0.071,"stdev":0.381,"median":0.104,"zscore":7.329},
{"experiment":30384,"c":23,"ratio":0,"stdev":0,"median":0,"zscore":7.329},
{"experiment":30384,"c":24,"ratio":0,"stdev":0,"median":0,"zscore":7.329}]

数据包含实验ID,染色体编号,比率和一些satistics。该数组可以包含来自各种实验的数据,这些数据都具有不同的ID。

我的js代码目前看起来像这样:

<script>
function unique(list) {
    var result = [];
    $.each(list, function(i, e) {
        if ($.inArray(e, result) == -1) result.push(e);
    });
    return result;
}

var margin = {top: 50, right: 50, bottom: 50, left: 50};
var width = 1000 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var threshold={upper:0.1,lower:-0.1};


var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);

var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom");

var yAxis = d3.svg.axis()
.scale(y)
.orient("left");

var svg = d3.select("#svg").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.json("{{settings.Base_url}}/templates/addons/data.json", function(error, data) {
    if (error) throw error;
    var expNames =unique(data.map(function(d) { return d.experiment; }));
    x0.domain(data.map(function(d) { return d.c; }));
    x1.domain(expNames).rangeRoundBands([0, x0.rangeBand()]);
    y.domain([-1.5,1.5]);

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

    svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", -50)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Average Ratio/Chromosome");

    var chr = svg.selectAll(".bar")
    .data(data)
    .enter().append("g")
    .attr("class", "bar")
    .attr("transform", function(d) { return "translate(" + x0(d.c) + ",0)"; });

    chr.selectAll("rect")
    .data(data)
    .enter().append("rect")
        .attr("x", function(d) {return x1(d.experiment);})
        .attr("y", function(d) { return y(Math.max(0, d.ratio)); })
        .attr("height", function(d) { return Math.abs(y(d.ratio)-y(0)); })
        .attr("width", x1.rangeBand())
        .style("fill", function(d) { return color(d.experiment); })
        .style({"opacity":0.6,"stroke-width":"2"})
        .text("test");


     var legend = svg.selectAll(".legend")
        .data(expNames.slice().reverse())
        .enter().append("g")
        .attr("class", "legend")
        .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

     legend.append("rect")
        .attr("x", width - 18)
        .attr("width", 18)
        .attr("height", 18)
        .style("fill", color);

     legend.append("text")
        .attr("x", width - 24)
        .attr("y", 9)
        .attr("dy", ".35em")
    .style("text-anchor", "end")
        .text(function(d) { return d; });

});

</script>

产生如下图:

graph

任何想法?我有一个大概的错误,但似乎无法找到解决方案。

1 个答案:

答案 0 :(得分:1)

请注意我是否正确理解了这个问题,但这是我得到的:

您将数据绑定到以x方向转换的组。

之后,您希望在每个组中显示两个小节(对于每个实验)(c值)

如果是这种情况,您不需要再次为条形图绑定数据,所以它只是:

var chr = svg.selectAll(".bar")
  .data(data)
  .enter().append("g")
  .attr("class", "bar")
  .attr("transform", function (d) {
    return "translate(" + x0(d.c) + ",0)";
 });

chr.append("rect")
  .attr("x", function (d) {
    return x1(d.experiment);
})
...etc

See fiddle

这有帮助吗?