如何在d3js中创建基本列(垂直)图表?

时间:2012-12-24 19:12:00

标签: javascript d3.js

我正在尝试使用d3js,并且我的第一个基本列(垂直条)图表工作有问题。我发现有点难以理解的唯一事情是缩放事物。我想让x和y轴标记为标签,但我有以下问题:

首先,这是我的数据:

{
"regions":
["Federal","Tigray","Afar","Amhara","Oromia","Gambella","Addis Ababa","Dire Dawa","Harar","Benishangul-Gumuz","Somali","SNNPR "],
"institutions":
[0,0,34,421,738,0,218,22,22,109,0,456]
}
  1. 在y轴上,值存在,但顺序相反。这是代码:

    var y = d3.scale.linear()。domain([0,d3.max(data.institutions)])。range([0,height]);

  2. 然后我用这个比例来创建一个y轴:

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

    并将此轴添加到svg元素

    svgContainer.append("g")
            .attr("class", "y axis")
            .call(yAxis)
                .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text("Institutions");
    

    这里的问题是y轴从顶部的0开始,底部的700开始,但是它应该是相反的顺序。

    我有另一个问题x轴。我希望有一个序数比例,因为我想要放置的值在我上面的区域名称中。所以这就是我所做的。

    var x = d3.scale.ordinal()
                        .domain(data.regions.map(function(d) { return d.substring(0, 2); }))
                        .rangeRoundBands([0, width], .1);
    

    然后是轴

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

    最后将其添加到svg元素

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

    这里的问题是刻度线和标签出现但它们没有均匀间隔,并且与我正在绘制的矩形的中心不对应。这是完整的代码,您可以看到发生了什么。

    $(document).ready(function(){
    
        d3.json("institutions.json", draw);
    
    });
    
    function draw(data){
        var margin = {"top": 10, "right": 10, "bottom": 30, "left": 50}, width = 700, height = 300;
    
        var x = d3.scale.ordinal()
                        .domain(data.regions.map(function(d) { return d.substring(0, 2); }))
                        .rangeRoundBands([0, width], .1);
    
    
        var y = d3.scale.linear()
                  .domain([0, d3.max(data.institutions)])
                  .range([0, height]);
    
        var xAxis = d3.svg.axis()
                          .scale(x)
                          .orient("bottom");    
    
        var yAxis = d3.svg.axis()
                          .scale(y)
                          .orient("left");  
    
        var svgContainer = d3.select("div.container").append("svg")
                               .attr("class", "chart")
                               .attr("width", width + margin.left + margin.right)
                               .attr("height", height + margin.top + margin.bottom)
                              .append("g")
                                .attr("transform", "translate(" +margin.left+ "," +margin.right+ ")");        
    
        svgContainer.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate( 0," + height + ")")
                .call(xAxis);
    
        svgContainer.append("g")
                      .attr("class", "y axis")
                      .call(yAxis)
                    .append("text")
                      .attr("transform", "rotate(-90)")
                      .attr("y", 6)
                      .attr("dy", ".71em")
                      .style("text-anchor", "end")
                      .text("Institutions");
    
        svgContainer.selectAll(".bar")
          .data(data.institutions)
          .enter()
            .append("rect")
            .attr("class", "bar")
            .attr("x", function(d, i) {return i* 41;})
            .attr("y", function(d){return height - y(d);})
            .attr("width", x.rangeBand())
            .attr("height", function(d){return y(d);});
    
    }
    

1 个答案:

答案 0 :(得分:6)

我把代码放到了Fiddle:http://jsfiddle.net/GmhCr/4/

随意编辑它!我已经解决了这两个问题。


要修复倒置的y轴,只需交换范围函数参数的值:

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

如果更改比例,请不要忘记调整条形码!


条形和x轴之间不匹配的来源可以在这里找到:

var x = d3.scale.ordinal()
    .domain(data.regions.map(function(d) {
        return d.substring(0, 2);}))
    .rangeRoundBands([0, width], .1);

svgContainer.selectAll(".bar")
  .data(data.institutions)
  .enter()
    .append("rect")
    .attr("class", "bar")
    .attr("x", function(d, i) {return i* 41;})
    .attr("y", function(d){return height - y(d);})
    .attr("width", x.rangeBand())
    .attr("height", function(d){return y(d);});

您将rangeRoundBands的填充指定为0.1,但在计算条形的x和宽度值时忽略填充。例如,填充0:

是正确的
var x = d3.scale.ordinal()
    .domain(data.regions.map(function(d) {
        return d.substring(0, 2);}))
    .rangeRoundBands([0, width], 0);

svgContainer.selectAll(".bar").data(data.institutions).enter().append("rect")
    .attr("class", "bar")
    .attr("x", function(d, i) {
        return i * x.rangeBand();
    })
    .attr("y", function(d) {
        return y(d);
    })
    .attr("width", function(){
        return x.rangeBand();
    })
    .attr("height", function(d) {
        return height -y(d);
    });

填充确定为填充保留多少域。当使用700的宽度和0.1的填充时,精确的70个像素用于填充。这意味着您必须在每个条形的x值上添加70 / data [“regions”]。length像素,以便使用填充。