Añadir un rótulo flotante

facebook-svg gplus-svg twitter-svg

Esta es una continuación de gráficos de líneas (2)

La función oMousePos

Puede ver la descripción de esta función a la posición del ratón. Lo que hay que saber es que devuelve un objeto con las coordenadas del ratón.


function oMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return { // devuelve un objeto
    x: Math.round(evt.clientX - rect.left),
    y: Math.round(evt.clientY - rect.top)
  };
}

La función rotulador

Cuando el ratón pasa por encima del <canvas> la función rotulador llama la función oMousePos() que detecta la posición del ratón y devuelve un objeto con las coordenadas x e y de este.
Si el ratón ( cuyas coordenadas son mousePos.x y mousePos.y ) esta encima del pequeño círculo

if (ctx.isPointInPath(mousePos.x, mousePos.y)){...}

la función rotulador():
- escribe el rotulo
- hace visible el rotulo ( rotulo.style.display="block"; )
- define la posición del rotulo ( enganchado al ratón )
Observación: Para que el método isPointInPath() funcione, tenemos que volver a esbozar el pequeño círculo.


function rotulador(o, nav, ano) {
  if (typeof window.addEventListener === "function") {
    canvas.addEventListener("mousemove", function(evt) {
      var mousePos = oMousePos(canvas, evt);
      ctx.beginPath();
      // esboza de nuevo el pequeño círculo
      ctx.arc(o, 270 - (oData[nav][ano] * 60) / 15, 5, 0, 2 * Math.PI);

      if (ctx.isPointInPath(mousePos.x, mousePos.y)) {
        rotulo.innerHTML = nav + " - " + ano + "
" + oData[nav][ano] + "%"; rotulo.style.display = "block"; rotulo.style.top = mousePos.y + "px"; rotulo.style.left = mousePos.x + 10 + "px"; return false; } }, false); } }

También habrá que declarar la variable var rotulo y establecer algunas características por defecto de este cuando el ratón pase por encima.


var rotulo = document.getElementById("rotulo");
canvas.addEventListener("mousemove", function(evt) {
  rotulo.innerHTML = "";
  rotulo.style.display = "none";
}, false);

Poniendolo todo junto



var canvas = document.getElementById("lienzo");
if (canvas && canvas.getContext) {
  var ctx = canvas.getContext("2d");
  if (ctx) {
   var oData = {
	"IE":	  {"2008":"54.7","2009":"44.8", "2010":"36.2", "2011":"26.6", "2012":"20.1",  "2013":"14.3", "2014":"10.2", "color":"#6495ED"},
	"Firefox":{"2008":"36.4","2009":"45.5", "2010":"46.3", "2011":"42.8", "2012":"37.2",  "2013":"30.2", "2014":"26.9", "color":"#FF8C00"},
	"Chrome": {"2008":"0",   "2009":"3.9",  "2010":"10.8", "2011":"23.8", "2012":"35.3",  "2013":"48.4", "2014":"55.7", "color":"#FFD700"},
	"Safari": {"2008":"1.9", "2009":"3.0",  "2010":"3.7",  "2011":"4.0",  "2012":"4.3",   "2013":"4.2",  "2014":"3.9",  "color":"#32CD32"},
	"Opera":  {"2008":"1.4", "2009":"2.3",  "2010":"2.2",  "2011":"2.5",  "2012":"2.4",   "2013":"1.9",  "2014":"1.8",  "color":"#DC143C"}
	};

    function rotulador(o, nav, ano) {
      if (typeof window.addEventListener === "function") {
        canvas.addEventListener("mousemove", function(evt) {
          var mousePos = oMousePos(canvas, evt);
          ctx.beginPath();
          // esboza de nuevo el pequeño círculo
          ctx.arc(o, 270 - (oData[nav][ano] * 60) / 15, 5, 0, 2 * Math.PI);

          if (ctx.isPointInPath(mousePos.x, mousePos.y)) {
            rotulo.innerHTML = nav + " - " + ano + "
" + oData[nav][ano] + "%"; rotulo.style.display = "block"; rotulo.style.top = mousePos.y + "px"; rotulo.style.left = mousePos.x + 10 + "px"; return false; } }, false); } } function oMousePos(canvas, evt) { var rect = canvas.getBoundingClientRect(); return { // devuelve un objeto x: Math.round(evt.clientX - rect.left), y: Math.round(evt.clientY - rect.top) }; } // características por defecto de rotulo on mousemove encima del canvas var rotulo = document.getElementById("rotulo"); canvas.addEventListener("mousemove", function(evt) { rotulo.innerHTML = ""; rotulo.style.display = "none"; }, false); function laLeyenda() { // las coordenadas de la esquina derecha arriba de la leyenda var ly = 160; var lx = 500; ctx.textBaseline = "top"; ctx.textAlign = "left"; ctx.font = "12px Verdana"; for (var nav in oData) { ctx.beginPath(); // el color que representa el navegador ctx.fillStyle = oData[nav]["color"]; // la casilla ctx.fillRect(lx, ly, 15, 15); ctx.beginPath(); ctx.fillStyle = "blue"; // el nombre del navegador ctx.fillText(nav, lx + 25, ly); // calcula el valor de ly para la siguiente línea ly += 23; } } // construye la cuadricula // dibuja el eje vertical ctx.strokeStyle = "#ccc"; ctx.lineWidth = 1; ctx.save(); ctx.translate(0.5, 0); ctx.beginPath(); ctx.moveTo(45, 25); ctx.lineTo(45, 275); ctx.stroke(); ctx.restore(); // define el estilo de texto ctx.font = "12px Verdana"; ctx.fillStyle = "blue"; ctx.textAlign = "right"; ctx.textBaseline = "middle"; // el porcentaje máximo var porcentaje = 60; // cada 60px for (var y = 30; y < 275; y += 60) { // dibuja el texto ctx.fillText(porcentaje + "%", 40, y); //dibuja una línea horizontal ctx.save(); ctx.translate(0, 0.5); ctx.beginPath(); ctx.moveTo(40, y); ctx.lineTo(475, y); ctx.stroke(); ctx.restore(); //el porcentaje disminuye en un 15% porcentaje -= 15; } // define el estilo de texto ctx.textAlign = "center"; ctx.textBaseline = "top"; // los anos // empezamos a dibujar a 60px del margen izquierdo var o = 80; for (var i = 2008; i <= 2014; i++) { ctx.fillStyle = "blue"; ctx.fillText(i, o, 275); o += 60; } // GRAFICO ctx.lineWidth = 2; for (var nav in oData) { ctx.beginPath(); ctx.strokeStyle = oData[nav]["color"]; ctx.fillStyle = oData[nav]["color"]; ctx.moveTo(80, 270 - (oData[nav][i] * 60) / 15); var o = 80; // para cada propiedad en el objeto oData for (var i = 2008; i <= 2014; i++) { ctx.lineTo(o, 270 - (oData[nav][i] * 60) / 15); ctx.stroke(); ctx.beginPath(); ctx.arc(o, 270 - (oData[nav][i] * 60) / 15, 3, 0, 2 * Math.PI); ctx.stroke(); ctx.fill(); rotulador(o, nav, i); // i = ano ctx.moveTo(o, 270 - (oData[nav][i] * 60) / 15); o += 60; } } // llama la función laLeyenda(); laLeyenda(); } }

Al pasar por encima de los "nodos" aparece un rotulo con el nombre del navegador, el año y el porcentaje correspondiente de usuarios.