d3 仅显示条形图中带有数据的刻度标签

d3 show labels only for ticks with data in a bar chart

首先,我是 D3 的新手。 :) 我有一个堆积条形图。我的 y 轴是一个序数刻度(状态)。 在我的数据中,我可以有一些滴答声 total=0。所以,我只想在总数 > 0 时查看标签,但保留数据的所有刻度。

var data = [{ "state":"A", "total":"10"},
{ "state":"B", "total":"0"},
{ "state":"C", "total":"0"},
{ "state":"D", "total":"20"},
{ "state":"E", "total":"0"},
{ "state":"F", "total":"50"}]

我试过这段代码,但是它删除了所有总计 = 0 的刻度。我只想删除那个刻度的标签。

yAxis.tickValues(dataSet.map( function(d,i) 
    { 
        if (d.total > 0)
            return d.state; 
        else
            if(i % 4 === 0 ) return d.state; 
    })
    .filter(function (d) 
    { return !!d; } )); 

谢谢, 菲利普

更新 这是代码:

    <!DOCTYPE html>

    <html xmlns="http://www.w3.org/1999/xhtml" class="ocks-org do-not-copy">
    <head>
      <link rel="stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
    <div id="timeLine"></div>
    <!--style>

    svg {
            font: 10px sans-serif;
        }

    path {
        fill: steelblue;
    }

    .axis path,
    .axis line {
        fill: none;
        stroke: #000;
        shape-rendering: crispEdges;
    }
</style-->
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var timeline;
var labels;


    var margin = {
        top : 20,
        right : 10,
        bottom : 60,
        left : 80
    },
    width = 500 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

    var x = d3.scale.linear()
        .rangeRound([0, width]);

        var y = d3.scale.ordinal()
        .rangeBands([height, 0], 0.1);

    var color = d3.scale.ordinal()
        .range(["#1f77b4", "#2ca02c", "#E53524"]);
    //var color = d3.scale.category10()

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom")
        .tickFormat(d3.format(".2s"))
        .ticks(10);

    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left")
        .ticks(5);

    timeline = d3.select("#timeLine").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 + ")")

    var dataSet;
    var all_nodes_t;
    var all_updates_t;
    var test;
    var entity = "ALL";

    dataSet = [
    { "Date":"2014-01", "insert":"27", "remove":"17","updates":"427"},
    { "Date":"2014-02", "insert":"27", "remove":"17","updates":"427"},
    { "Date":"2014-03", "insert":"27", "remove":"17","updates":"427"},
    { "Date":"2014-04", "insert":"0", "remove":"0","updates":"0"},
    { "Date":"2014-05", "insert":"27", "remove":"17","updates":"427"},
    ];
        color.domain(d3.keys(dataSet[0]).filter(function (key) {
            return key !== "Date";
        }));

    dataSet.forEach(function (d) {
        var x0 = 0;
        d.ages = color.domain().map(function (name) {
                return {
                    name : name,
                    x0 : x0,
                    x1 : x0 += +d[name]
                };
            });
        d.total = d.ages[d.ages.length - 1].x1;
    });

    //HERE
    yAxis.tickFormat(dataSet.map(function(d) { 
        d.total == 0 ? "" : d.Date; 
    }));

    y.domain(dataSet.map(function (d) {
        return d.Date;
    }));

    x.domain([0, d3.max(dataSet, function (d) {
        return (d.total + 5);
    })]);

    timeline.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis)
    .append("text")
    .attr("x", 1)
    .attr("dx", "42em")
    .attr("dy", "3em")
    .style("text-anchor", "end")
    .text("Operations");

    timeline.append("g")
    .attr("class", "y axis")
    .call(yAxis);

    var layer = timeline.selectAll(".state")
        .data(dataSet)
        .enter().append("g")
        .attr("class", "rect")
        .attr("transform", function (d) {
            return "translate(0," + y(d.Date) + ")";
        });

    var rect = layer.selectAll("rect")
        .data(function (d) {
            return d.ages;
        })
        .enter().append("rect")
        .attr("class", "rect")
        .attr("width", 0)
        .attr("x", width)
        .attr('y', function (d, i) {
                return y(d.Date);
            })
        .attr("height", y.rangeBand())
        .style("fill", function (d) {
            return color(d.name);
        });

    rect.transition()
    .duration(600)
    .delay(function (d, i) {
        return i * 300;
    })
    .attr("width", function (d) {
        return x(d.x1) - x(d.x0);
    })
    .attr("x", function (d) {
        return x(d.x0);
    });

</script>
</body>
</html>

您可以使用 .tickFormat() 来隐藏那些特定值的标签。由于您要检查的内容不是秤可用数据的一部分,因此您需要在整个数据中找到它:

yAxis.tickFormat(function(d) {
    var val = 0;
    dataSet.forEach(function(item) {
        if(item.Date == d) val = item.total;
    });
    return val == 0 ? "" : d;
});

如果总计为 0 或在数据集中找不到该值,这将抑制标签 (return "")。完成演示 here.