在ng-repeat,AngularJS和指令

时间:2016-07-19 12:42:11

标签: angularjs d3.js angularjs-directive

我遵循了这个示例D3Integration,这是在OpenMUC框架中为我在Angular中使用正确的D3自定义可视化的唯一方法。

我有几个带ID的设备。我设法为条形图分开数据,这些数据是独立更新的。当然我只想为特定设备显示一个条,但控制器保存完整的数据。

是否可以仅显示特定栏(通过索引或过滤器)? ng-Model与索引完美配合:X。在data =“d3Data [deviceIndex]”上设置索引会引发错误。有趣的是,只是deviceIndex的栏消失了(由于错误),另一个工作正常。

此:

<div class="row">
    <div class="col-md-6 col-md-offset-3" ng-controller="DemoCtrl">
        <span>{{title}}</span>
        <d3-bars data="d3Data" label="name" on-click="d3OnClick(item)"></d3-bars>                                       
        <br><input type="text" ng-model="d3Data[deviceIndex].value"></input>    
    </div>
</div>

我很确定它可以通过良好的指令函数定义或类似的东西来管理,但我无法做到:(

用ng-repeat包装以扫描设备:

<div ng-repeat="(deviceIndex,device) in checkedDevices track by $index" ng-switch on= "device.id | limitTo : 3">

我的指令看起来像这样(很少修改D3Integration示例):

(function () {
  'use strict';

  angular.module('myAppDirective')
    .directive('d3Bars', ['d3', function(d3) {
      return {
        restrict: 'EA',		
        scope: {
          data: "=",    
          label: "@", 
          onClick: "&", 
		  onLoad: "&"  //can i define something like this?
        },
        link: function(scope, iElement, iAttrs) {
          var svg = d3.select(iElement[0])
              .append("svg")
              .attr("width", "100%");

          // on window resize, re-render d3 canvas
          window.onresize = function() {
            return scope.$apply();
          };
          scope.$watch(function(){
              return angular.element(window)[0].innerWidth;
            }, function(){
              return scope.render(scope.data);
            }
          );
		  
		
          // watch for data changes and re-render
          scope.$watch('data', function(newVals, oldVals) {
            return scope.render(newVals);
          }, true);
		  
		  //here we catch a broadcast from demoCtrl. In obj currently all Data (d3Data) is inside.
		   scope.$on('onRerender', function(event, obj) {
			  //TODO: Solve this dependend on index?! 
			   return scope.data = obj;  //triggers $watch
			})
		  
		  



          // define render function
          scope.render = function(data){
            // remove all previous items before render
            svg.selectAll("*").remove();

            // setup variables
            var width, height, max;
            width = d3.select(iElement[0])[0][0].offsetWidth - 10;
              // 20 is for margins and can be changed
            height = scope.data.length * 35;
              // 35 = 30(bar height) + 5(margin between bars)
            max = 250;
              // this can also be found dynamically when the data is not static
              // max = Math.max.apply(Math, _.map(data, ((val)-> val.count)))

            // set the height based on the calculations above
            svg.attr('height', height);

            //create the rectangles for the bar chart
            svg.selectAll("rect")
              .data(data)
              .enter()
                .append("rect")
                .on("click", function(d, i){
					return scope.onClick({item: d});   // this is how it worked before
				})
				.on("load", function(d,i){
					return scope.onLoad({item: d, index: i});
				})
                .attr("height", 30) // height of each bar
                .attr("width", 0) // initial width of 0 for transition
                .attr("x", 10) // half of the 20 side margin specified above
                .attr("y", function(d, i){
                  return i * 35;
                }) // height + margin between bars
                .transition()
                 // .duration(1000) // time of duration
                  .duration(0) // time of duration
                  .attr("width", function(d){
                    return d.value*2/(max/width);
                  }); // width based on scale

            svg.selectAll("text")
              .data(data)
              .enter()
                .append("text")
                .attr("fill", "#555")
                .attr("y", function(d, i){return i * 35 + 22;})
                .attr("x", 15)
                .text(function(d){return d[scope.label];});

          };
		  
		  
		  scope.getData = function(indexOfHTML){
			  return scope.data[indexOfHTML];
		  };
		  
        }
      };
    }]);

}());

(function () {
  'use strict';

  angular.module('myAppControllers')
    .controller('DemoCtrl', ['$scope', function($scope){
      $scope.title = "DemoCtrl";
      $scope.d3Data = [];
      $scope.d3OnClick = function(item){
        console.log(item.name);
      };
	  
	  //tried something here
	  $scope.d3OnLoad = function(item, index){
        console.log(item.name + " | " + index.i); 
      };
	  	  
	  console.log("create initial data:" );	  
		for(var i = 1; i <= 4; i++){
			if(i < 10){
				$scope.d3Data.push({name: "voltageL1_0x00" + i + "0", value:i});
			}else{
				$scope.d3Data.push({name: "voltageL1_0x0" + i + "0", value:i});
			}				
		}
	  
	$scope.$on('onSearch', function(event, obj) {
		
	  	for(var len = $scope.d3Data.length, i=0; i<len; ++i){
			if(obj[0].name == $scope.d3Data[i].name){
				$scope.d3Data[i] = obj[0];
			} 
		};
	  $scope.$broadcast('onRerender', $scope.d3Data);
    });

    }]);

}());

我的问题显示在这张图片中:Data issues 任何帮助都是超级优秀的!

0 个答案:

没有答案