无法将文字添加到d3水平条

时间:2017-01-10 01:23:11

标签: javascript d3.js svg

我使用以下水平条形图(http://bl.ocks.org/juan-cb/ab9a30d0e2ace0d2dc8c),根据某些选项进行更新。我试图在条形图上添加标签,这些条形图会显示每个条形图内的值。不知道我哪里出错了。我最初有SVG rect元素,我将其归入" g"元素并试过这种方式,但仍然没有运气。任何帮助将不胜感激!

JsFiddle - https://jsfiddle.net/b772s5mg/3/

JS

  datasetTotal = [
        {label:"Category 1", value:19},
        {label:"Category 2", value:5},
        {label:"Category 3", value:13},
        {label:"Category 4", value:17},
        {label:"Category 5", value:21},
        {label:"Category 6", value:25}
    ];

    datasetOption1 = [
        {label:"Category 1", value:22},
        {label:"Category 2", value:33},
        {label:"Category 3", value:4},
        {label:"Category 4", value:15},
        {label:"Category 5", value:36},
        {label:"Category 6", value:0}
    ];

    datasetOption2 = [
        {label:"Category 1", value:10},
        {label:"Category 2", value:20},
        {label:"Category 3", value:30},
        {label:"Category 4", value:5},
        {label:"Category 5", value:12},
        {label:"Category 6", value:23}
    ];

    d3.selectAll("input").on("change", selectDataset);

    function selectDataset()
    {
        var value = this.value;
        if (value == "total")
        {
            change(datasetTotal);
        }
        else if (value == "option1")
        {
            change(datasetOption1);
        }
        else if (value == "option2")
        {
            change(datasetOption2);
        }
    }

    var margin = {top: (parseInt(d3.select('body').style('height'), 10)/20), right: (parseInt(d3.select('body').style('width'), 10)/20), bottom: (parseInt(d3.select('body').style('height'), 10)/20), left: (parseInt(d3.select('body').style('width'), 10)/5)},
            width = parseInt(d3.select('body').style('width'), 10) - margin.left - margin.right,
            height = parseInt(d3.select('body').style('height'), 10) - margin.top - margin.bottom;

    var div = d3.select("body").append("div").attr("class", "toolTip");

    var formatPercent = d3.format("");

    var y = d3.scale.ordinal()
            .rangeRoundBands([height, 0], .2, 0.5);

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

    var xAxis = d3.svg.axis()
            .scale(x)
            .tickSize(-height)
            .orient("bottom");

    var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left");
    //.tickFormat(formatPercent);

    var svg = d3.select("body").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 + ")");

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

    d3.select("input[value=\"total\"]").property("checked", true);
    change(datasetTotal);

    function change(dataset) {

        y.domain(dataset.map(function(d) { return d.label; }));
        x.domain([0, d3.max(dataset, function(d) { return d.value; })]);

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

        svg.select(".y.axis").remove();
        svg.select(".x.axis").remove();

        svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                .attr("transform", "rotate(0)")
                .attr("x", 50)
                .attr("dx", ".1em")
                .style("text-anchor", "end")
                .text("Option %");


        var bar = svg.selectAll(".bar")
                .data(dataset, function(d) { return d.label; })
        // new data:
        .enter().append("g").append("rect")
                .attr("class", "bar")
                .attr("x", function(d) { return x(d.value); })
                .attr("y", function(d) { return y(d.label); })
                .attr("width", function(d) { return width-x(d.value); })
                .attr("height", y.rangeBand());

                bar.append("text")
    .attr("x", function(d) { return x(d) - 3; })
    .attr("y", 30)
    .attr("dy", ".35em")
    .text(function(d) { return d.value; });


        var bars = d3.select("svg").selectAll("g.rects").data(dataset);

        // removed data:
        bars.exit().remove();

        // updated data:
        bars.transition()
                .duration(750)
                .attr("x", function(d) { return 0; })
                .attr("y", function(d) { return y(d.label); })
                .attr("width", function(d) { return x(d.value); })
                .attr("height", y.rangeBand());

    };

2 个答案:

答案 0 :(得分:1)

您可能认为自己正在将<text>元素添加到<g>(群组)元素中,但您不是!

你这样做的那一刻......

.enter().append("g").append("rect")

...您现在正在尝试将文本元素附加到<rect>元素,这不起作用。

解决方案:打破您的bars变量:

//appending the <g> elements
var bar = svg.selectAll(".bar")
    .data(dataset, function(d) {
        return d.label;
    })
    .enter().append("g");

//now you append the <rect> to the <g>
bar.append("rect")
    .attr("class", "bar")
    .attr("x", function(d) {
        return x(d.value);
    })
    .attr("y", function(d) {
        return y(d.label);
    })
    .attr("width", function(d) {
        return width - x(d.value);
    })
    .attr("height", y.rangeBand());

//and then you append the <text> to the <g>
bar.append("text")
    .attr("x", function(d) {
        return x(d.value) - 3;
    })
    .attr("text-anchor", "end")
    .attr("y", function(d) {
        return y(d.label) + y.rangeBand() / 2;
    })
    .attr("dy", ".35em")
    .text(function(d) {
        return d.value;
    });

这是您更新的小提琴:https://jsfiddle.net/v8razxc8/

答案 1 :(得分:0)

我更喜欢在g元素中添加rect和text,然后将translate转换为position。 https://jsfiddle.net/sjp700/b772s5mg/4/

 var bar = svg.selectAll(".bar")
                .data(dataset, function(d) { return d.label; })
        // new data:
       var bar_g = bar.enter().append("g")
             .attr("transform", function (d) { return "translate(" + x(d.value) + "," + y(d.label) + ")"; });


        bar_g.append("rect")
                .attr("class", "bar")            
                .attr("width", function(d) { return width-x(d.value); })
                .attr("height", y.rangeBand());


         bar_g.append("text")
           .attr("transform", function (d) { return "translate(" + 10 + "," + 10 + ")"; })
           .attr("y", 30)
           .attr("dy", ".35em")
           .text(function(d) { return d.value; 

});