2013-06-12 50 views
8

Tôi đang sử dụng phần tử canvas html5 để vẽ biểu đồ có dấu chấm biểu thị các điểm khác nhau trong here.Hiển thị chú giải công cụ trong biểu đồ canvas

Tôi muốn hiển thị mẹo công cụ khác nhau trên các điểm khác nhau trên di chuột. Văn bản sẽ được hiển thị dưới dạng công cụ-tip sẽ được cung cấp bởi người dùng.

tôi đã cố gắng nhưng không thể tìm ra cách để thêm công cụ-tip để các điểm khác nhau trong các mã graph.The Tôi đang sử dụng để hiển thị dấu chấm được ..

// Draw the dots 
c.fillStyle = '#333'; 

for (var i = 0; i < data.values.length; i++) { 
    c.beginPath(); 
    c.arc(getXPixel(data.values[i].X), getYPixel(data.values[i].Y), 4, 0, Math.PI * 2, true); 
    c.fill(); 
} 

tôi nên bổ sung gì trong mã này để tôi có thể hiển thị đầu vào của người dùng làm công cụ-tip?

Trả lời

17

Bạn có thể hiển thị tooltips khi người dùng di chuyển của bạn trên của biểu đồ của bạn dữ liệu chấm

Chú giải công cụ này chỉ đơn giản là canvas thứ hai vẽ văn bản từ hộp văn bản được liên kết và là vị trí của chính nó phía trên dấu chấm dữ liệu.

Trước tiên, bạn tạo một mảng để giữ thông tin chú giải công cụ cho mỗi dấu chấm dữ liệu của bạn.

var dots = []; 

Đối với mỗi tooltip, bạn sẽ cần:

  • x/Tọa độ y của dữ liệu chấm,
  • Bán kính của dữ liệu chấm,
  • Id của hộp văn bản bạn muốn nhận mẹo.
  • Bạn cũng cần RXR mà luôn luôn == bán kính bình phương (cần thiết trong quá trình thử nghiệm hit)

Đây là đoạn mã để tạo thông tin tooltip được lưu trữ trong các chấm []

// define tooltips for each data point 

    for(var i = 0; i < data.values.length; i ++) { 
     dots.push({ 
      x: getXPixel(data.values[i].X), 
      y: getYPixel(data.values[i].Y), 
      r: 4, 
      rXr: 16, 
      tip: "#text"+(i+1) 
     }); 
    } 

Sau đó, bạn thiết lập lập trình xử lý mousemove nhìn qua mảng dấu chấm.Các tooltip được hiển thị nếu người dùng di chuyển bên trong bất kỳ dữ liệu = dot:

// request mousemove events 

    $("#graph").mousemove(function(e){handleMouseMove(e);}); 

    // show tooltip when mouse hovers over dot 
    function handleMouseMove(e){ 
     mouseX=parseInt(e.clientX-offsetX); 
     mouseY=parseInt(e.clientY-offsetY); 

     // Put your mousemove stuff here 
     var hit = false; 
     for (var i = 0; i < dots.length; i++) { 
      var dot = dots[i]; 
      var dx = mouseX - dot.x; 
      var dy = mouseY - dot.y; 
      if (dx * dx + dy * dy < dot.rXr) { 
       tipCanvas.style.left = (dot.x) + "px"; 
       tipCanvas.style.top = (dot.y - 40) + "px"; 
       tipCtx.clearRect(0, 0, tipCanvas.width, tipCanvas.height); 
       tipCtx.fillText($(dot.tip).val(), 5, 15); 
       hit = true; 
      } 
     } 
     if (!hit) { tipCanvas.style.left = "-200px"; } 
    } 

[Sửa để phù hợp với mã của bạn]

Đây là mã và một Fiddle: http://jsfiddle.net/m1erickson/yLBjM/

<!doctype html> 
<html> 
<head> 
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 

<style> 
    body{ background-color: ivory; margin-top:35px; } 
    #wrapper{position:relative; width:300px; height:150px;} 
    canvas{border:1px solid red;} 
    #tip{background-color:white; border:1px solid blue; position:absolute; left:-200px; top:100px;} 
</style> 

