You can display tooltips when a user moves around your point-to-point chart
This tooltip is just the second canvas that draws text from the linked text box and takes up positions above the data point.
First, you create an array to store tooltip information for each of your data points.
var dots = [];
For each hint you will need:
- X / y coordinate of the data point,
- Radius of the data point,
- The identifier of the text field from which you want to receive feedback.
- You also need rXr, which is always equal to the square of the radius (necessary during testing when testing)
Here is the code for creating tooltip information that will be stored in dots []
// 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) }); }
Then you create a mousemove handler that looks at an array of points. A tooltip is displayed if the user moves inside any data = 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"; } }
[Edited to be inserted into your code]
Here is the code and script: http://jsfiddle.net/m1erickson/yLBjM/
<!doctype html> <html> <head> <link rel="stylesheet" type="text/css" media="all" href="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;
// immutable code follows
// 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>