2013-06-12 49 views
8

我使用html5畫布元素繪製了一個圖形,其中點表示here中的各個點。顯示在畫布上的工具提示圖

我想在鼠標懸停的不同點上顯示不同的工具提示。要顯示爲工具提示的文本將由用戶提供。

我試過,但無法弄清楚如何將工具提示在graph.The代碼添加到各個點我使用的顯示點的..

// 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(); 
} 

我應該做的是什麼此外此代碼,以便我能夠顯示用戶輸入爲工具提示?

回答

17

您可以顯示工具提示,當用戶在圖表的數據點

移動

這個工具提示只是第二個畫布,它從鏈接的文本框中繪製文本,並將其自身定位在數據點之上。

首先您創建一個數組來存放每個數據點的工具提示信息。

var dots = []; 

對於每一個提示,你將需要:

  • 的X/Y數據點的座標,
  • 數據點的半徑,
  • 的的ID文本框,你想得到的提示。
  • 您還需要RXR總是平方(命中測試時使用)==半徑

這裏是存儲在點創建工具提示信息的代碼[]

// 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) 
     }); 
    } 

然後,設置建立一個mousemove處理程序,通過點陣數組來查看。工具提示顯示如果任何數據=點內的用戶移動:

// 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"; } 
    } 

[編輯,以適合你的代碼]

這裏是代碼和一個小提琴: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"; } 
    } 

//不變的代碼如下

// 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

我試着將你的代碼合併到我的代碼中http://jsfiddle.net/nshX6/9/。即使我沒有收到錯誤,我也沒有收到任何輸出。我在做什麼我的代碼錯誤..請幫助.. – Lucy

+0

我編輯了我的答案,以顯示如何在圖表中包含工具提示。快樂的編碼! :) – markE

+0

非常感謝你的幫助!!!! :)代碼的作品像魅力!!! :) :) – Lucy

0

簡短的回答:正如你現在所做的那樣,你不能。

長答案:你可以,但你需要每30毫秒左右得到一個確切的鼠標位置。對於每毫秒,您必須檢查鼠標是否懸停在點上,重新繪製屏幕並顯示工具提示是否正在執行。自己這樣做可能很乏味,這就是爲什麼我使用gee.js

看看這個例子:http://jsfiddle.net/Saturnix/Aexw4/

這是控制鼠標懸停表達:

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

你可以給在文本框中的值被顯示爲工具提示???爲例,它gee.js的網站上說,它是不再支持一個應該使用paper.js而不是.. – Lucy

-3

此處僅使用CSS方法。不需要JavaScript,JQUERY或特殊庫。輕便,性感。

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; 
} 

這裏是小提琴。 http://jsfiddle.net/honkskillet/RKnEu/

+0

這不回答原來的問題。您可以在控件上繪製工具提示。他希望根據畫布內容在畫布內的任何位置繪製它。如果他有2個圈子,他希望能夠在每個圈子附近顯示1個不同的工具提示。考慮到圓圈的位置是動態的。 –

1

我試過了markE的解決方案,它的工作完美無瑕,除了當您向下滾動一點點時(例如,當您的畫布在網站上稍微向下時)。

那麼當你使用的MouseEvent您的鼠標懸停是公認的立場將轉向底部相同的長度和它可能發生,他們最終畫布之外,並不會在所有被認可的

.pageX和mouseEvent.pageY而不是.clientX和.clientY,你應該沒問題。對於更多的上下文,這裏是我的代碼:

// 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"; 
    } 
});