简体   繁体   English

D3JS Barchart:如何允许重复的x轴标签值?

[英]D3JS Barchart : How to allow repeated x-axis label values?

Here is the JSFiddle 是JSFiddle

please look at the function drawBarchart(); 请看一下函数drawBarchart();

Note: in my example when xData values are renamed and made unique all 4 bars are shown, but omitted when values are same, i know this is expected behavior but i have to allow repeated values.Please help.. 注意:在我的示例中,当xData值被重命名并使其唯一时,所有4条都显示出来,但是当值相同时被省略,我知道这是预期的行为,但是我必须允许重复的值。请帮助..

code: 码:

$(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;
    }
}    

You can do this by not using a scale for the x axis. 您可以通过不为x轴使用刻度来做到这一点。 The point of a scale is to map input values to outputs, ie the same inputs will give you the same outputs. 比例尺的重点是将输入值映射到输出,即相同的输入将为您提供相同的输出。 Given that this is not what you want in this case, you don't need a scale. 鉴于在这种情况下这不是您想要的,因此不需要刻度。

You can calculate the position of each bar based on the index within the data: 您可以根据数据中的索引计算每个条形的位置:

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

The width of each bar can be calculated in a similar fashion. 每个条的宽度可以类似的方式计算。 Same thing for the text labels, which you have to add manually. 对于文本标签,您必须手动添加。 Complete jsfiddle here . 在此处完成jsfiddle。

You MUST use unique values on an scale because it will "map" those values. 您必须在比例尺上使用唯一值,因为它将“映射”这些值。 Nevertheless we will modify the text on the ticks and make your graph to appear that it has repeated values. 不过,我们将修改刻度线上的文本,并使您的图形显示其具有重复的值。

add the following above the x scale definition(var x =...) : 在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))

   };
}

Then,. 然后,。 when you are actually drawing the scale invoke the call method passing adjustTicks as argument, like this : 当您实际绘制比例时,调用调用方法,将AdjustTicks作为参数传递,如下所示:

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

What it does is create a scale using unique values but replaces the text on the scale so it appears that repeated values are being used. 它的作用是使用唯一值创建刻度,但替换刻度上的文本,因此似乎正在使用重复的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM