2017-03-23 2 views
0

동적 레이다 차트를 만들고 있는데, 코드를 검토 한 후 동료 SO 멤버의 권고를 따랐습니다. 강조의 지점을 이동하는 가정입니다, 당신이 지점을 클릭하면다이나믹 레이더 차트 포인트 추적하기

var canv = document.getElementById('canvas'); 
 
var canv1 = document.getElementById('canvas1'); 
 
var point_xy = document.getElementById('point_xy'); 
 
var tipCanvas = document.getElementById("tip"); 
 
var tipCtx = tipCanvas.getContext("2d"); 
 
var point_xy_cords = [ 
 
    [] 
 
]; 
 
var pentagon_one = 24; 
 
var pentagon_two = 18; 
 
var pentagon_three = 12; 
 
var pentagon_four = 6; 
 
var pentagon_five = 0; 
 
var circles = []; 
 
var contx = canv.getContext('2d'); 
 
var contx1 = canv1.getContext('2d'); 
 
var offsetX = canv1.offsetLeft; 
 
var offsetY = canv1.offsetTop; 
 
contx.clearRect(0, 0, canv.width, canv.height); 
 

 
function drawShape(ctx, x, y, points, radius1, radius2, alpha0) { 
 
    //points: number of points (or number of sides for polygons) 
 
    //radius1: "outer" radius of the star 
 
    //radius2: "inner" radius of the star (if equal to radius1, a polygon is drawn) 
 
    //angle0: initial angle (clockwise), by default, stars and polygons are 'pointing' up 
 
    var radius_size = radius1; 
 
    var i, angle, radius; 
 
    if (radius2 !== radius1) { 
 
    points = 2 * points; 
 
    } 
 
    for (var i = 0; i <= 5; i++) { 
 
    var temp = []; 
 
    contx1.beginPath(); 
 
    for (var j = 0; j <= 4; j++) { 
 
     angle = j * 2 * Math.PI/points - Math.PI/2 + alpha0; 
 
     radius = j % 2 === 0 ? radius_size : radius_size; 
 
     temp[j] = [(x + radius_size * Math.cos(angle)), (y + radius_size * Math.sin(angle))]; 
 
     ctx.lineTo(temp[j][0], temp[j][1]); 
 
    } 
 
    ctx.closePath(); 
 
    style(ctx); 
 
    radius_size = radius_size - 20; 
 
    point_xy_cords.push(temp); 
 
    } 
 
    point_xy.textContent = "[1] = " + point_xy_cords[1] + " y = " + point_xy_cords[1][1]; 
 
} 
 

 
function style(ctx, fill) { 
 
    ctx.strokeStyle = "rgba(0, 109, 0, 1)"; 
 
    ctx.lineWidth = 2; 
 
    if (fill) { 
 
    ctx.fillStyle = "rgba(74, 157, 33, 0.6)"; 
 
    ctx.fill(); 
 
    } else { 
 
    ctx.stroke() 
 
    } 
 

 
    //contx.fill(); 
 
} 
 

 
var radius = 2; 
 

 
var Circle = function(x, y, radius) { 
 
    this.left = x - radius; 
 
    this.top = y - radius; 
 
    this.right = x + radius; 
 
    this.bottom = y + radius; 
 
    this.point_clicked = []; 
 
    
 
    this.clicked = function(){ 
 
    points[1][0] = x; //hardcoded part 
 
    points[1][1] = y; //hardcoded part 
 
    contx1.clearRect(0, 0, canv.width, canv.height); 
 
    drawBackgroundPentagons(contx1); 
 
    drawMainPentagon(contx1, points); 
 
    drawPoints(); 
 
    } 
 

 
    this.draw = function(ctx) { 
 
    //Draw all points 
 
    
 
    ctx.beginPath(); 
 
    ctx.arc(x, y, 2, 0, 2 * Math.PI, false); 
 
    ctx.lineWidth = 1; 
 
    ctx.strokeStyle = "rgba(74, 157, 33, 1)"; 
 
    ctx.fill(); 
 
    ctx.stroke(); 
 
    } 
 
    
 
    this.containsPoint = function(x,y){ 
 
    \t return (x < this.right && x > this.left && y > this.top && y < this.bottom); 
 
    } 
 
}; 
 

 
//Draw background 
 
function drawBackgroundPentagons(ctx) { 
 
    drawShape(ctx, 120, 120, 5, 100, 100, 0); 
 
} 
 
drawBackgroundPentagons(contx1); 
 

 
//Draw all the points 
 
function drawPoints(){ 
 
    for (var x = 1; x <= 5; x++){ 
 
    for (var y = 0; y <= 4; y++){ 
 
     var circle = new Circle(point_xy_cords[x][y][0], point_xy_cords[x][y][1], 8); 
 
     circle.draw(contx1); 
 
     circles.push(circle); 
 
    } 
 
    } 
 
} 
 
drawPoints(); 
 
function drawMainPentagon(ctx, points) { 
 
    ctx.beginPath(); 
 
    ctx.moveTo(points[0][0], points[0][1]); 
 
    for (var x = 1; x <= 4; x++) { 
 
    ctx.lineTo(points[x][0], points[x][1]); 
 
    } 
 
    style(ctx, "fill"); 
 
    \t ctx.closePath(); 
 
} 
 

 
points = point_xy_cords[1]; 
 
