代码之家  ›  专栏  ›  技术社区  ›  mBo

Angularjs svg图形ng在范围内重复

  •  0
  • mBo  · 技术社区  · 6 年前

    我正在从一个点数组中构建一个图,其中每个点都有:label、xValue、yValue。 现在,当我尝试按如下方式连接数据点时:

    <svg height="{{height}}" width="100%">
      <line class="line{{$index}}" ng-repeat="point in points" x1="{{width / 
      maxX * points[$index].xValue }}" y1="{{points[$index].yValue / maxY * 
      height}}" x2="{{width / maxX * points[$index + 1].xValue}}" y2="
      {{points[$index + 1].yValue / maxY * height}}" />
    </svg>
    

    它创建一条从最后一个点到第一个点的直线,贯穿整个图形。 正如您在最后一行的代码中所看到的,它将索引与索引+1(即数组中的第一个点)连接起来 例如,能否向ng repeat添加一个范围以阻止其创建最后一行?

    图表为: https://codepen.io/nickmoreton/pen/ByYZMB

    1 回复  |  直到 6 年前
        1
  •  1
  •   Nishanth    6 年前

    如果要停止创建最后一行,可以添加limito

    进行以下更改

    <line class="line{{$index}}" 
    ng-repeat="point in points | limitTo : points.length-1" 
    x1="{{width / maxX * $index }}" y1="{{points[$index - 1].yValue / maxY * height}}" x2="{{width / maxX * ($index + 1)}}" y2="{{point.yValue / maxY * height}}" />
    

    Codepen link:

    <!DOCTYPE html>
    <html>
    
    <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
      <script>
        (function() {
    
          var app = angular.module('graphApp', []);
    
          app.controller('graphController', function($scope) {
    
            // Options
    
            $scope.width = 600;
            $scope.height = 350;
            $scope.yAxis = 'Sales';
            $scope.xAxis = '2014';
    
            // Data 
    
            $scope.points = [{
              label: 'January',
              xValue: 1,
              yValue: 36
            }, {
              label: 'February',
              xValue: 2,
              yValue: 54
            }, {
              label: 'March',
              xValue: 3,
              yValue: 62
            }, {
              label: 'April',
              xValue: 4,
              yValue: 82
            }, {
              label: 'May',
              xValue: 5,
              yValue: 96
            }, {
              label: 'June',
              xValue: 6,
              yValue: 104
            }, {
              label: 'July',
              xValue: 7,
              yValue: 122
            }, {
              label: 'August',
              xValue: 8,
              yValue: 152
            }, {
              label: 'September',
              xValue: 9,
              yValue: 176
            }, {
              label: 'October',
              xValue: 10,
              yValue: 180
            }, {
              label: 'November',
              xValue: 11,
              yValue: 252
            }, {
              label: 'December',
              xValue: 12,
              yValue: 342
            }];
    
            // Find Maximum X & Y Axis Values - this is used to position the points as a percentage of the maximum
            $scope.maxY = 0;
            $scope.maxX = 0;
    
            var arrLength = $scope.points.length;
            for (var i = 0; i < arrLength; i++) {
              // Find Maximum X Axis Value
              if ($scope.points[i].yValue > $scope.maxY)
                $scope.maxY = $scope.points[i].yValue;
              // Find Maximum Y Axis Value
              if ($scope.points[i].xValue > $scope.maxX)
                $scope.maxX = $scope.points[i].xValue;
            }
    
            // End Controller  
          });
    
        })();
      </script>
      <style>
        
        * {box-sizing:border-box;}
    
    h1 {
      color: #D07371;
    }
    
    body {
      font-size:1.1em;
      text-align:center;
      background:#F4F0DC;
      color:#444;
    }
    
    p {
      width:60%;
      margin:20px auto;
    }
    
    .graph {
      position:relative;
      margin:50px auto;
      background:#D9F2E6; 
    }
    
    svg {
      transform: rotateX(180deg);
      position:relative;
    }
    
    .y {
      font-weight:bold;
      border-bottom:1px solid #71CBD0;
      position:absolute;
      text-align:center;
      padding: 10px;
      transform: rotate(-90deg);
      transform-origin: bottom left;
      bottom:0;
      color: #D07371;
    }
    
    .x {
      font-weight:bold;
      border-top:1px solid #71CBD0;
      position:absolute;
      width: 100%;
      text-align:center;
      padding: 10px;
      top:100%;
      color:#D07371;
    }
    
    .dot {
      border-radius:50%;
      width:0px;
      height:0px;
      position:absolute;
      background:#71CBD0;
      cursor: pointer;
      animation: dots 100ms linear forwards;
      &:after {
        content:attr(data-title);
        display:inline-block;
        white-space: nowrap;
        overflow:hidden;
        background:#D07371;
        color:white;
        position:absolute;
        padding:10px;
        left:150%;
        top:-15px;
        width:0;
        opacity:0;
        border-radius:3px;
        font-weight:700;
      }
      
      &:hover {
        background:#D07371; 
         
        &:after {
          width:auto;
          opacity:1;
          z-index:9999;
        }
      }
    }
    
    line {
      stroke-dasharray: 200;
      stroke-dashoffset: 200;
      stroke:#D07371;
      stroke-width:2;
      animation: dash 500ms linear forwards;
    }
    
    .lines(11);
    
    .lines(@n, @i: 0, @a :0) when (@i =< @n) {
      .line@{i} {
        animation-delay:(@a+1000)*1ms;
      }
      .dot@{i} {
        animation-delay:(@a+1150)*1ms;
      }
      .lines(@n, (@i + 1), (@a + 150));
    }
    
    @keyframes dash {
      to {
        stroke-dashoffset: 0;
      }
    }
    
    @keyframes dots {  
      0% {
        width:0px;
        height:0px;
      }
      
      50% {
        width:10px;
        height:10px;
      }
      
      75% {
        width:15px;
        height:15px;
      }
      
      100% {
        width:10px;
        height:10px;
      }
    }
        
      </style>
    </head>
    
    <body>
      <h1>AngularJS Graph with animated SVG line</h1>
    
    
      <div ng-app="graphApp">
        <div ng-controller="graphController as graph">
          <div class="graph" style="width:{{width}}px; height:{{height}}px;">
    
            <div class="y" style="width:{{height}}px;">{{yAxis}}</div>
    
            <div class="x">{{xAxis}}</div>
            <svg height="{{height}}" width="100%">
              <line class="line{{$index}}" ng-repeat="point in points | limitTo : points.length-1" x1="{{width / maxX * $index }}" y1="{{points[$index - 1].yValue / maxY * height}}" x2="{{width / maxX * ($index + 1)}}" y2="{{point.yValue / maxY * height}}" />
            </svg>
            <div class="dot dot{{$index}}" ng-repeat="point in points" style="bottom:calc({{point.yValue}}/{{maxY}}*{{height}}px - 5px); left:calc({{point.xValue}}/{{maxX}}*{{width}}px - 5px);" data-title="{{point.label}}: {{point.yValue}}"></div>
    
          </div>
        </div>
      </div>
    
      <p>It always struck me that AngularJS could be used as a nice simple tool for visualising data.</p>
    
      <p>Here I use ng-repeat and data binding for inline styling and controlling SVG</p>
    
    
    </body>
    
    </html>