自动调整Angular Material Grid内的Angular-nvd3图表

时间:2016-01-15 07:43:25

标签: angularjs angular-material angular-nvd3

我正在尝试在角度材质网格内获得响应式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>

请查看此codepen

提前致谢

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

1 个答案:

答案 0 :(得分: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>