0

我正在尝试在角材料网格内获取响应式 nvd3 图表。在我调整窗口大小后它似乎工作正常,但在初始加载时没有达到正确的大小。

我的方法是将 nvd3 指令包装在“resize”指令中。然后我可以观察父元素并在窗口调整大小时更新图表的高度和宽度。我遇到的问题是加载父 div 的高度和宽度属性似乎为 0。我尝试使用 $timeout 来应用范围,但这似乎也不起作用。

angular.module('MyApp', ['ngMaterial', 'ngMessages', 'nvd3'])
  .controller('AppCtrl', function($scope) {
    $scope.options = {
      chart: {
        type: 'discreteBarChart',
        height: 450,
        margin: {
          top: 20,
          right: 20,
          bottom: 50,
          left: 55
        },
        x: function(d) {
          return d.label;
        },
        y: function(d) {
          return d.value + (1e-10);
        },
        showValues: true,
        valueFormat: function(d) {
          return d3.format(',.4f')(d);
        },
        duration: 500,
        xAxis: {
          axisLabel: 'X Axis'
        },
        yAxis: {
          axisLabel: 'Y Axis',
          axisLabelDistance: -10
        }
      }
    };

    $scope.data = [{
      key: "Cumulative Return",
      values: [{
        "label": "A",
        "value": -29.765957771107
      }, {
        "label": "B",
        "value": 0
      }, {
        "label": "C",
        "value": 32.807804682612
      }, {
        "label": "D",
        "value": 196.45946739256
      }, {
        "label": "E",
        "value": 0.19434030906893
      }, {
        "label": "F",
        "value": -98.079782601442
      }, {
        "label": "G",
        "value": -13.925743130903
      }, {
        "label": "H",
        "value": -5.1387322875705
      }]
    }]
  }).directive('resize', function($window, $timeout) {
    var linker = function(scope, element, attrs) {
      var w = angular.element($window);
      
      w.bind('resize', function() {
        scope.$apply();
      })
      
      $timeout(function(){
        updateHeight();
        updateWidth();
        scope.$apply();
      })

      scope.$watch(function() {
        return element.parent()[0].clientHeight;

      }, updateHeight);

      scope.$watch(function() {
        return element.parent()[0].clientWidth;

      }, updateWidth);

      function updateHeight() {
        scope.options.chart.height = element.parent()[0].clientHeight;
      }

      function updateWidth() {
        scope.options.chart.width = element.parent()[0].clientWidth;
      }
    };

    return {
      template: '<div style="height100%;width:100%;"><nvd3 options="options" data="data"></nvd3></div>',
      restrict: "E",
      link: linker,
      scope: {
        data: '=',
        options: '='
      }
    };
  });
.gridListdemoBasicUsage md-grid-list {
  margin: 8px; }

.gridListdemoBasicUsage .gray {
  background: #f5f5f5; }

.gridListdemoBasicUsage .green {
  background: #b9f6ca; }

.gridListdemoBasicUsage .yellow {
  background: #ffff8d; }

.gridListdemoBasicUsage .blue {
  background: #84ffff; }

.gridListdemoBasicUsage .purple {
  background: #b388ff; }

.gridListdemoBasicUsage .red {
  background: #ff8a80; }

.gridListdemoBasicUsage md-grid-tile {
  transition: all 400ms ease-out 50ms; }
<div ng-controller="AppCtrl as appCtrl" ng-cloak="" class="gridListdemoBasicUsage" ng-app="MyApp">
  <md-grid-list md-cols-xs="1" md-cols-sm="2" md-cols-md="4" md-cols-gt-md="6" md-row-height-gt-md="1:1" md-row-height="2:2" md-gutter="12px" md-gutter-gt-sm="8px">
    <md-grid-tile class="gray" md-rowspan="3" md-colspan="2" md-colspan-sm="1">
      <resize options="options" data="data"></resize>
      <md-grid-tile-footer>
        <h3>#1: (3r x 2c)</h3>
      </md-grid-tile-footer>
    </md-grid-tile>

    <md-grid-tile class="green">
      <md-grid-tile-footer>
        <h3>#2: (1r x 1c)</h3>
      </md-grid-tile-footer>
    </md-grid-tile>

    <md-grid-tile class="yellow">
      <md-grid-tile-footer>
        <h3>#3: (1r x 1c)</h3>
      </md-grid-tile-footer>
    </md-grid-tile>

    <md-grid-tile class="blue" md-rowspan="2">
      <md-grid-tile-footer>
        <h3>#4: (2r x 1c)</h3>
      </md-grid-tile-footer>
    </md-grid-tile>

    <md-grid-tile class="red" md-rowspan="2" md-colspan="2" md-colspan-sm="1">
      <md-grid-tile-footer>
        <h3>#5: (2r x 2c)</h3>
      </md-grid-tile-footer>
    </md-grid-tile>

    <md-grid-tile class="green" md-rowspan="2">
      <md-grid-tile-footer>
        <h3>#6: (2r x 1c)</h3>
      </md-grid-tile-footer>
    </md-grid-tile>

  </md-grid-list>
</div>

请查看此代码笔

提前致谢

更新:我使用 Angular nvd3s api.updateWithOptions(options) 为我的应用找到了解决方案。仍然无法在代码笔中工作。可能是代码笔的版本差异将很快附上最终解决方案。

4

1 回答 1

1

我对 angular-nvd3 和 angular-material 有同样的问题。我无法解释为什么会发生这种情况,并且自 2016 年 6 月以来它已经被报告为错误(请参阅https://github.com/krispo/angular-nvd3/issues/454)。

但是,我能够用一个简单的方法来修复它

angular.element(document).ready(function () {})

围绕 $scope.data 阻塞。

这个例子对我有用:

控制器

angular.module('app')

.controller('pieChartCtrl', function($scope){

    $scope.options = {
        chart: {
            type: 'pieChart',
            height: 500,
            x: function(d){return d.key;},
            y: function(d){return d.y;},
            showLabels: true,
            duration: 500,
            labelThreshold: 0.01,
            labelSunbeamLayout: true,
            legend: {
                margin: {
                    top: 5,
                    right: 35,
                    bottom: 5,
                    left: 0
                }
            }
        }
    };

    angular.element(document).ready(function () {
        $scope.data = [
            {
                key: "One",
                y: 5
            },
            {
                key: "Two",
                y: 2
            },
            {
                key: "Three",
                y: 9
            },
            {
                key: "Four",
                y: 7
            },
            {
                key: "Five",
                y: 4
            },
            {
                key: "Six",
                y: 3
            },
            {
                key: "Seven",
                y: .5
            }
           ];
    });    
})

看法

  <div ng-controller="pieChartCtrl">
      <nvd3 options="options" data="data"></nvd3>
   </div>
于 2016-09-28T08:02:14.507 回答