2

我在 NVD3/AngularJS 中创建了一个多条形图。我想在每个矩形条内显示文本及其值,如下面的 JSON 所示。

如何在每个条形图内显示文本值?

NVD3 图表定义

multiBarChart: {
        options: function(){
          return {
            chart: {
              type: 'multiBarChart',
              stacked: true,
              x: function(d){return d.x;},
              y: function(d){return d.y;},
              text: function(d){return d.x;},
              showLabels: true,
              showLegend: false,
              transitionDuration: 500,
              forceX: ["Team", "Meeting", "Phase", "Source"],
              xAxis: {
                axisLabel: 'Category',
                axisLabelDistance: -8
              },
              yAxis: {
                axisLabel: 'Number Of Action Items',
              }
            }
          }
        },
        data: categoryChartData
      }

JSON 数据 (categoryChartData)

  [ 
                                {"values" : [
                                    {
                                        "y" :10,
                                        "x" : "Team"
                                    }, {
                                        "y" : 0,
                                        "x" : "Meeting"
                                    },
                                    {
                                        "y" :0,
                                        "x" : "Phase"
                                    }, {
                                        "y" : 0,
                                        "x" : "Source"
                                    }
                                    ],
                                    "key" : "Team1"
                                },

                                {"values" : [
                                    {
                                        "y" :5,
                                        "x" : "Team"
                                    }, {
                                        "y" : 0,
                                        "x" : "Meeting"
                                    },
                                    {
                                        "y" :0,
                                        "x" : "Phase"
                                    }, {
                                        "y" : 0,
                                        "x" : "Source"
                                    }
                                    ],
                                    "key" : "Team2"
                                },
                                    {"values" : [
                                    {
                                        "y" :0,
                                        "x" : "Team"
                                    }, {
                                        "y" : 7,
                                        "x" : "Meeting"
                                    },
                                    {
                                        "y" :0,
                                        "x" : "Phase"
                                    }, {
                                        "y" : 0,
                                        "x" : "Source"
                                    }
                                    ],
                                    "key" : "Meeting1"
                                },
                                    {"values" : [
                                    {
                                        "y" :0,
                                        "x" : "Team"
                                    }, {
                                        "y" : 3,
                                        "x" : "Meeting"
                                    },
                                    {
                                        "y" :0,
                                        "x" : "Phase"
                                    }, {
                                        "y" : 0,
                                        "x" : "Source"
                                    }
                                    ],
                                    "key" : "Meeting2"
                                },
                                {"values" : [
                                    {
                                        "y" :0,
                                        "x" : "Team"
                                    }, {
                                        "y" : 0,
                                        "x" : "Meeting"
                                    },
                                    {
                                        "y" :9,
                                        "x" : "Phase"
                                    }, {
                                        "y" : 0,
                                        "x" : "Source"
                                    }
                                    ],
                                    "key" : "Phase1"
                                },
                                {"values" : [
                                    {
                                        "y" :0,
                                        "x" : "Team"
                                    }, {
                                        "y" : 0,
                                        "x" : "Meeting"
                                    },
                                    {
                                        "y" :5,
                                        "x" : "Phase"
                                    }, {
                                        "y" : 0,
                                        "x" : "Source"
                                    }
                                    ],
                                    "key" : "Phase1"
                                },
                                {"values" : [
                                    {
                                        "y" :0,
                                        "x" : "Team"
                                    }, {
                                        "y" : 0,
                                        "x" : "Meeting"
                                    },
                                    {
                                        "y" :0,
                                        "x" : "Phase"
                                    }, {
                                        "y" : 2,
                                        "x" : "Source"
                                    }
                                    ],
                                    "key" : "Internal"
                                },
                                {"values" : [
                                    {
                                        "y" :0,
                                        "x" : "Team"
                                    }, {
                                        "y" : 0,
                                        "x" : "Meeting"
                                    },
                                    {
                                        "y" :0,
                                        "x" : "Phase"
                                    }, {
                                        "y" : 1,
                                        "x" : "Source"
                                    }
                                    ],
                                    "key" : "Customer"
                                }


                                ];

类别堆积图

4

2 回答 2

5

由于动画堆叠条形图的一些复杂性,Angular-nvd3 本身并不为多条形图执行此操作,但它将用于离散条形图,如如何在堆叠多条形图中显示值 - nvd3 Graphs探索。但是,在更新他对该问题的回答时,@Topicus 链接到他们编写的一个要点,该要点可以完成您正在寻找的内容。

我根据您的情况调整了要点;你可以在这个 Plunker中看到结果。如果标签显示有点不稳定,您可以稍微调整一下格式。关键是动画完成后需要附加标签,所以我设置了一个等于(也可以略大于)transitionDuration 图表属性的值的超时。我还删除了所有零值,这样它们就不会掩盖非零值。

$scope.options = {
  chart: {
    type: 'multiBarChart',
    height: 500,
    transitionDuration: 500,
    ...
  }
};

$scope.data...

