我正在构建一个点数组的图形,每个点都有: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添加一个范围以阻止它创建最后一行吗?
如果要停止创建最后一行,可以添加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}}" />
<!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>