2016-06-16 7 views
1

私はbarchartに入れる必要があるいくつかのデータを持っており、選択した日付に基づいてデータを更新する必要があります。 チャートには、選択した週の7日間分のデータが表示されます。D3jsとAngularjsを使用した動的barchartの作成

plunker上

私のコードはhttps://plnkr.co/edit/raVy7y3KcOX757jcy3pL?p=preview

マイ@ある棒グラフ上に、私はページ上の日付のページネーションを持っていると私は前の週に移動したときに、私はその週のデータが母集団になりたいですコード:

index.htmlを

<!DOCTYPE html> 
<html> 
<head> 
    <style> 
     .chart { 
      background: #eee; 
      padding: 3px; 
     } 

     .chart div { 
      width: 0; 
      transition: all 1s ease-out; 
      -moz-transition: all 1s ease-out; 
      -webkit-transition: all 1s ease-out; 
     } 

     .chart div { 
      font: 10px sans-serif; 
      background-color: steelblue; 
      text-align: right; 
      padding: 3px; 
      margin: 5px; 
      color: white; 
      box-shadow: 2px 2px 2px #666; 
     } 

     .bar { 
      fill: steelblue; 
     } 
     .bar:hover { 
      fill: blue ; 
     } 
     .d3-tip { 
      line-height: 1; 
      font-weight: bold; 
      padding: 12px; 
      background: rgba(0, 0, 0, 0.8); 
      color: #fff; 
      border-radius: 2px; 
     } 

     /* Creates a small triangle extender for the tooltip */ 
     .d3-tip:after { 
      box-sizing: border-box; 
      display: inline; 
      font-size: 10px; 
      width: 100%; 
      line-height: 1; 
      color: rgba(0, 0, 0, 0.8); 
      content: "\25BC"; 
      position: absolute; 
      text-align: center; 
     } 

     /* Style northward tooltips differently */ 
     .d3-tip.n:after { 
      margin: -1px 0 0 0; 
      top: 100%; 
      left: 0; 
     } 

     ul { 
      width: 800px; 
     } 

     li { 
      float: left; 
      list-style: none; 
      margin: 25px; 
      /*border-bottom: 1px solid grey;*/ 
     } 

     input { 
      width: 100%; 
      /*margin-top: 12px; 
      margin-bottom: 12px;*/ 
      padding: 24px; 
     } 

     .event__container { 
      width: 100%; 
      height: 100px; 
     } 

     .date { 
      float: left; 
      width: 100%; 
      background-color: grey; 
      text-align: center; 
      color: grey; 
      font-weight: 700; 
      margin-left: 0; 
      margin: 0; 
      padding: 12px; 
      color: white; 
     } 
    </style> 

</head> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script> 
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> 
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script> 
<script src="main.js"></script> 

<body> 
    <div ng-app="myApp" ng-controller="Ctrl"> 

     <div> 

      <h2><i class="fa fa-arrow-left"></i>Week Of {{currentWeekStart()}} - {{currentWeekEnd()}}<i class="fa fa-arrow-right"></i></h2> 
       <button ng-click="prevWeek()">previous week</button> 
       <button ng-click="nextWeek()">next week</button> 


     </div> 




     <cr-d3-bars data='myData'></cr-d3-bars> 
    </div> 
    <script> 
     $('.filter').click(function() { 
      $(this).toggleClass('clicked'); 
     }); 
    </script> 
    </script> 
</body> 
</html> 

main.js

angular.module('myApp',[]).directive('crD3Bars', [ 
    function() { 
    return { 
     restrict: 'E', 
     scope: { 
     data: '=' 
     }, 
     link: function (scope, element) { 
      scope.data.forEach(function(d) { 
      d.name = d.name._i; 
      d.value = +d.value; 
      //console.log(d.name, d.value) 
     }); 
     var margin = {top: 20, right: 20, bottom: 30, left: 40}, 
      width = 800 - margin.left - margin.right, 
      height = 500 - margin.top - margin.bottom; 
     var svg = d3.select(element[0]) 
      .append("svg") 
      .attr('width', 800) 
      .attr('height', 800) 
      .append("g") 
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

     var x = d3.scale.ordinal().rangeRoundBands([0, width], .1); 
     var y = d3.scale.linear().range([height, 0]); 

     var xAxis = d3.svg.axis() 
      .scale(x) 
      .orient("bottom"); 

     var yAxis = d3.svg.axis() 
      .scale(y) 
      .orient("left") 
      .ticks(10); 

     //For tool tip 

     var tip = d3.tip() 
     .attr('class', 'd3-tip') 
     .offset([-10, 0]) 
     .html(function(d) { 
     return "<span style='color:red'>" + d.date, d.value + "</span>"; 
    }); 

    svg.call(tip); 
     //Render graph based on 'data' 
     scope.render = function(data) { 
      //Set our scale's domains 
      x.domain(data.map(function(d) { return d.name; })); 
      y.domain([0, d3.max(data, function(d) { return d.value; })]); 

      //Redraw the axes 
      svg.selectAll('g.axis').remove(); 
      //X axis 
      svg.append("g") 
       .attr("class", "x axis") 
       .attr("transform", "translate(0," + height + ")") 
       .call(xAxis) 
       .selectAll("text") 
      .style("text-anchor", "end") 
      .attr("dx", "-.8em") 
      .attr("dy", "-.55em") 
      .attr("transform", "rotate(-60)"); 

      //Y axis 
      svg.append("g") 
       .attr("class", "y axis") 
       .call(yAxis) 
      .append("text") 
       .attr("transform", "rotate(-90)") 
       .attr("y", 6) 
       .attr("dy", ".55em") 
       .attr("transform", "rotate(-90)") 
       .style("text-anchor", "end") 
       .text("value"); 


      var bars = svg.selectAll(".bar").data(data); 
      bars.enter() 
      .append("rect") 
      .attr("class", "bar") 
      .attr("x", function(d) { return x(d.name); }) 
      .attr("width", x.rangeBand()) 
      .attr('height', function(d) { return height - y(d.value); }) 
      .attr("y", function(d) { return y(d.value); }) 
      .on('mouseover', tip.show) 
      .on('mouseout', tip.hide) 
      //Animate bars 
      // bars 
      //  .transition() 
      //  .duration(1000) 
      //  .attr('height', function(d) { return height - y(d.value); }) 
      //  .attr("y", function(d) { return y(d.value); }) 
      // //  .on('mouseover', tip.show) 
      // // .on('mouseout', tip.hide) 

     }; 

     //Watch 'data' and run scope.render(newVal) whenever it changes 
     //Use true for 'objectEquality' property so comparisons are done on equality and not reference 
      scope.$watch('data', function(){ 
       scope.render(scope.data); 
      }, true); 
     } 
    }; 
    } 
]) 


    .controller('Ctrl', function($scope, $http) { 
     var currentDate, 
     weekStart, 
     weekEnd, 
     shortWeekFormat = 'MMMM Do'; 
     $scope.currentWeekStart; 
     $scope.currentWeekEnd; 

    function setCurrentDate(aMoment){ 
     currentDate = aMoment, 
     weekStart = currentDate.clone().startOf('week'), 
     weekEnd = currentDate.clone().endOf('week') 
    }  

    setCurrentDate(moment()); 

    $scope.currentWeekStart = function(){ return weekStart.format(shortWeekFormat); }; 
    $scope.currentWeekEnd = function(){ return weekEnd.format(shortWeekFormat); }; 

    $scope.week = function(item) { 
     var eventTime = moment(item.name); 
     return (eventTime >= weekStart && eventTime <= weekEnd); 
    }; 
     var data = [ 
       {name: moment('May 29 2016'), value: 300}, 
      {name: moment('May 30 2016'), value: 150}, 
      {name: moment('May 31 2016'), value: 400}, 
      {name: moment('Jun 1 2016'), value: 300}, 
      {name: moment('Jun 2 2016'), value: 100}, 
      {name: moment('Jun 3 2016'), value: 300}, 
      {name: moment('Jun 4 2016'), value: 150}, 
       {name: moment('Jun 5 2016'), value: 300}, 
      {name: moment('Jun 6 2016'), value: 150}, 
      {name: moment('Jun 7 2016'), value: 400}, 
      {name: moment('Jun 8 2016'), value: 300}, 
      {name: moment('Jun 9 2016'), value: 100}, 
      {name: moment('Jun 10 2016'), value: 300}, 
      {name: moment('Jun 11 2016'), value: 150}, 
      {name: moment('Jun 12 2016'), value: 400}, 
      {name: moment('Jun 13 2016'), value: 300}, 
      {name: moment('Jun 14 2016'), value: 100}, 
      {name: moment('Jun 15 2016'), value: 400}, 
      {name: moment('Jun 16 2016'), value: 300}, 
      {name: moment('Jun 17 2016'), value: 100}, 
      {name: moment('Jun 18 2016'), value: 100} 
      ]; 

     var beginValue = weekStart._d; 
     var endValue = weekEnd._d; 

     $scope.myData = data.filter(function(d){ 
     return d.name >= beginValue && d.name <= endValue; 
     }); 

    $scope.nextWeek = function(){ 
     var next = setCurrentDate(currentDate.add(7,'days')); 
     next = currentDate; 
     beginValue = weekStart._d; 
     endValue = weekEnd._d; 

     $scope.myData = data.filter(function(d){ 
     return d.name >= beginValue && d.name <= endValue; 
     }); 


     $scope.$watch('myData', function(){ 
       $scope.render($scope.myData); 
     }, true); 
     console.log($scope.myData) 

    }; 


    $scope.prevWeek = function(){ 
     var prev = setCurrentDate(currentDate.subtract(7,'days')); 
     prev = currentDate; 
     //console.log(weekStart) 
     //console.log(weekEnd) 
     $scope.myData = data.filter(function(d){ 
     return d.name >= weekStart._d && d.name <= weekEnd._d; 
     }); 
    // console.log($scope.myData) 
    }; 


    }); 

