如何在D3中的条形图栏中添加文本图例?

时间:2015-09-03 10:14:22

标签: d3.js

我正在尝试使用D3.Js将条形图中的文本/标签添加到条形图中。 我的文本正在附加,但是从第二个索引数据中跳过了第一个索引我不知道为什么会这样做。我调试了数据,数据正确来了.. 我一直在做如下:

function revenueBar(localDataJson) {
        var w = 400;
        var h = 400;
        var barPadding = 1;
        var maxRevenue = 0;
        var maxTurnOver = 0;
        var padding = {
            left: 45, right: 10,
            top: 40, bottom: 60
        }

        var maxWidth = w - padding.left - padding.right;
        var maxHeight = h - padding.top - padding.bottom;
        for (var j = 0; j < localDataJson.length; j++) {
            if (localDataJson[j].Revenue > maxRevenue) {
                maxRevenue = localDataJson[j].Revenue;
            }

        }
        for (var j = 0; j < localDataJson.length; j++) {
            if (localDataJson[j].TurnOver > maxTurnOver) {
                maxTurnOver = localDataJson[j].TurnOver;
            }

        }
        var convert = {
            x: d3.scale.ordinal(),
            y: d3.scale.linear()
        };
        // Define your axis
        var axis = {
            x: d3.svg.axis().orient('bottom')
            //y: d3.svg.axis().orient('left')
        };

        // Define the conversion function for the axis points
        axis.x.scale(convert.x);
       // axis.y.scale(convert.y);

        // Define the output range of your conversion functions
        convert.y.range([maxHeight, 0]);
        convert.x.rangeRoundBands([0, maxWidth]);

        convert.x.domain(localDataJson.map(function (d) {
            return d.Country;
        })
        );
        convert.y.domain([0, maxRevenue]);
        $('#chartBar').html("");
        var svg = d3.select("#chartBar")
                   .append("svg")
                   .attr("width", w)
                   .attr("height", h);
        // The group node that will contain all the other nodes
        // that render your chart
        $('.bar-group').html("");
        var chart = svg.append('g')
                             .attr({
                                 class: 'container',
                                 transform: function (d, i) {
                                     return 'translate(' + padding.left + ',' + padding.top + ')';
                                 }
                             });

        chart.append('g') // Container for the axis
                    .attr({
                        class: 'x axis',
                        transform: 'translate(0,' + maxHeight + ')'
                    })
                   .call(axis.x)
                    .selectAll("text")
                                 .attr("x", "-.8em")
                                 .attr("y", ".15em")
                         .style("text-anchor", "end")
                                .attr("transform", "rotate(-65)");// Insert an axis inside this node
        $('.axis path').css("fill", "none");
        chart.append('g') // Container for the axis
           // .attr({
           //     class: 'y axis',
           //     height: maxHeight,

           // })
           //.call(axis.y);

        var bars = chart
             .selectAll('g.bar-group')
             .data(localDataJson)
             .enter()
             .append('g') // Container for the each bar
             .attr({
                 transform: function (d, i) {
                     return 'translate(' + convert.x(d.Country) + ', 1)';
                 },
                 class: 'bar-group'
             });

        var color = d3.scale.ordinal()
                      .range(['#f1595f', '#79c36a', '#599ad3', '#f9a65a', '#9e66ab','#cd7058']);
        bars.append('rect')
                    .attr({
                        y: maxHeight,
                        height: 0,
                        width: function (d) { return convert.x.rangeBand(d) - 3; },
                        class: 'bar'
                    })
                    .transition()
                    .duration(1500)
                    .attr({
                        y: function (d, i) {
                            return convert.y(d.Revenue);
                        },
                        height: function (d, i) {
                            return maxHeight - convert.y(d.Revenue);
                        }
                    })
                    .attr("fill", function (d, i) {
                        return color(i);
                    })




        var svgs = svg.selectAll("g.container")
      //  svgs.selectAll("text")
          .data(localDataJson)

          .enter()
          .append("text")
            //.transition()        // <-- This is new,
          // .duration(5000)
          .text(function (d) {
              return (d.Revenue);
          })
          .attr("text-anchor", "middle")
          //// Set x position to the left edge of each bar plus half the bar width
          .attr("x", function (d, i) {
              return (i * (w / localDataJson.length)) + ((w / localDataJson.length - barPadding) / 2);
          })
         .attr({
             y: function (d, i) {
                 return convert.y(d.Revenue) +70;
             },
             height: function (d, i) {
                 return maxHeight - convert.y(d.Revenue);
             }
         })
       .attr("font-family", "sans-serif")
        .attr("font-size", "13px")
        .attr("fill", "white")


    }

我的数据是:

localdatajson=[
               {"Country";"USA","Revenue":"12","TurnOver":"16"},
               {"Country";"Brazil","Revenue":"4.5","TurnOver":"16"},
               {"Country";"Belzium","Revenue":"4.8","TurnOver":"16"},
               {"Country";"Britain","Revenue":"20","TurnOver":"16"},
               {"Country";"Canada","Revenue":"6.5","TurnOver":"16"},
               {"Country";"DenMark","Revenue":"7.5","TurnOver":"16"}
             ]

问题是文字正在附加但是在第一个之后,即它正在逃避收入12.并且从第二个附加&#34; 4.5&#34;

请帮忙。

1 个答案:

答案 0 :(得分:1)

  

问题是文字正在附加但是在第一个之后,即它是   逃避收入12.并追加第二个&#34; 4.5&#34;

这是因为添加text元素的当前块有

var svgs = svg.selectAll("g.container")
              .data(localDataJson)
              .enter()
              ...

这意味着它会在svg中搜索g.container个元素,并尝试将每个元素与相应的localDataJson元素相关联(为额外的localDataJson元素添加新元素,因为它可以使用g.container元素。找到相应的g.container元素。

由于您只有一个text元素,它会将第一个元素链接到该元素,然后为剩余元素添加新的var svgs = svg.select("g.container").selectAll("text.label") .data(localDataJson) .enter() .append("text") .classed("label", true) ... 元素。

你想要这样做

g.container

而是将.label中的文本元素与数据数组匹配,并为每个额外的数组添加一个新元素。

请注意,我们使用label并添加了类... .attr("x", function (d, i) { return convert.x(d.Country) + (convert.x.rangeBand(d) - 3) / 2; }) .attr("y", function (d, i) { return maxHeight; }) ... - 这是因为我们希望将其与数据标签的文本元素相匹配(不是说,我们为x轴添加的元素)标签)

虽然这样可以解决问题,但您可能需要在标签的x和y坐标中进行更多修正,而实际上并不需要为标签设置宽度

X,
C,
D,
Y,
A,

我将它设置为maxHeight只是为了显示它的工作原理 - 条形高度实际上是离线图,因为你的y尺度有问题。