<script> 
$(function(){ 

    var graph = document.getElementById("graph"); 
    var ctx = graph.getContext("2d"); 
    var tipCanvas = document.getElementById("tip"); 
    var tipCtx = tipCanvas.getContext("2d"); 

    var canvasOffset = $("#graph").offset(); 
    var offsetX = canvasOffset.left; 
    var offsetY = canvasOffset.top; 

    var graph; 
    var xPadding = 30; 
    var yPadding = 30; 

    // Notice I changed The X values 
    var data = { values:[ 
     { X: 0, Y: 12 }, 
     { X: 2, Y: 28 }, 
     { X: 3, Y: 18 }, 
     { X: 4, Y: 34 }, 
     { X: 5, Y: 40 }, 
     { X: 6, Y: 80 }, 
     { X: 7, Y: 80 } 
    ]}; 

    // define tooltips for each data point 
    var dots = []; 
    for(var i = 0; i < data.values.length; i ++) { 
     dots.push({ 
      x: getXPixel(data.values[i].X), 
      y: getYPixel(data.values[i].Y), 
      r: 4, 
      rXr: 16, 
      color: "red", 
      tip: "#text"+(i+1) 
     }); 
    } 

    // request mousemove events 
    $("#graph").mousemove(function(e){handleMouseMove(e);}); 

    // show tooltip when mouse hovers over dot 
    function handleMouseMove(e){ 
     mouseX=parseInt(e.clientX-offsetX); 
     mouseY=parseInt(e.clientY-offsetY); 

     // Put your mousemove stuff here 
     var hit = false; 
     for (var i = 0; i < dots.length; i++) { 
      var dot = dots[i]; 
      var dx = mouseX - dot.x; 
      var dy = mouseY - dot.y; 
      if (dx * dx + dy * dy < dot.rXr) { 
       tipCanvas.style.left = (dot.x) + "px"; 
       tipCanvas.style.top = (dot.y - 40) + "px"; 
       tipCtx.clearRect(0, 0, tipCanvas.width, tipCanvas.height); 
       tipCtx.fillText($(dot.tip).val(), 5, 15); 
       hit = true; 
      } 
     } 
     if (!hit) { tipCanvas.style.left = "-200px"; } 
    } 

// mã không đổi theo sau

// Returns the max Y value in our data list 
    function getMaxY() { 
     var max = 0; 

     for(var i = 0; i < data.values.length; i ++) { 
      if(data.values[i].Y > max) { 
       max = data.values[i].Y; 
      } 
     } 

     max += 10 - max % 10; 
     return max; 
    } 

    // Returns the max X value in our data list 
    function getMaxX() { 
     var max = 0; 

     for(var i = 0; i < data.values.length; i ++) { 
      if(data.values[i].X > max) { 
       max = data.values[i].X; 
      } 
     } 

     // omited 
     //max += 10 - max % 10; 
     return max; 
    } 

    // Return the x pixel for a graph point 
    function getXPixel(val) { 
     // uses the getMaxX() function 
     return ((graph.width - xPadding)/(getMaxX() + 1)) * val + (xPadding * 1.5); 
     // was 
     //return ((graph.width - xPadding)/getMaxX()) * val + (xPadding * 1.5); 
    } 

    // Return the y pixel for a graph point 
    function getYPixel(val) { 
     return graph.height - (((graph.height - yPadding)/getMaxY()) * val) - yPadding; 
    } 

     graph = document.getElementById("graph"); 
     var c = graph.getContext('2d');    

     c.lineWidth = 2; 
     c.strokeStyle = '#333'; 
     c.font = 'italic 8pt sans-serif'; 
     c.textAlign = "center"; 

     // Draw the axises 
     c.beginPath(); 
     c.moveTo(xPadding, 0); 
     c.lineTo(xPadding, graph.height - yPadding); 
     c.lineTo(graph.width, graph.height - yPadding); 
     c.stroke(); 

     // Draw the X value texts 
     var myMaxX = getMaxX(); 
     for(var i = 0; i <= myMaxX; i ++) { 
      // uses data.values[i].X 
      c.fillText(i, getXPixel(i), graph.height - yPadding + 20); 
     } 
     /* was 
     for(var i = 0; i < data.values.length; i ++) { 
      // uses data.values[i].X 
      c.fillText(data.values[i].X, getXPixel(data.values[i].X), graph.height - yPadding + 20); 
     } 
     */ 

     // Draw the Y value texts 
     c.textAlign = "right" 
     c.textBaseline = "middle"; 

     for(var i = 0; i < getMaxY(); i += 10) { 
      c.fillText(i, xPadding - 10, getYPixel(i)); 
     } 

     c.strokeStyle = '#f00'; 

     // Draw the line graph 
     c.beginPath(); 
     c.moveTo(getXPixel(data.values[0].X), getYPixel(data.values[0].Y)); 
     for(var i = 1; i < data.values.length; i ++) { 
      c.lineTo(getXPixel(data.values[i].X), getYPixel(data.values[i].Y)); 
     } 
     c.stroke(); 

     // Draw the dots 
     c.fillStyle = '#333'; 

     for(var i = 0; i < data.values.length; i ++) { 
      c.beginPath(); 
      c.arc(getXPixel(data.values[i].X), getYPixel(data.values[i].Y), 4, 0, Math.PI * 2, true); 
      c.fill(); 
     } 


}); // end $(function(){}); 
</script> 

