2011-08-09 42 views
19

Tôi đang cố gắng để tạo ra một biểu đồ pie đơn giản như thể hiện trong hình bên dưới:HTML5 Canvas biểu đồ hình tròn

enter image description here

Biểu đồ sẽ hiển thị các kết quả cho một bài kiểm tra mà người dùng có thể chọn hoặc là một, b hoặc c. Đó là 10 câu hỏi và người dùng chỉ có thể chọn một tùy chọn cho mỗi câu hỏi.

Điều tôi muốn làm là hiển thị biểu đồ hình tròn với mỗi phân đoạn là phần trăm 100% bằng cách chuyển các giá trị cho a, b hoặc c.

Tôi đã sau cho đến nay:

var greenOne = "#95B524"; 
 
var greenTwo = "#AFCC4C"; 
 
var greenThree = "#C1DD54"; 
 

 
function CreatePieChart() { 
 
    var chart = document.getElementById('piechart'); 
 
    var canvas = chart.getContext('2d'); 
 
    canvas.clearRect(0, 0, chart.width, chart.height); 
 

 
    var total = 100; 
 

 
    var a = 3; 
 
    var b = 4; 
 
    var c = 3; 
 

 
    for (var i = 0; i < 3; i++) { 
 
    canvas.fillStyle = "#95B524"; 
 
    canvas.beginPath(); 
 
    canvas.strokeStyle = "#fff"; 
 
    canvas.lineWidth = 3; 
 
    canvas.arc(100, 100, 100, 0, Math.PI * 2, true); 
 
    canvas.closePath(); 
 
    canvas.stroke(); 
 
    canvas.fill(); 
 
    } 
 
} 
 
CreatePieChart();
<canvas id="piechart" width="200" height="200"></canvas>

Những màu sắc đặc trưng cho kích thước của phân khúc này, vì vậy một màu xanh lá cây được sử dụng cho những lớn nhất và màu xanh lá cây ba cho nhỏ nhất.

Cảm ơn

+0

Một chút nỗ lực nữa có thể đi một chặng đường dài. Vấn đề của bạn chính xác là gì? – TJHeuvel

+2

Tôi không chắc bắt đầu từ đâu với dữ liệu và vẽ biểu đồ – Cameron

Trả lời

28

Ngay cả sau khi tìm kiếm Google và triple-kiểm tra radian giá trị của tôi, vv Tôi đã vẫn gặp rắc rối với điều này, vì vậy tôi đã tạo ra một jsFiddle cho người chơi với như một tấm gương sống và ý chí đăng mã dưới đây.

var canvas = document.getElementById("can"); 
 
var ctx = canvas.getContext("2d"); 
 
var lastend = 0; 
 
var data = [200, 60, 15]; // If you add more data values make sure you add more colors 
 
var myTotal = 0; // Automatically calculated so don't touch 
 
var myColor = ['red', 'green', 'blue']; // Colors of each slice 
 

 
for (var e = 0; e < data.length; e++) { 
 
    myTotal += data[e]; 
 
} 
 

 
for (var i = 0; i < data.length; i++) { 
 
    ctx.fillStyle = myColor[i]; 
 
    ctx.beginPath(); 
 
    ctx.moveTo(canvas.width/2, canvas.height/2); 
 
    // Arc Parameters: x, y, radius, startingAngle (radians), endingAngle (radians), antiClockwise (boolean) 
 
    ctx.arc(canvas.width/2, canvas.height/2, canvas.height/2, lastend, lastend + (Math.PI * 2 * (data[i]/myTotal)), false); 
 
    ctx.lineTo(canvas.width/2, canvas.height/2); 
 
    ctx.fill(); 
 
    lastend += Math.PI * 2 * (data[i]/myTotal); 
 
}
<canvas id="can" width="200" height="200" />

+1

Tôi thích điều này, nó cực kỳ đơn giản, rất nhẹ, không yêu cầu bất kỳ tập lệnh bên ngoài nào như jQuery, v.v. Điều này tốt cho tôi vì tôi định sử dụng hàng trăm trong số này được tải thông qua một yêu cầu một phần lol – RedactedProfile

+0

Điều này thật tuyệt! Tôi có thể chỉ cần thêm rằng nếu bạn muốn các phân đoạn để bắt đầu từ vị trí nửa đêm, khởi tạo 'var lastend = -1.57'. 1,57 là một phần tư số radian trong một vòng tròn. Cảm ơn. –

