2017-01-11 45 views
0

我是新来的d3.js,但我还不明白为什么我的X轴线放在顶部而不是底部(请图像波纹管)。如何在d3.js中从上到下更改X轴线

enter image description here

这里是我正在使用的代码(简化,以减少代码量):

var data = []; 
var days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; 
for(var i = 0; i<7; i++){ 
    data.push({"letter":i,"frequency":Math.random(), "day":days[i]}) 
} 



var svg = d3.select("#graph1"), 
    margin = {top: 80, right: 20, bottom: 100, left: 100}, 
    width = +svg.attr("width") - margin.left - margin.right, 
    height = +svg.attr("height") - margin.top - margin.bottom; 


var x = d3.scaleLinear().rangeRound([0, width]), 
    y = d3.scaleBand().rangeRound([0, height]); 

var g = svg.append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 


    x.domain([0,1]); 
    y.domain(data.map(function(d) { return d.day; })); 

    g.append("g") 
     .attr("class", "axis axis--x") 
     .attr("transform", "translate(0," + height + ")") 
     .call(d3.axisBottom(x).ticks(5, "%")); 

    g.append("g") 
     .attr("class", "axis axis--y") 
     .call(d3.axisLeft(y)) 
     .append("text") 
     .attr("transform", "rotate(-90)") 
     //.attr("y", 6) 
     //.attr("dy", "0.71em") 
     //.attr("text-anchor", "end"); 



     //setup the tool 

    g.append("g")   
    .attr("class", "grid") 
    /*.attr("transform", "translate("+margin.left+"," + margin.top + ")")*/ 
    .call(d3.axisBottom(x) 
     .ticks(5) 
     .tickSize(height) 
     .tickFormat("") 
     ); 



var thickness = 14; 
g.selectAll(".bar") 
    .data(data) 
    .enter().append("rect") 
    .attr("class", "bar") 
    .attr("x", 0) 
    .attr("y", function(d) { return y(d.day) + thickness/2 ;}) 
    .attr("width", function(d) { return x(d.frequency);}) 
    .attr("height", thickness); 

回答

2

对不起,我误解了你的问题。问题是d3轴会自动创建连接外部2个刻度和轴线的路径。在你的情况下,你已经使用d3轴创建你的网格。我假设这条路线覆盖了底部的轴线。为了检查这种情况,我建议使用浏览器的开发工具检查DOM。

不管怎样,问题是,不是使用d3轴来创建网格,而应该为每个网格线创建一个路径。你创建网格的方式是一种黑客攻击,这就是为什么你在顶部看到一条线。因此,我将摆脱:

g.append("g")   
    .attr("class", "grid") 
    .call(d3.axisBottom(x) 
     .ticks(5) 
     .tickSize(height) 
     .tickFormat("")); 

为以下几点:

var grid = g.append("g").attr("class","grid"); 
grid.selectAll("path") 
    .data(x.ticks(5)) 
    .enter().append("path") 
    .attr("d", function(d) {return "M"+x(d)+",0v"+height;}); 

快速的解释

此例如创建刻度值的数组[0,20,40,...]:

x.ticks(5) 

的代码的其余部分被附加一个路径.grid组用于每个刻度值,然后终于此代码定义路径的形状作为垂直线从顶部开始并向下到图表的底部。

.attr("d", function(d) {return "M"+x(d)+",0v"+height;}) 
+0

我不相信他的网格在顶部生产线。在他的代码中,他只使用一个x轴作为长度为“高度”的网格。那只会产生你在他的情节中看到的垂直网格元素。虽然使用轴有点破解,但实际上它是一种非常好的方法来实现网格,因为它们非常易于缩放并在实现缩放和平移控制时可以工作,因为您可以使用'd3.event.transform '。即使迈克博斯托克经常使用这种方法来绘制网格。 – HamsterHuey

+0

我刚刚运行了代码,网格部分在顶部创建了一条线。我确信Bostock会这么做,所以在轴的末端的支架形状的路径显示在实际轴的下面。当您使用.call(轴)时,它会创建4个元素,括号形状的路径,每个滴答的组,每个滴答的文本。 –

+0

为了跟进,您会注意到附加图像中的网格线与@Hangon试图摆脱的线条具有相同的灰色。 –

0

你确定顶部的线实际上是从x轴?它看起来像我的X轴的路径被禁用(可能通过CSS - 如果您从其他示例中复制粘贴,很多人会禁用其图表中的轴路径)。唯一的神秘之处在于上面的灰线来自...也许一些CSS样式的svg元素?如果您仍然无法解决问题,发布JSFiddle或plunker会很有用。