I am working on a Radar chart. I have appended some circles that I am trying to position at intersections. However, there seems to be something wrong with the cx and cy
attributes of the circles, which I am unable to figure out.
Any help with this will be greatly appreciated.
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>
To fix the code, you should implement little bit of trigonometry:
// 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");
});
DEMO: http://jsbin.com/jitepuhitu/1/
DEMO (animation): http://jsbin.com/niculecuzo/2/
I recommend you to draw data points like markers:
DEMO: http://jsbin.com/sepunibove/2/
By the way, multiple .attr()
lines:
.attr("class", "datapoints")
.attr("r", 3)
you can write like single associative array:
.attr({"class": "datapoints", "r": 3})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.