Angularjs svg 图 ng-repeat 在范围内

Posted

技术标签:

【中文标题】Angularjs svg 图 ng-repeat 在范围内【英文标题】:Angularjs svg graph ng-repeat within range 【发布时间】:2018-08-12 04:22:10 【问题描述】:

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

<svg  >
  <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>

它创建一条从最后一个点到第一个点的线,一直穿过图形。 正如您在最后一行的代码中看到的,它将 index 与 index + 1 连接起来(这是数组中的第一个点) 例如,您可以:向 ng-repeat 添加一个范围以阻止它创建最后一行吗?

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

【问题讨论】:

你能创建一个小提琴或 plnkr 吗? Plunkr 会有所帮助,但据我了解,看看***.com/questions/23088523/… 添加了我正在使用的 codepen 链接 【参考方案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:widthpx; height:heightpx;">

        <div class="y" style="width:heightpx;">yAxis</div>

        <div class="x">xAxis</div>
        <svg  >
          <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*heightpx - 5px); left:calc(point.xValue/maxX*widthpx - 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>

【讨论】:

以上是关于Angularjs svg 图 ng-repeat 在范围内的主要内容,如果未能解决你的问题,请参考以下文章

angularjs ng重复svg跳过空值的索引

关于angularjs的ng-repeat指令

ng-repeat angularJS 中的 ng-repeat

嵌套 ng-repeat 拖放,AngularJS

ng-repeat 内的 ng-repeat 和每个项目的 td - AngularJS

删除动态添加的值到 ng-repeat(angularjs)