2015-03-30 4 views
0

Я работаю над радаром. Я добавил несколько кругов, которые я пытаюсь установить на пересечениях. Однако, кажется, что-то не так с атрибутами cx and cy кругов, которые я не могу понять.Как разместить круги/точки на пересечении на радарной диаграмме в D3.js

Любая помощь с этим будет принята с благодарностью.

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>

+0

Прошу прощения, вы можете уточнить вопрос немного? Вы пытаетесь расположить точки на пересечениях между линиями и кругами? – nick

+0

@nick - Извинения за путаницу. Я просто хотел разместить точки на линии/пути, похожие на график рассеяния, связанный с линией. Забудьте о серых кругах, это просто линии сетки. – Adnan

ответ

2

Чтобы исправить код, вы должны реализовать немного тригонометрии:

// 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 (анимация): http://jsbin.com/niculecuzo/2/

+0

Я рекомендую вам http://en.wikipedia.org/wiki/Polar_coordinate_system и https://www.khanacademy.org/math/precalculus/parametric_equations/polar_coor/v/polar-coordinates-1 И вы знаете, все начинается с математико. –

+0

Я рассмотрю их. Приветствия. – Adnan

0

Я рекомендую вам рисовать точки данных как маркеры:

DEMO: http://jsbin.com/sepunibove/2/

Кстати, несколько .attr() линий:

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

вы можете написать как единый ассоциативный массив:

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

Большое спасибо Рубину, это тоже будет. Мне просто интересно, знаете ли вы, как изменить положение точек, используя атрибуты 'cx и cy', как это было в моем коде? Это довольно просто на линейной диаграмме, но я просто не мог их переместить на радиолокационную карту из-за своих полярных координат, я думаю. – Adnan