2013-10-21 88 views
0

Here是的jsfiddleD3JS条形图:如何允许重复的x轴标签值?

请看功能drawBarchart();

注:在我的例子中,当外部数据值被重命名并提出独特的全4条显示,但省略当值是一样的,我知道这是预期的行为,但我必须允许重复values.Please帮助..

代码:

$(document).ready(function(){ 
    var dataArray = [ 
       { 
        "xData" : "Repeat", 
        "yData" : 38 
       }, 
       { 
        "xData" : "Unique", 
        "yData" : 27 
       }, 
       { 
        "xData" : "Repeat", 
        "yData" : 27 
       }, 
       { 
        "xData" : "Repeat", 
        "yData" : 29 
       } ]; 
drawBarchart("graph",dataArray,"count",700,400); 
} 
); 


function drawBarchart(containerId, dataArray, yAxisText, chartAreaWidth, 
     chartAreaHeight) { 
    var margin = { 
     top : 20, 
     right : 20, 
     bottom : 30, 
     left : 40 
    }, width = chartAreaWidth - margin.left - margin.right, height = chartAreaHeight 
      - margin.top - margin.bottom; 

    var formatPercent = d3.format(".0%"); 

    var x = d3.scale.ordinal().rangeRoundBands([ 0, width ], .1); 

    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").tickFormat(formatPercent); 
    var yAxis = d3.svg.axis().scale(y).orient("left"); 

    var svg = d3.select("#" + containerId).append("svg").attr("width", 
      width + margin.left + margin.right).attr("height", 
      height + margin.top + margin.bottom).append("g").attr("transform", 
      "translate(" + margin.left + "," + margin.top + ")"); 

    x.domain(dataArray.map(function(d) { 
     return d.xData; 
    })); 
    y.domain([ 0, d3.max(dataArray, function(d) { 
     return d.yData; 
    }) ]); 

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

    svg.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(yAxisText); 

    svg.selectAll(".bar").data(dataArray).enter().append("rect") 
      .attr("class", "bar").attr("x", function(d) { 
       return x(d.xData); 
      }).attr("width", x.rangeBand()).attr("y", function(d) { 
       return y(d.yData); 
      }).attr("height", function(d) { 
       return height - y(d.yData); 
      }); 

    function type(d) { 
     d.yData = +d.yData; 
     return d; 
    } 
}  

回答

1

您可以通过不使用x轴的规模做到这一点。比例点是将输入值映射到输出,即相同的输入会给你相同的输出。鉴于这不是你想要的这种情况,你不需要一个规模。

可以计算基于所述数据内的索引的每个杆的位置:

.attr("x", function(d, i) { 
    return i * width/dataArray.length; 
}) 

每个条的宽度可以以类似的方式来计算。文字标签的相同之处,您必须手动添加。完成jsfiddle here

+0

太棒了!非常感谢您的回答,但是现在第一个栏与y轴重叠,并且x轴的勾号也被删除,进一步的帮助将不胜感激:) – Lord

+0

您可以通过调整x位置来移动栏位,如上所述。您还必须手动绘制刻度线,即在适当的位置生成线段。 –

+0

感谢您的帮助:) 虽然我设法改变了第一个bar.i m仍然坚持绘制X轴和X轴刻度。 所以我现在没有他们,以后再试。 – Lord

0

您必须在一个比例上使用唯一值,因为它会“映射”这些值。不过,我们将修改滴答的文本,并让图表显示它具有重复的值。

添加的x缩放比例定义以上下述(VAR X = ...):

// Rewrite xData and prepend index -> xData: "Repeat0" 
dataArray = dataArray.map(function(d,i){d.xData = d.xData +i; return d}); 

// Remove the index from the ticks -> xData: "Repeat0" -> "Repeat" 
var adjustTicks = function(){ 
    var xaxisgroup = this.node(); 
    var ticks = xaxisgroup.children; 
    for (var i = 0; i < ticks.length; i++) { 
     if(ticks[i].localName == 'path'){continue; } 

     var tick_text = d3.select(ticks[i].children[1]); 
     tick_text.text(tick_text.text().substring(0, tick_text.text().length - 1)) 

    }; 
} 

然后,. 当你实际绘制规模调用调用方法传递adjustTicks作为参数,就像这样:

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

它能做什么是使用唯一的值来创建规模,但替代刻度上的文本,似乎重复值正在使用。