javascript - 如何在 d3js 中制作基本柱形(垂直)图表?

标签 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]);

然后我使用这个比例来创建一个 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);});

}

最佳答案

我把代码放到 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 个像素用于填充。这意味着您必须将 70/data["regions"].length 像素添加到每个条形的 x 值才能使其与填充一起使用。

关于javascript - 如何在 d3js 中制作基本柱形(垂直)图表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14024930/

相关文章:

javascript - 如何创建一个正则表达式来选择不以 '#' 或 '.' 开头的单词

javascript - 如何使用 Php 在 php 中附加 Json 文件

javascript - 如何实现 D3 比例尺让 child 从 parent 那里继承颜色?

javascript - 如何让数据显示在我的图表中?

javascript - 当结果为整数时打印 ".00"?

javascript - jQuery SlideDown 在新附加的 div 上

javascript - Threejs 移除之前渲染的场景

javascript - polymer 和D3 : How to send JSON from element attribute to template

javascript - 在 nvd3 结构中使用 d3 和 json 的多折线图

javascript - 单堆叠条形图数据设置?