drawMainPentagon(contx1, points); 
 

 
function handleMouseDown(e, message) { 
 

 
    point_xy.textContent = (message); 
 
} 
 

 
function getMousePos(canvas, evt) { 
 
    var rect = canvas.getBoundingClientRect(); 
 
    return { 
 
    x: evt.clientX - rect.left, 
 
    y: evt.clientY - rect.top 
 
    }; 
 
} 
 

 
canv1.onmousedown = function(e) { 
 
    var pos = getMousePos(canv1, e); 
 
    var clickedX = pos.x; 
 
    var clickedY = pos.y; 
 

 

 
    var tooltipText = "nothing"; 
 
    
 
    for (var i = 0; i < circles.length; i++) { 
 
    var circle = circles[i]; 
 
    if (circle.containsPoint(clickedX, clickedY)) { 
 
     circle.clicked(); 
 
     return; 
 
    } 
 
\t } 
 
    tooltip("points[0]", clickedX, clickedY); 
 
}; 
 

 
function tooltip(text, clickedX, clickedY) { 
 
    tipCtx.fillStyle = "black"; 
 
    tipCtx.fillRect(0, 0, canvas.width, canvas.height); 
 
    tipCtx.fillStyle = "white"; 
 
    tipCtx.fillText(text, 5, 10); 
 
    tipCanvas.style.left = (clickedX + 15) + "px"; 
 
    tipCanvas.style.top = (clickedY - 26) + "px"; 
 
} 
 

 
canv1.onmouseover = function(e) { 
 
    return null; 
 

 
} 
 
canv1.onmouseout = function(e) { 
 
    return null; 
 
} 
 
canv1.onmousemove = function(e) { 
 
    return null; 
 
}
#tip { 
 
    left: -200px; 
 
    top: 100px; 
 
    position: absolute; 
 
    float: left; 
 
    maxWidth: 200px; 
 
    backgroundColor: rgba(0, 0, 0, 0.8); 
 
    border: rgba(45, 65, 45, 1); 
 
    borderRadius: 5px; 
 
    color: #f9f9f9; 
 
    fontSize: 14px; 
 
    padding: 5px; 
 
    textAlign: left; 
 
}
<div id="canvasesdiv" style="position:relative; width:400px; height:300px"> 
 
    <canvas id="tip" width=100 height=100 style="z-index: 3;"></canvas> 
 
    <canvas id="canvas" style="z-index: 1; 
 
position:absolute; 
 
left:10px; 
 
top:10px; 
 
" height="300px" width="400"> 
 
    This text is displayed if your browser does not support HTML5 Canvas. 
 
    </canvas> 
 
    <canvas id="canvas1" style="z-index: 2; 
 
position:absolute; 
 
left:10px; 
 
top:10px; 
 
" height="300px" width="400"> 
 
    This text is displayed if your browser does not support HTML5 Canvas. 
 
    </canvas> 
 

 
</div> 
 
<div id='point_xy'></div>

:

이 내가 장애물에 충돌 한 올하지만 보인다했습니다 얼마나 멀리입니다 오각형을 클릭 지점으로 가져옵니다. 그것은 강조된 5 각형의 정확한 구석을 이동시키기 위해 어떤 조건을 더할 수 없는지를 제외하고는 작동합니다. 위의 코드에서 필자는 하드 코드하여 어떤 점을 클릭하든 인덱스 0으로 이동합니다.

어느 방향 으로든 감상 할 수 있습니다.

답변

1

그럼 원하는 것은 각 원에 spoke 또는 radii이 속한 것을 알리는 것입니다. 이런 식으로 뭔가 :

var Circle = function(x, y, radius, spoke, value) { 
    this.x = x; 
    this.y = y; 
    this.radius = radius; 
    this.spoke = spoke; 
    this.value = value; 

지금처럼 무엇인가를 만들 :

function drawPoints() { 
    for (var value = 1; value <= 5; value++){ 
    for (var spoke = 0; spoke <= 4; spoke++){ 
     var circle = new Circle(point_xy_cords[value][spoke][0], point_xy_cords[value][spoke][1], 8, spoke, value); 
     circle.draw(contx1); 
     circles.push(circle); 
    } 
    } 
} 

내가 의미있는에 변수 이름을 변경했습니다. 여기서 한 가지 메모는 코드를 만들어 서클을 만들고 코드를 그리는 것입니다. 너는 이것을 원하지 않는다. 초기화 할 때 한 번 생성하고 변경 사항을 적용 할 때 클릭하여 다시 그립니다. 다시 그릴 때마다 서클을 다시 만들고 싶지 않습니다. 내가 제안을 할 수있는 경우,

function updateCanvas() { 
    contx1.clearRect(0, 0, canv.width, canv.height); 
    drawBackgroundPentagons(contx1); 
    drawMainPentagon(contx1, points); 
    drawPoints(); 
} 

당신이 할 수있는 가장 간단한 코드로 시작 : 다른

// Circle 
this.clicked = function(){ 
    points[this.spoke][0] = this.x; 
    points[this.spoke][1] = this.y; 
    updateCanvas(); 
} 

과 :

은 마지막으로이를 변경합니다. 원과 오각형을 표시하는 것부터 시작하여 깨끗하게 작업하고 빌드하십시오. 코드에서 로직을 분리하여 유지하십시오. 드로잉을하는 동안 객체를 생성하고 배열을 초기화하는 곳 (예 : coords)이 둘 다 불필요한 것이 아니라 한 번만 반복하지 않고 계속 반복하는 것을 의미합니다. 불필요한 많은 코드가 여기에 있습니다.