2015-06-16 39 views
0

我想绘制实际值以及使用角度和D3的趋势线。我读了很多教程,但无法理解我们如何在D3中访问控制器的多个变量。在d3线图中用角度绘制趋势线与实际值

我有以下的控制器数据:

$scope.salesData=[ 
     {hour: 1997,sales: 205000}, 
     {hour: 1998,sales: 305000}, 
     {hour: 1999,sales: 405000}, 

    ]; 

$scope.lrResults = {slope: -16958.279411764706, intercept: 34325954.51470588, r2: 0.8292316961223657} 

HTML:

<div linear-chart chart-data="salesData" line-data="lrResults"></div> 

然后,我有以下指令:

app.directive('linearChart', function($parse, $window){ 
    return{ 
     restrict:'EA', 
     template:"<svg width='850' height='250'></svg>", 
     link: function(scope, elem, attrs){ 
      var exp = $parse(attrs.chartData); 
      var salesDataToPlot=exp(scope); 


      var padding = 20; 
      var pathClass="path"; 
      var xScale, yScale, xAxisGen, yAxisGen, lineFun, trendline; 

      var d3 = $window.d3; 
      var rawSvg=elem.find('svg'); 
      var svg = d3.select(rawSvg[0]); 

      scope.$watchCollection(exp, function(newVal, oldVal){ 
       salesDataToPlot=newVal; 
       redrawLineChart(); 
      }); 

使用上面我能够解析内包含的数据salesData并使用以下d3代码绘制折线图:

svg.append("svg:path") 
     .attr("transform", "translate(70,0)") 
       .attr({ 
        d: lineFun(salesDataToPlot), 
        "stroke": "red", 
        "stroke-width": 2, 
        "fill": "none", 
        "class": pathClass 
       }); 

,但我无法理解我怎么可以检索包含在lrResults数据,然后加上正常图的顶部趋势线。

这里是代码片段我会用绘制线:

svg.append("svg:line") 
       .attr("x1", xScale(0)) 
       .attr("y1", yScale(lrData.intercept)) 
       .attr("x2", xScale(max)) 
       .attr("y2", yScale((max*lrData.slope)+ lrData.intercept)) 
       .style("stroke", "black"); 

回答

1

你需要基于这些参数数据。

这是我的控制器内的工作示例:

angular.module('d3-angular.controllers', [], function() {}) 
.controller('myCtrl', function($scope) { 

    // svg parameters 
    var width = 500, height = 500, margin = 50; 

    // line parameters (y = mx + b) 
    $scope.b = 0.3; 
    $scope.m = 2; 
    $scope.numPts = 20; 

    // generate data 
    var data = new Array($scope.numPts); 
    for (var idx = 0; idx < $scope.numPts; idx++) { 
      data[idx] = { 
        x: idx/$scope.numPts, 
        y: $scope.m*idx/$scope.numPts + $scope.b + (Math.random()-0.5) 
      } 
    } 

    // build the scales 
    var xScale = d3.scale.linear().domain([0,1]).range([margin,width-margin]); 
    var yScale = d3.scale.linear().domain([0,2.5]).range([height-margin,margin]); 

    // select our svg element, set up some properties 
    var svg = d3.select("svg"); 
    svg.attr("width",width).attr("height",height); 

    // add the trendline 
    var line = svg.selectAll("line").data([{'p1': [0, $scope.b], 'p2': [1, $scope.m+$scope.b]}]); 
    line.enter().append("line").attr("stroke","red").attr("stroke-width",2) 
      .attr("x1", function(d) { return xScale(d.p1[0]) }) 
      .attr("y1", function(d) { return yScale(d.p1[1]) }) 
      .attr("x2", function(d) { return xScale(d.p2[0]) }) 
      .attr("y2", function(d) { return yScale(d.p2[1]) }) 

    // join with our data 
    var points = svg.selectAll("circle").data(data); 

    // enter (add circles) 
    points.enter().append("circle") 
      .attr("cx", function(d) { 
        return xScale(d.x); 
      }) 
      .attr("cy", function(d) { 
        return yScale(d.y); 
      }) 
      .attr("r", 5); 

    // add Axes 
    var xAxis = d3.svg.axis().scale(xScale).orient("bottom").tickValues([0,1]); 
    svg.append("g").attr("class","axis") 
      .attr("transform", "translate(0," + (height-margin) + ")") 
      .call(xAxis); 
    var yAxis = d3.svg.axis().scale(yScale).orient("left").ticks(5); 
    svg.append("g").attr("class","axis") 
      .attr("transform", "translate(" + margin + ",0)") 
      .call(yAxis); 

})

用m和b替换您范围参数的斜率和截距。 尝试......可能有帮助!

+0

感谢它以这种方式工作,但如果有人可以帮助我通过指令使用它,那将会很好。 – mribot

+0

@mribot只需将svg所需的所有参数声明和计算放入指令中,并从那里返回所需的参数声明和计算,并像往常一样使用svg。 – sam100rav

+0

@mribot,并请记住答案,如果你喜欢它接受。 – sam100rav