2013-06-12 8 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

ときに、チャートのデータ・ドット

の上にユーザが移動あなたはツールチップを表示することができます

このツールチップは、リンクされたテキストボックスからテキストを描画し、データドットの上に位置する2番目のキャンバスです。

まず、各データドットのツールチップ情報を保持する配列を作成します。

各ツールチップについて
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

短い答え:これまでやったように、できません。

長い回答:30millisecondsほど正確なマウス位置を取得する必要があります。各ミリ秒ごとに、マウスがドットの上をホバリングしているかどうかを確認し、画面を再描画し、実行している場合はツールチップを表示する必要があります。あなた自身でそれを行うことは面倒なことがあります。これが私が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のウェブサイト上で述べていないと1つは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を使用します.clientXと.clientYの代わりに.pageXとmouseEvent.pageYを使用すると、うまくいくはずです。より多くのコンテキストの場合、ここに私のコードは次のとおりです。

// 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"; 
    } 
}); 
関連する問題