</head> 

<body> 
    <div id="wrapper"> 
     <canvas id="graph" width=300 height=150></canvas> 
     <canvas id="tip" width=100 height=25></canvas> 
    </div> 
    <br><br> 
    <input type="text" id="text1" value="text 1"/><br><br> 
    <input type="text" id="text2" value="text 2"/><br><br> 
    <input type="text" id="text3" value="text 3"/><br><br> 
    <input type="text" id="text4" value="text 4"/><br><br> 
    <input type="text" id="text5" value="text 5"/><br><br> 
    <input type="text" id="text6" value="text 6"/><br><br> 
    <input type="text" id="text7" value="text 7"/><br><br> 
</body> 
</html> 
+0

tôi đã thử kết hợp mã của bạn trong mã của tôi ở đây http://jsfiddle.net/nshX6/9/. Mặc dù tôi không nhận được một lỗi tôi không nhận được bất kỳ đầu ra hoặc .. những gì tôi đang làm sai trong mã của tôi .. Xin vui lòng giúp đỡ .. – Lucy

+0

Tôi đã chỉnh sửa câu trả lời của tôi để hiển thị làm thế nào để bao gồm tooltips trong biểu đồ của bạn. Chúc mừng mã hóa! :) – markE

+0

Cảm ơn bạn rất nhiều vì sự giúp đỡ của bạn !!!! :) mã hoạt động như quyến rũ !!! :) :) – Lucy

0

Câu trả lời ngắn gọn: như bạn đã làm ngay bây giờ, bạn không thể.

Câu trả lời dài: bạn có thể, nhưng bạn cần phải có được vị trí chuột chính xác sau mỗi 30 giây hoặc lâu hơn. Đối với mỗi mili giây, bạn phải kiểm tra xem con chuột có đang di chuột qua dấu chấm hay không, vẽ lại màn hình và hiển thị chú giải công cụ nếu anh ta đang thực hiện. Làm như vậy một mình có thể tẻ nhạt, đây là lý do tại sao tôi sử dụng gee.js.

Kiểm tra ví dụ này: http://jsfiddle.net/Saturnix/Aexw4/

Đây là biểu hiện mà điều khiển lơ lửng chuột:

g.mouseX < x + r && g.mouseX > x -r && g.mouseY > y -r && g.mouseY < y+r 
+0

bạn có thể đưa ra ví dụ trong đó giá trị hộp văn bản đang được hiển thị dưới dạng chú giải công cụ và nó nói trên trang web của gee.js rằng nó không còn được hỗ trợ nữa một nên sử dụng paper.js thay vì .. – Lucy

-3

Phương thức CSS ONLY tại đây. Không yêu cầu javascript, JQUERY hoặc thư viện đặc biệt. Nhẹ, gợi cảm.

HTML

<!DOCTYPE html> 
<body> 
    <br /> 
    <br /> 
    <br /> 
    <br /> 
<span class="popup" popupText="This is some popup text">Locate </span> 
<img src="http://upload.wikimedia.org/wikipedia/en/thumb/f/f4/The_Scream.jpg/220px-The_Scream.jpg" 
    /> 
