javascript - d3js 条形图 : can two bars represent two different categories/variables?

标签 javascript d3.js bar-chart

我的数据看起来像这样:

var data = {

     { name: Andrew,
       date: 12/08/07,
       alpha: 1.2,
       beta: 3.4
     },
     { name: Fred,
       date: 14/12/06,
       alpha: 1.7,
       beta: 2.8
     }
};

我想要一个在 x 轴上带有名称的条形图,每个名称都有两个条:一个用于 alpha,一个用于 beta。我遇到的所有示例都在类别/格式中对条进行了分组(例如,所有条代表日期等),这就是为什么他们的解决方案没有多大帮助。我已经走到这一步了:

var x0 = d3.scale.ordinal()
            .rangeRoundBands([0, width], 0.2);

    var x1 = d3.scale.ordinal();

    var y = d3.scale.linear()
         .range([height, 0]);

    var color = d3.scale.ordinal()
            .range([ "#6b486b", "#ff8c00"]);

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

    var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left")
            .tickFormat(d3.format(".2s"));

    var svg = d3.select("#punchcard").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 + ")");

    var ageNames = ["Alpha", "Beta"];

    x0.domain(patient_names);
    x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()], 0);
    console.log(patientList);


    console.log(data);

    var alpha_max = d3.max(data, function(d) {return parseFloat(d.alpha); });
    var beta_max = d3.max(data, function(d) { return parseFloat(d.beta); });

    console.log(alpha_max);
    console.log(beta_max);
    var y_domain = [ alpha_max, beta_max];

    y.domain([0, parseFloat(d3.max(y_domain))+0.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", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end");

    svg.selectAll("bars")
        .data(data)
        .enter().append("rect")
        .attr("transform", function(d) { return "translate(" + x0(d.name)+",0)";})
        .style("fill", "#ff8c00")
        .attr("x", function(d) { return x1(d.alpha); })
        .attr("width", x1.rangeBand())      
        .attr("y", function(d) { return y(d.alpha); })
        .attr("height", function(d) { return height - y(d.alpha); });

    svg.selectAll("bars")
        .data(data)
        .enter().append("rect")
        .style("fill", "#6b486b")
        .attr("transform", function(d) { return "translate(" + x0(d.name)+",0)";})
        .attr("x", function(d) { return x1(d.beta); })
        .attr("width", x1.rangeBand())      
        .attr("y", function(d) { return y(d.beta); })
        .attr("height", function(d) { return height - y(d.beta); });


var legend = svg.selectAll(".legend")
      .data(ageNames.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; });

这段代码堆叠了 alpha 和 beta 条,而不是彼此相邻。我花了几个小时查看各种示例,但仍然无法找到执行此操作的方法。

提前致谢!

最佳答案

您可以通过在第二个数据连接中使用映射函数来创建嵌套数组数据结构,每个变量都有一个对象。

首先将组连接到数据对象数组,然后使用嵌套数据连接中的函数为每个组动态创建子数组:

var propertyNames = ["Alpha", "Beta"];

var groups = plottingArea.selectAll("g.groups")
                .data(data);

/* and handle the enter selection, classes, etc */

var bars = groups.selectAll("rect.bars")
                .data( function(d) {
                   //the `d` value is the data object for the *group*
                   //this function needs to return an array of data objects
                   //representing each bar in the group

                   return propertyNames.map( function(property){
                      //to get one bar for each variable, start with the
                      //array of variable names, and use a map function
                      //to create data objects for each:

                      return { type: property,
                               value: d[property],
                               name: d.name,
                               date: d.date
                             };

                   });

                });

其余代码应遵循标准 grouped bar chart结构。您创建的内部数据对象应包含正确定位每个条形并为其着色所需的所有数据。

关于javascript - d3js 条形图 : can two bars represent two different categories/variables?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22717812/

相关文章:

javascript - WinJS 在导航时保留元素 ID

php - 将 D3.js 与 symfony2 一起使用

javascript - 一般更新模式,在新文件上传时旧的不会删除

java - java中的条形图

javascript - 无法在处理程序中获取 Dojo 文本框值

javascript - Dojo 拖放 : how to retrieve order of items?

javascript - 如何制作Grails richui g :autocomplete field mandatory

javascript - 将标记旋转为多彩圆圈

r - R 中的双向条形图

python - Pandas 按类别绘制数据框条形图和颜色