3

Tôi thích câu trả lời trước, nhưng tôi cảm thấy nó còn thiếu trong mã rõ ràng và nó đã không thực sự giới thiệu cách sử dụng các nhãn.

Tôi đã chuyển giá trị vào mảng đối tượng dữ liệu để dễ khai báo. Các giá trị khác, như phần trăm, tôi đã khai báo rõ ràng là thuộc tính trên đối tượng dữ liệu hoặc dưới dạng biến riêng biệt. Điều này, tôi nghĩ, làm cho nó dễ đọc hơn.

Các refactoring cũng làm cho nó dễ dàng hơn để buộc các giá trị để hộp đầu vào nếu đó là một cái gì đó bạn quan tâm đến

Để xem những gì tôi có ý nghĩa và vui chơi với các giá trị kiểm tra CodePen này:. http://codepen.io/zfrisch/pen/pRbZeb

var data = [{ 
 
    label: "one", 
 
    value: 100, 
 
    color: 'white' 
 
    }, { 
 
    label: "two", 
 
    value: 100, 
 
    color: 'skyBlue' 
 
    }, { 
 
    label: "three", 
 
    value: 100, 
 
    color: 'yellow' 
 
    }]; 
 

 
    var total = 0; 
 
    for (obj of data) { 
 
    total += obj.value; 
 
    } 
 

 
    var canvas = document.getElementById('myCanvas'); 
 
    var ctx = canvas.getContext('2d'); 
 
    var previousRadian; 
 
    var middle = { 
 
    x: canvas.width/2, 
 
    y: canvas.height/2, 
 
    radius: canvas.height/2, 
 
    }; 
 
    
 
    //background 
 
    ctx.beginPath(); 
 
    ctx.arc(middle.x, middle.y, middle.radius, 0, 2 * Math.PI); 
 
    ctx.closePath(); 
 
    ctx.stroke(); 
 
    ctx.fillStyle = "black"; 
 
    ctx.fill(); 
 
    //end of background 
 

 
    for (obj of data) { 
 
    previousRadian = previousRadian || 0; 
 
    obj.percentage = parseInt((obj.value/total) * 100) 
 
    
 
    ctx.beginPath(); 
 
    ctx.fillStyle = obj.color; 
 
    obj.radian = (Math.PI * 2) * (obj.value/total); 
 
    ctx.moveTo(middle.x, middle.y); 
 
    //middle.radius - 2 is to add border between the background and the pie chart 
 
    ctx.arc(middle.x, middle.y, middle.radius - 2, previousRadian, previousRadian + obj.radian, false); 
 
    ctx.closePath(); 
 
    ctx.fill(); 
 
    ctx.save(); 
 
    ctx.translate(middle.x, middle.y); 
 
    ctx.fillStyle = "black"; 
 
    ctx.font = middle.radius/10 + "px Arial"; 
 
    ctx.rotate(previousRadian + obj.radian); 
 
    var labelText = "'" + obj.label + "' " + obj.percentage + "%"; 
 
    ctx.fillText(labelText, ctx.measureText(labelText).width/2, 0); 
 
    ctx.restore(); 
 

 
    previousRadian += obj.radian; 
 
    }
<canvas id="myCanvas" width="500" height="500" ></canvas>

0

tôi đã cùng một vấn đề trước đây nhưng tôi đã có thể giải quyết vấn đề này sau.

Những gì tôi đã bỏ lỡ là tôi đã vẽ một vòm trong bối cảnh và đang cố lấp đầy nó, do màu sắc đang lan rộng khắp vòng tròn bởi vì hiện tại bối cảnh chỉ bị ràng buộc giữa đường bán kính từ trung tâm đến điểm bắt đầu điểm của vòm và vòm để ràng buộc bối cảnh.

Nhưng không có ranh giới khác dòng từ cuối vòm đến trung tâm, ngay sau khi tôi vẽ dòng đó bằng cách sử dụng sau đây:

ctx.lineTo(center coordinates of circle); 

Tôi có một ranh giới hoàn toàn của một chiếc bánh, vì vậy bây giờ nếu tôi điền vào màu trong ngữ cảnh, nó sẽ không bị lây lan bên trong toàn bộ vòng tròn nhưng sẽ bị giới hạn ở chiếc bánh đó.

Các vấn đề liên quan