Vishnu
Vishnu

Reputation: 2452

Rotating multiple texts in canvas

I am trying to create graph in a HTML5 canvas. But text in the x axis is overlapping. I am trying to rotate it so it looks neat.

Example jsfiddle: http://jsfiddle.net/67tddgcj/1/

I tried to save, rotate, and restore like below

c.save();
c.rotate(-Math.PI/2);
c.fillText(data.values[i].X, getXPixel(i), graph.height() - yPadding + 20);
c.restore();

But the text appears in a different place.

Upvotes: 1

Views: 654

Answers (1)

markE
markE

Reputation: 105015

enter image description here

You could angle your text so it always fits the graph like this:

  1. Save the starting context state (untransformed)
  2. Set the desired font
  3. Measure the pixel width of the text
  4. Translate to the desired endpoint
  5. Rotate to the desired angle
  6. Set the text baseline so the text is vertically centered on the endpoint
  7. Draw the text offset by the negative width so the text ends at the desired endpoint
  8. Rrestore the context to its starting state

Here is example code and a Demo:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");

for(var i=0;i<10;i++){
  var endingX=30+i*15;
  drawRotatedText(endingX,50,-Math.PI/4,'Jan '+i,'9px verdana');
}

function drawRotatedText(endingX,centerY,radianAngle,text,font){
  // save the starting context state (untransformed)
  ctx.save();
  // set the desired font
  ctx.font=font;
  // measure the pixel width of the text
  var width=ctx.measureText(text).width;
  // translate to the desired endpoint
  ctx.translate(endingX,centerY);
  // rotate to the desired angle
  ctx.rotate(radianAngle);
  // set the text baseline so the text 
  // is vertically centered on the endpoint 
  ctx.textBaseline='middle';
  // draw the text offset by the negative width
  // so the text ends at the desired endpoint
  ctx.fillText(text,-width,0);
  // restore the context to its starting state
  ctx.restore();
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>

Upvotes: 4

Related Questions