Angularjs svg图 - 重复范围内

问题描述 投票:0回答:1

我正在构建一个点数组的图形,每个点都有: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

html angularjs svg angularjs-ng-repeat
1个回答
1
投票

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

进行以下更改

<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>
© www.soinside.com 2019 - 2024. All rights reserved.