<!--I used an image here but it could be anything, including a canvas--> 
</body> 
</html> 

CSS

.popup{ 
    position:absolute; /*allows span to be on top of image*/ 
    border: solid; /*a border, just for demonstration purposes*/ 
    border-color: #333 ; 
    border-width: 1px; 
    width:220px; /*set the height, width equal to the size of your ing/canvas*/ 
    height:280px; 
} 
/*this bit draws the bottom arrow of the popup, it can excluded entire if you don't want it*/ 
.popup:hover:before{ 
    border: solid; 
    border-color: #333 transparent; 
    border-width: 6px 6px 0 6px; 
    bottom: 300px; 
    content: ""; 
    left: 40px; 
    position: absolute; 
    z-index: 99; 
} 
/*this bit draw the main portion of the popup, including the text*/ 
.popup:hover:after{ 
    background: #333; 
    background: rgba(0,0,0,.8); 
    border-radius: 5px; 
    bottom: 306px; 
    color: #fff; 
    content: attr(popupText); /*this is where the text gets introduced.*/ 
    left: 20px; 
    padding: 5px 15px; 
    position: absolute; 
    z-index: 98; 
    width: 150px; 
} 

Đây là fiddle. http://jsfiddle.net/honkskillet/RKnEu/

+0

Điều này không trả lời được câu hỏi gốc. Bạn vẽ tooltip trên đầu trang của điều khiển. Anh ta muốn vẽ nó ở bất cứ đâu bên trong canvas dựa trên nội dung canvas. Nếu anh ấy có 2 vòng kết nối, anh ấy muốn có thể hiển thị 1 chú giải công cụ khác nhau gần mỗi vòng kết nối. Xem xét vị trí vòng kết nối là động. –

1

Tôi đã thử giải pháp của markE và nó hoạt động hoàn hảo, NGOẠI TRỪ rằng khi bạn cuộn xuống một chút (ví dụ: khi bạn đặt canvas xuống một chút).

Sau đó, các vị trí nơi mouseover bạn được công nhận sẽ chuyển đến phía dưới cùng độ dài và nó có thể xảy ra mà họ kết thúc bên ngoài của khung hình và sẽ không được công nhận ở tất cả ...

Khi bạn sử dụng mouseEvent .pageX và mouseEvent.pageY thay vì .clientX và .clientY, bạn nên ổn. Để biết thêm ngữ cảnh, dưới đây là mã của tôi: đây là mã của tôi:

// Filling the dots 
var dots = []; 
// [...] 
dots.push({ 
    x: xCoord, 
    y: yCoord, 
    v: value, 
    r: 5, 
    tooltipRadius2: 7*7 // a little increased radius for making it easier to hit 
}); 
// [...] 

var tooltipCanvas = $('#tooltipCanvas')[0]; 
var tooltipCtx = tooltipCanvas.getContext('2d'); 
var canvasOffset = canvas.offset(); 
canvas.mousemove(function (e) { 

    // getting the mouse position relative to the page - not the client 
    var mouseX = parseInt(e.pageX - canvasOffset.left); 
    var mouseY = parseInt(e.pageY - canvasOffset.top); 

    var hit = false; 
    for (var i = 0; i < dots.length; i++) { 
     var dot = dots[i]; 
     var dx = mouseX - dot.x; 
     var dy = mouseY - dot.y; 
     if (dx * dx + dy * dy < dot.tooltipRadius2) { 
      // show tooltip to the right and below the cursor 
      // and moving with it 
      tooltipCanvas.style.left = (e.pageX + 10) + "px"; 
      tooltipCanvas.style.top = (e.pageY + 10) + "px"; 
      tooltipCtx.clearRect(0, 0, tooltipCanvas.width, tooltipCanvas.height); 
      tooltipCtx.textAlign = "center"; 
      tooltipCtx.fillText(dot.v, 20, 15); 
      hit = true; 
      // when a dot is found, don't keep on searching 
      break; 
     } 
    } 
    if (!hit) { 
     tooltipCanvas.style.left = "-200px"; 
    } 
}); 
Các vấn đề liên quan