【问题标题】:Dynamically update directive data动态更新指令数据
【发布时间】:2016-10-24 14:07:09
【问题描述】:

对不起,也许这是个愚蠢的问题,但我还在学习。

我正在尝试在 angularJS 中使用 D3.js 制作一个简单的折线图。一切正常,我正在使用自定义指令使用 D3 绘制图表。我正在使用 $scope 在控制器本身中添加图表数据。最初它会绘图,但我会一键更改数据,但图表不会自动更新,

阅读 angularjs 文档后,我了解到通过使用 $scope 我们可以动态更改 UI 内容。无论是这里可能还是 angularJs 中存在任何其他场景

我是 AngularJS 的初学者

  <div  data-ng-app="chartApp" data-ng-controller="SalesController">
  <h1>Today's Sales Chart</h1>
  <div linear-chart chart-data="salesData"></div>
  <button type="button" data-ng-click="Change()">Click Me!</button>
  </div>

我的 JS 代码

 var app = angular.module('chartApp', []);
    app.controller('SalesController', ['$scope', function($scope){
    $scope.salesData=[
    {hour: 1,sales: 54},
    {hour: 2,sales: 66},
    {hour: 3,sales: 77},
    {hour: 4,sales: 70},
    {hour: 5,sales: 60},
    {hour: 6,sales: 63},
    {hour: 7,sales: 55},
    {hour: 8,sales: 47},
    {hour: 9,sales: 55},
    {hour: 10,sales: 30}
];  
  $scope.Change = function () {
  //here i am changing the data so i need to replot the chart
  $scope.salesData=[
    {hour: 1,sales: 14},
    {hour: 2,sales: 16},
    {hour: 3,sales: 77},
    {hour: 4,sales: 10},
    {hour: 5,sales: 60},
    {hour: 6,sales: 63},
    {hour: 7,sales: 55},
    {hour: 8,sales: 47},
    {hour: 9,sales: 55},
    {hour: 10,sales: 30}
];
}  
}]);
//creating one custom directive to plot the chart
app.directive('linearChart', function($window){
  return{
  restrict:'EA',
  template:"<svg width='850' height='200'></svg>",
   link: function(scope, elem, attrs){
       var salesDataToPlot=scope[attrs.chartData];
       //if u gave like this u can remove attributr chart-data 
      // var salesDataToPlot=scope.salesData
       var padding = 20;
       var pathClass="path";
       var xScale, yScale, xAxisGen, yAxisGen, lineFun;

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

       function setChartParameters(){

           xScale = d3.scale.linear()
               .domain([salesDataToPlot[0].hour, salesDataToPlot[salesDataToPlot.length-1].hour])
               .range([padding + 5, rawSvg.attr("width") - padding]);

           yScale = d3.scale.linear()
               .domain([0, d3.max(salesDataToPlot, function (d) {
                   return d.sales;
               })])
               .range([rawSvg.attr("height") - padding, 0]);

           xAxisGen = d3.svg.axis()
               .scale(xScale)
               .orient("bottom")
               .ticks(salesDataToPlot.length - 1);

           yAxisGen = d3.svg.axis()
               .scale(yScale)
               .orient("left")
               .ticks(5);

           lineFun = d3.svg.line()
               .x(function (d) {
                   return xScale(d.hour);
               })
               .y(function (d) {
                   return yScale(d.sales);
               })
               .interpolate("basis");
       }

     function drawLineChart() {

           setChartParameters();

           svg.append("svg:g")
               .attr("class", "x axis")
               .attr("transform", "translate(0,180)")
               .call(xAxisGen);

           svg.append("svg:g")
               .attr("class", "y axis")
               .attr("transform", "translate(20,0)")
               .call(yAxisGen);

           svg.append("svg:path")
               .attr({
                   d: lineFun(salesDataToPlot),
                   "stroke": "blue",
                   "stroke-width": 2,
                   "fill": "none",
                   "class": pathClass
               });
       }
       drawLineChart();
   }
  };
  });

Fiddle

【问题讨论】:

  • 我更新了代码,打印数据时它似乎可以工作:jsfiddle.net/cpyx2tq9/3
  • @Matheno:数据会更新,但我需要更新图表...

标签: javascript angularjs d3.js angularjs-directive angularjs-scope


【解决方案1】:

这里有一个活生生的例子: http://jsfiddle.net/7dc3efrc/1/

scope.$watch(attrs.chartData, function(newValue) {
    if (newValue) {
        svg.selectAll("*").remove();
        drawLineChart(newValue);
    }
}, true);

使用 $watch 范围方法来触发模型更改的更新。另外,如果你不需要它,不要忘记清除之前的图表(svg.selectAll("*").remove())。

请查看完整示例,因为我对您的 salesDataToPlot 变量(它现在是一个函数参数)做了一些小的修改。

【讨论】:

  • 谢谢...工作正常
【解决方案2】:

您可以在作用域上使用$watch 来监听salesData 数据更改并在完成后重建您的图表。

//...
scope.$watch('salesData', function (newSalesData){
    // drawLineChart();
    // redraw logic
});
//...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-25
    • 2014-09-10
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多