无法使D3 y轴和列沿x轴正确对齐

时间:2014-10-24 20:32:03

标签: javascript jquery html css d3.js

我正在研究的D3图表有几个问题:

  1. 我无法让y axis在页面上正确对齐。数字超过了最左边的边界,无法看到。

  2. 我希望条形图中使用的列在刻度线之间整齐排列,并在两侧均匀分布。

  3. 小提琴:http://jsfiddle.net/bf1gf8ep/8/

    D3.js

    var barWidth = 70;
    var width = (barWidth + 10) * 7;
    var height = 200;
    var data = [{"label" : "1/7yrs", "contract" : "111830.17", "annReturn" : "1.63%"},
                {"label" : "2/7yrs", "contract" : "115311.17", "annReturn" : "2.07%"},
                {"label" : "3/7yrs", "contract" : "118984.65", "annReturn" : "2.52%"},
                {"label" : "4/7yrs", "contract" : "122859.65", "annReturn" : "2.98%"},
                {"label" : "5/7yrs", "contract" : "126947.77", "annReturn" : "3.46%"},
                {"label" : "6/7yrs", "contract" : "131260.74", "annReturn" : "3.94%"},
                {"label" : "7/7yrs", "contract" : "135810.92", "annReturn" : "4.44%"}];
    
     var margin = { top: 20, right: 20, bottom: 20, left: 20 };
    
     var chart = d3.selectAll("body").append("svg:svg")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom + 20);
    
            var x = d3.scale.linear().domain([0, data.length]).range([0, width]);
            var y = d3.scale.linear().range([height, 0]);
    
            var xAxis = d3.svg.axis().scale(x).orient("bottom");
            var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5);
    
      chart.append("g")
           .attr("class", "axis").call(xAxis)
           .attr("transform", "translate(0," + (height) + ")");
    
      chart.append("g")
           .attr("class", "axis")
           .attr("transform", "translate(" + 10 + ",0)")
           .call(yAxis);
    
    
    x = d3.scale.linear().domain([0, data.length]).range([0, width]);
    y = d3.scale.linear().domain([0, 135810.92 + 1000]).range([height, 0]);
    
    chart.selectAll("rect")
        .data(data)
        .enter()
        .append("svg:rect")
        .attr("x", function (d, i) { return x(i); })
        .attr("y", function (d) { return y(d.contract); })
        .attr("height", function (d) { return height - y(d.contract); })
        .attr("width", barWidth)
        .attr("fill", "#2d578b");
    
    chart.selectAll("text.contractInfo")
        .data(data)
        .enter()
        .append("svg:text")
        .attr("x", function(d, i) { return x(i) + barWidth; })
        .attr("y", function(d) { return y(d.contract); })
        .attr("dx", -barWidth / 2)
        .attr("dy", "1.2em")
        .attr("text-anchor", "middle")
        .text(function(d) { return d.contract; })
        .attr("fill", "white")
        .attr("class", "contractInfo");
    
    chart.selectAll("text.yAxis")
        .data(data)
        .enter().append("svg:text")
        .attr("x", function (d, i) { return x(i) + barWidth; })
        .attr("y", height)
        .attr("dx", -barWidth / 2)
        .attr("dy", "15px")
        .attr("text-anchor", "middle")
        .attr("style", "font-size: 12; font-family; Helvetica, sans-serif")
        .text(function (d) { return d.label; })
        .attr("transform", "translate(0, 18)")
        .attr("class", "yAxis");
    

    屏幕截图

    enter image description here

1 个答案:

答案 0 :(得分:2)

您已完成所有艰苦工作,只需稍微使用保证金变量即可。你真正想做的是通过20pxmargin.left向右推杆,并将它们居中。 width变量已设置为barwidth + 10,因此您需要10px填充。要使其居中,您需要将一半填充添加到条带宽度。因此,在创建条形图时将它们放在一起需要添加margin.left和5,即:

.attr("x", function (d, i) { return x(i) + margin.left + 5; })

您还需要使用完全相同的代码移动文本。

还需要移动xAxis,再次添加margin.left值,如:

.attr("transform", "translate(" + margin.left + "," + (height) + ")");

我还注意到你硬编码了y scale max,所以我引入了ymax变量来计算最大值并修改y变量如下所示;

var ymax = d3.max(data, function(d) { return d.contract; });
var y = d3.scale.linear().domain([0, ymax]).range([height, 0]);

上述方法的替代方法是附加一个组元素以放置条形并通过margin变量转换该组。这样可以避免在条形几何中使用边距变量。

无论如何,我已经碰到了你的小提琴,里面包含here的更新