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>

あなたがポイントをクリックすると、強調表示のポイントを移動すると仮定されます五角形をクリックします。強調表示された五角形の正しい角を移動するために追加する条件を特定できないことを除いて、機能します。上のコードでは、私はそれをハードコーディングしているので、どの点をクリックしてもインデックス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など)がいくつかありますが、いずれも非抽象であるだけでなく、1度ではなく何度も繰り返すこともあります。ここには不要なコードもたくさんあります。

関連する問題