// 添加纵轴 var lines = main.append('g') .classed('lines', true); lines.selectAll('line') .data(polygons.webPoints[0]) .enter() .append('line') .attr('x1', 0) .attr('y1', 0) .attr('x2', function(d) { return d.x; }) .attr('y2', function(d) { return d.y; });
雷达图的坐标轴部分就完成了。
计算雷达图区域并添加
雷达图区域也是一个多边形,只不过是一个不规则的多边形。但是他的几个点始终处在纵轴上,并且点在纵轴上的位置可以通过点所代表的值在纵轴范围内的占比计算出来的。
// 计算雷达图表的坐标 var areasData = []; var values = data.values; for(var i=0;i<values.length;i++) { var value = values[i], area = '', points = []; for(var k=0;k<total;k++) { var r = radius * (value[k] - rangeMin)/(rangeMax - rangeMin); var x = r * Math.sin(k * onePiece), y = r * Math.cos(k * onePiece); area += x + ',' + y + ' '; points.push({ x: x, y: y }) } areasData.push({ polygon: area, points: points }); }
计算完点的坐标以后我们就可以添加雷达图区域了。为了使雷达图更可观,我们除了添加多边形表示雷达图的区域以外,也把多边形在各纵轴上的点标记出来。
// 添加g分组包含所有雷达图区域 var areas = main.append('g') .classed('areas', true); // 添加g分组用来包含一个雷达图区域下的多边形以及圆点 areas.selectAll('g') .data(areasData) .enter() .append('g') .attr('class',function(d, i) { return 'area' + (i+1); }); for(var i=0;i<areasData.length;i++) { // 依次循环每个雷达图区域 var area = areas.select('.area' + (i+1)), areaData = areasData[i]; // 绘制雷达图区域下的多边形 area.append('polygon') .attr('points', areaData.polygon) .attr('stroke', function(d, index) { return getColor(i); }) .attr('fill', function(d, index) { return getColor(i); }); // 绘制雷达图区域下的点 var circles = area.append('g') .classed('circles', true); circles.selectAll('circle') .data(areaData.points) .enter() .append('circle') .attr('cx', function(d) { return d.x; }) .attr('cy', function(d) { return d.y; }) .attr('r', 3) .attr('stroke', function(d, index) { return getColor(i); }); }
这里为了体验层次关系,我用areas包含住所有雷达图区域,又在里面用一个g分组表示一个雷达图区域,在雷达图区域里包含组成该区域的多边形和圆点。这里因为我们数据用一个雷达图区域就表示了,所以这个for循环只会循环一次。给绘制好的区域加上样式。
.areas polygon { fill-opacity: 0.5; stroke-width: 3; } .areas circle { fill: white; stroke-width: 3; }
于是得到了下图这个样子的图表。
计算文字标签坐标并添加
为了让上面的图表更完整一些,我们给它加上文字标签。文字标签标注在网轴的外围,所以可以以计算网轴多边形点坐标的同样的原理计算文字标签的坐标。
// 计算文字标签坐标 var textPoints = []; var textRadius = radius + 20; for(var i=0;i<total;i++) { var x = textRadius * Math.sin(i * onePiece), y = textRadius * Math.cos(i * onePiece); textPoints.push({ x: x, y: y }); }
计算好坐标以后再添加到画布中。
// 绘制文字标签 var texts = main.append('g') .classed('texts', true); texts.selectAll('text') .data(textPoints) .enter() .append('text') .attr('x', function(d) { return d.x; }) .attr('y', function(d) { return d.y; }) .text(function(d,i) { return data.fieldNames[i]; });
最后的样子是这样的。
总结
以上就是利用D3.js实现雷达的全部内容,希望这篇文章对大家的学习和工作能有所帮助。如果有疑问大家可以留言交流,感兴趣的朋友们请大家继续关注脚本之家。
您可能感兴趣的文章: