如何在D3.js中在雷达图上定位交点处的圆/点

How to position circles/points at intersection on a Radar Chart in D3.js

本文关键字:定位 D3 js 雷达图      更新时间:2023-09-26

我正在绘制雷达图。我已经添加了一些圆圈,我正试图在交叉点定位。然而,圆的cx and cy属性似乎有问题,我无法弄清楚。

如有任何帮助,我们将不胜感激。

var dataset = [{
  "day": 1,
  "sales": 40
}, {
  "day": 2,
  "sales": 85
}, {
  "day": 3,
  "sales": 70
}, {
  "day": 4,
  "sales": 30
}, {
  "day": 5,
  "sales": 85
}, {
  "day": 6,
  "sales": 60
}, {
  "day": 7,
  "sales": 85
}, {
  "day": 8,
  "sales": 35
}, {
  "day": 9,
  "sales": 70
}, {
  "day": 10,
  "sales": 15
}];
var w = 460,
  h = 460;
var margin = {
  top: 20,  bottom: 10,  left: 10,  right: 10
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
var circleConstraint = d3.min([height, width]);
var radius = d3.scale.linear()
  .domain([0, 100])
  .range([0, (circleConstraint / 2)]);
var centerXPos = width / 2 + margin.left;
var centerYPos = height / 2 + margin.top;
var svg = d3.select("body").append("svg")
  .attr("width", w)
  .attr("height", h)
  .append("g")
  .attr("transform", "translate(" + centerXPos + ", " + centerYPos + ")");
//Adds circular gridLines and labels
var gridLines = [0, 20, 40, 60, 80, 100];
var circleAxes = svg.selectAll(".circularGrid")
  .data(gridLines)
  .enter().append("g")
  .attr("class", "circularGrid");
circleAxes.append("circle")
  .attr("r", function(d) {
    return radius(d);
  })
  .style("stroke", "#CCC")
  .style("fill", "none");
circleAxes.append("text")
  .attr("text-anchor", "middle")
  .attr("dy", function(d) {
    return radius(-d - 1);
  })
  .text(String)
  .style("font-size", "10pt")
  .style("font-family", "sans-serif");
//Append path for salesLine
var sales = [];
dataset.forEach(function(d) {
  sales.push(d.sales);
});
svg.selectAll(".salesLine")
  .data([sales])
  .enter().append("path")
  .attr("class", "salesLine")
  .style("fill", "none")
  .style("stroke", "#000")
  .attr("d", d3.svg.line.radial()
    .radius(function(d) {
      return radius(d);
    })
    .angle(function(d, i) {
      return (i / dataset.length) * 2 * Math.PI;
    }));
// Appending circles at intersections
svg.selectAll(".datapoints")
  .data(dataset).enter()
  .append("circle")
  .attr("class", "datapoints")
  .attr("r", 3)
  .style("fill", "#4393c3")
  .attr("cx", function(d) {
    return radius(d.day);
  })
  .attr("cy", function(d) {
    return radius(d.sales);
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

要修复代码,您应该实现一点三角函数:

// Appending circles at intersections
svg.selectAll(".datapoints")           // it doubles line [*]
  .data(dataset).enter()
  .append("svg:circle")                // full notation for the node
  .classed({"datapoints": true})       // [*] selection.classed() method for classes,
                                       // but you can omit this line because you wrote .selectAll(".datapoints") above
  .attr({"r": 10, "fill": "#4393c3"})  // you must make big dots 
                                       // to be clickable for people
  .attr("cx", function(d, i) {
        var alpha = (2 * Math.PI / dataset.length) * i;
        return( radius(d.sales) * Math.cos(alpha - Math.PI / 2) ); // just as in trigonometry book
  })
  .attr("cy", function(d, i) {
        var alpha = (2 * Math.PI / dataset.length) * i;
        return( radius(d.sales) * Math.sin(alpha - Math.PI / 2) );
  })
  .on("click", function(d){
        alert("$" + d.sales);
  })                                // now you can click on it to see the sales value
  .on("mouseover", function(d){     // little kiss of animation
    d3.select(this).attr("r", "14");
  })
  .on("mouseout", function(d){
    d3.select(this).attr("r", "10");
  });

演示:http://jsbin.com/jitepuhitu/1/

演示(动画):http://jsbin.com/niculecuzo/2/

我建议您绘制类似标记的数据点:

演示:http://jsbin.com/sepunibove/2/

顺便说一下,多条.attr()线路:

.attr("class", "datapoints")
.attr("r", 3)

你可以像单个关联数组一样编写:

.attr({"class": "datapoints", "r": 3})