3

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で始まることです。これは問題ありませんが、逆の順序である必要があります。

もう1つの問題は、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);});

}
4

1 に答える 1

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値とwidth値を計算するときにパディングを無視します。たとえば、これは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ピクセルを追加する必要があります。

于 2012-12-24T21:32:52.833 に答える