私が選ばれた日付に基づいて棒グラフの値を変更することはできませんよ。

私はD3jsを初めて使用しているため、間違っていることがわかりません。

あなたの考えを教えてください。

答えて

0

あなたはenterupdate、およびexitpatternを正しく処理していません。 Plunker here更新

 // join the data 
     var bars = svg.selectAll(".bar").data(data); 

     // any bars that no longer exist should be removed 
     bars.exit().remove(); 

     // new bars should be created 
     bars.enter() 
     .append("rect") 
     .attr("class", "bar") 
     .on('mouseover', tip.show) 
     .on('mouseout', tip.hide); 

     // all bars need to have new x positions, width and height 
     bars 
     .attr("x", function(d) { 
      return x(d.name); 
     }) 
     .attr("width", x.rangeBand()) 
     .attr('height', function(d) { 
      return height - y(d.value); 
     }) 
     .attr("y", function(d) { 
      return y(d.value); 
     }); 

:あなたのコードは次のようになります。

+0

ありがとうございました!ほとんど働いた私は1つの問題がある。前の週をクリックすると、値を取得しています。しかし、先週、ack clickignをクリックして、次週をクリックすると(つまり、今週に戻ると)、データが失われています。私はその部分をデバッグすることができません。更新されたプランカはhttps://plnkr.co/edit/0AYLP8Z198HEnj0pjWnY?p=preview –

+0

@javascriptnoviceにあります。この行は「d.name = d.name._i'」という文字列を返しています。 (モーメントオブジェクトから)。どうしてそんなことをするのか?ここには[更新されたプランカー](https://plnkr.co/edit/w0ZR0P4VzXUdsWOHpGzt?p=preview) – Mark

+0

私はそれを修正しました..ありがとう!! –

関連する問題