$timeout(function () {
  d3.selectAll('.nv-multibar .nv-group').each(function(group){
    var g = d3.select(this);
  
    // Remove previous labels if there is any
    g.selectAll('text').remove(); 
    g.selectAll('.nv-bar').each(function(bar) {
      var b = d3.select(this);
      var barWidth = b.attr('width');
      var barHeight = b.attr('height');

      g.append('text')
        // Transforms shift the origin point then the x and y of the bar
        // is altered by this transform. In order to align the labels
        // we need to apply this transform to those.
        .attr('transform', b.attr('transform'))
        .text(function() {
          // No decimals format and eliminate zero values
          if (bar.y === 0) {
            return;
          }
          return parseFloat(bar.y).toFixed(0);
        })
        .attr('y', function() {
          // Center label vertically
          var height = this.getBBox().height;
          return parseFloat(b.attr('y')) + 15; // 15 is the label's margin from the top of bar
        })
        .attr('x', function() {
          // Center label horizontally
          var width = this.getBBox().width;
          return parseFloat(b.attr('x')) + (parseFloat(barWidth) / 2) - (width / 2);
        })
        .style("stroke","black")
        .attr('class', 'bar-values');
    });
  });
}, 500);
于 2016-01-07T18:45:38.437 回答
0

我认为答案有两点要补充。1.我们添加代码在回调函数中添加值文本。如:

callback: function(chart){
    chart.dispatch.on('stateChange', function(e){
        setMultiBarValue(e.stacked);
    });

    setMultiBarValue(config.stacked);
}

2.添加功能以在组/堆叠选项中显示正确的文本

function setMultiBarValue(chart, config, dataRange, stacked, time){
    if(config.type === 'multiBarChart'){
        if(stacked === true){
            //stack set your totalMin, totalMax to make all the value visible.
            chart.yDomain([dataRange.totalMin, dataRange.totalMax]);
            initStackLables(d3.select(chart.container), time || 1000);
        }else{
            //group: set your min,max to make all the value visible.
            chart.yDomain([dataRange.yMin, dataRange.yMax]);
            initGroupLabels(d3.select(chart.container), time || 1000);
        }
    }
}
  1. 定义两个函数initStackLables,initGroupLabels,如:

    1).initGroupLabels

    var initGroupLabels = 函数(容器,时间){ 时间 = 时间 || 500; container.selectAll('.nv-multibar .nv-group').each(function(group) { var g = d3.select(this); // 如果有任何标签,则删除之前的标签 g.selectAll('text') 。消除(); }); $timeout(function() { container.selectAll('.nv-multibar .nv-group').each(function(group) { var g = d3.select(this);

                g.selectAll('.nv-bar').each(function(bar, index) {
                    var b = d3.select(this);
                    var barWidth = b.attr('width');
                    var barHeight = b.attr('height');
    
                    g.append('text')
                    // Transforms shift the origin point then the x and y of the bar
                    // is altered by this transform. In order to align the labels
                    // we need to apply this transform to those.
                    .attr('transform', b.attr('transform')).text(function() {
                        // No decimals format and eliminate zero values
                        if (bar.y === 0) {
                            return;
                        }
                        return parseFloat(bar.y);
                    }).attr('y',
                    function() {
                        // Center label vertically
                        var height = this.getBBox().height;
                        return parseFloat(b.attr('y')) - 10; // 10 is the label's margin from the top of bar
                    }).attr('x',
                    function() {
                        // Center label horizontally
                        var width = this.getBBox().width;
                        return parseFloat(b.attr('x')) + (parseFloat(barWidth) / 2) - (width / 2);
                    }).style('stroke', 'black').attr('class', 'bar-values');
                });
            });
        },
        time);
    }
    

    2)初始化堆栈标签

    var initStackLables =function(container, time){ time = time || 500;

    container.selectAll('.nv-multibar .nv-group').each(function(group){
        var g = d3.select(this);
        // Remove previous labels if there is any
        g.selectAll('text').remove(); 
    });
    $timeout(function () {
        var length = container.selectAll('.nv-multibar .nv-group').length;
        var vArr = []; var yArr = [];
        container.selectAll('.nv-multibar .nv-group').each(function(group){
            var g = d3.select(this);
            g.selectAll('.nv-bar').each(function(bar, index){
                var b = d3.select(this); var by = parseFloat(b.attr('y'));
                var barHeight = b.attr('y');
                vArr[index] = vArr[index] || 0;
                vArr[index] += parseFloat(bar.y) || 0;
                yArr[index] = yArr[index] || by;
                yArr[index] = yArr[index] > by ? by : yArr[index];
            });
        });
        container.selectAll('.nv-multibar .nv-group').each(function(group, index){
            if(index === 0){
                var g = d3.select(this);
                // Remove previous labels if there is any
                g.selectAll('text').remove(); 
                g.selectAll('.nv-bar').each(function(bar, index){
                    var b = d3.select(this);
                    var barWidth = b.attr('width');
                    var barHeight = b.attr('height');
    
                    g.append('text')
                        .attr('transform', b.attr('transform'))
                        .text(function(){
                            if (bar.y === 0) {
                                return;
                            }
                            return parseFloat(vArr[index];
                        })
                        .attr('y', function(){
                            var height = this.getBBox().height;
                            return parseFloat(yArr[index]) - 10; // 10 is the label's margin from the top of bar
                        })
                        .attr('x', function(){
                            var width = this.getBBox().width;
                            return parseFloat(b.attr('x')) + (parseFloat(barWidth) / 2) - (width / 2);
                        })
                        .style('stroke','black')
                        .attr('class', 'bar-values');
                });
            }
        });
    
    }, time);
    

    }

于 2018-07-12T02:31:35.203 回答