如何在堆叠多条形图中显示值 - nvd3 Graphs [英] How to display values in Stacked Multi-bar chart - nvd3 Graphs

查看:25
本文介绍了如何在堆叠多条形图中显示值 - nvd3 Graphs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个场景,我需要在堆叠多条形图中显示每个堆栈的值 - nvd3 图形,因为我们可以在离散值中显示值 - nvd3 图形.

I got a scenario where in I need to display value for every stack in stacked multi-bar chart - nvd3 graph as we can display value in discrete value - nvd3 graph.

我知道,'showvalue' 用于 离散栏控制器,我们可以使用 showvalue 在堆叠图中,如果没有,请提出替代解决方案.

I understand, 'showvalue' is used in discrete bar controller, can we use showvalue in stacked graph, if not please suggest with an alternative solution.

提前致谢

推荐答案

目前不可能.该选项仅在离散条形图中可用.

Currently isn't possible. That option is available only in the discrete bar chart.

来自维护者:

我们没有这种能力.堆叠/分组图表也有复杂的动画,这使得这个问题很难解决.我们改用工具提示.

We don't have this ability. Stacked/Grouped charts also have complex animations making this a tricky thing to solve. We use tooltips instead.

来源 https://github.com/novus/nvd3/issues/150

如果您想这样做,您需要使用 d3 进行自己的实现.这里有一个很好的例子 http://plnkr.co/edit/BNpAlFalKz0zkkSszHh1?p=preview.它使用了 angular 包装器,但这是一个很好的起点.

If you want to do this you need to make your own implementation using d3. There is a good example here http://plnkr.co/edit/BNpAlFalKz0zkkSszHh1?p=preview. It's using the angular wrapper but it's a good starting point.

var app = angular.module('app', ['nvd3ChartDirectives']);

app.controller('chartCtrl', function($scope, $timeout) {

  var ANIMATION_TIME = 1500,
    countSeriesDisplayed = 2,
    promise,
    labels = ["label1", "label2", "label3", "label4", "label5"];

  $scope.isStacked = false;

  // Example data
  $scope.chartData = [{
    "key": "Series 1",
    "values": [
      [0, 10],
      [1, 20],
      [2, 30],
      [3, 40],
      [4, 50]
    ]
  }, {
    "key": "Series 2",
    "values": [
      [0, 10],
      [1, 40],
      [2, 60],
      [3, 20],
      [4, 40]
    ]
  }];

  /* To add labels, images, or other nodes on the created SVG, we need to wait
   *  for the chart to be rendered with a callback.
   *  Once the chart is rendered, a timeout is set to wait for the animation to
   *  finish.
   *
   *  Then, we need to find the position of the labels and set it with the
   *  transform attribute in SVG.
   *  To do so, we have to get the width and height of each bar/group of bar 
   *  which changes if stacked or not
   *
   */

  // Callback called when the chartData is assigned
  $scope.initLabels = function() {
    return function(graph) {
      promise = $timeout(function() {
        var svg = d3.select("svg"),
          lastRects, rectWidth,
          heightForXvalue = []; // Used for grouped mode

        // We get one positive rect of each serie from the svg (here the last serie)
        lastRects = svg.selectAll("g.nv-group").filter(
          function(d, i) {
            return i == countSeriesDisplayed - 1;
          }).selectAll("rect.positive");

        if ($scope.isStacked) {
          // If stacked, we get the width of one rect
          rectWidth = lastRects.filter(
            function(d, i) {
              return i == countSeriesDisplayed - 1;
            }).attr("width");
        } else {
          // If grouped, we need to get the greatest height of each bar
          var nvGroups = svg.selectAll("g.nv-group").selectAll("rect.positive");
          nvGroups.each(
            function(d, i) {
              // Get the Min height space for each group (Max height for each group)
              var rectHeight = parseFloat(d3.select(this).attr("y"));
              if (angular.isUndefined(heightForXvalue[i])) {
                heightForXvalue[i] = rectHeight;
              } else {
                if (rectHeight < heightForXvalue[i]) {
                  heightForXvalue[i] = rectHeight;
                }
              }
            }
          );

          // We get the width of one rect multiplied by the number of series displayed
          rectWidth = lastRects.filter(
            function(d, i) {
              return i == countSeriesDisplayed - 1;
            }).attr("width") * countSeriesDisplayed;
        }

        // We choose a width equals to 70% of the group width
        var labelWidth = rectWidth * 70 / 100;

        var groupLabels = svg.select("g.nv-barsWrap").append("g");

        lastRects.each(
          function(d, index) {
            var transformAttr = d3.select(this).attr("transform");
            var yPos = parseFloat(d3.select(this).attr("y"));
            groupLabels.append("text")
              .attr("x", (rectWidth / 2) - (labelWidth /2)) // We center the label
              // We add a padding of 5 above the highest rect
              .attr("y", (angular.isUndefined(heightForXvalue[index]) ? yPos : heightForXvalue[index]) - 5)
              // We set the text
              .text(labels[index])
              .attr("transform", transformAttr)
              .attr("class", "bar-chart-label");
          });

      }, ANIMATION_TIME);
    }
  };

  // Tooltips
  $scope.toolTipContentFunction = function () {
    return function (key, x, y, e, graph) {
      return labels[x];
    }
};

  $scope.$on('$destroy', function () {
    // Cancel timeout if still active
    $timeout.cancel(promise);
  });

});

更新:

我已经创建了一个要点,可以帮助您自己实现这一点.

I've created a gist that could help you to implement this by yourself.

https://gist.github.com/topicus/217444acb4204f364e46

这篇关于如何在堆叠多条形图中显示值 - nvd3 Graphs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