Canvas- Plot Data in Smart X-Y Chart

Written by @m_k_amin 2 July 2013

One useful tool for websites is plotting feature. The users' posts per day, download counts per hour and etc. are examples of statistical plots which are more usual. HTML5 Canvas combination with Javascript is powerful tool for easily drawing plots. In the following example we have a smart XY plot. It is not depends on the width and heights of the plot and data ranges. It smartly adjusts the specified area and rescales the data to be proper for drawing. Note that many other features can also get added to our HTML5 Canvas Plotter based on what is needed.

Code Snippet:

                                                
                                                <!-- this script is provided by https://www.html5freecode.com coded by: Kerixa Inc. -->
<!-- This Script is from www.html5freecode.com, Coded by: Kerixa Inc-->
<table style="border: 1px solid #000000; width: 347; height: 186;">
	<tr><td style="border-style: solid; border-width: 1px; text-align: center; width: 125;">Data (x,y):</td>
	<td rowspan="3" style="border-style: solid; border-width: 1px; width: 289px;">
		<canvas id="myCanvas" width="300px" height="230px"></canvas>
	</td></tr>
	<tr><td style="width: 125; border-left-style: solid; border-left-width: 1px; border-top-style: solid; border-top-width: 1px; border-bottom-style: solid; border-bottom-width: 1px; text-align: center; height: 159px;">
		<textarea id="txy" name="txtXY" style="width: 65px; height: 148px" tabindex="1">1,3
2,7
3,6
4,0
5,6
7,9</textarea></td></tr>
	<tr><td style="text-align: center; border-left-style: solid; border-left-width: 1px; border-top-style: solid; border-top-width: 1px; border-bottom-style: solid; border-bottom-width: 1px; width: 125; height: 35px;">
		<input name="btnPrev" type="button" value="Preview" id="prv" tabindex="2" onclick="plot()" /></td></tr>
</table>
<script>
    var cnv = document.getElementById('myCanvas')
    var txy= document.getElementById('txy')
    //txy.focus()

function plot(){
	x= new Array()
	y= new Array()
	var rData= txy.value
	row= rData.split("\n")
	for (var i in row){
		xy= row[i].split(",")
		x.push(xy[0])
		y.push(xy[1])
	}
	plotData(x,y, cnv)
}
function plotData(arrX, arrY, Canvas){
    var ctx = Canvas.getContext('2d'), cW= Canvas.offsetWidth, cH= Canvas.offsetHeight
	ctx.setTransform(1, 0, 0, 1, 0, 0)
    ctx.fillStyle="rgb(255,243,240)"
    ctx.fillRect(0,0,cW,cH)

    ctx.strokeStyle='black'        
    ctx.beginPath()
	ctx.moveTo(0.1*cW, 0.05*cH)
	ctx.lineTo(0.08*cW, 0.08*cH)
	ctx.moveTo(0.1*cW, 0.05*cH)
	ctx.lineTo(0.12*cW, 0.08*cH)
	ctx.moveTo(0.1*cW, 0.05*cH)	
	ctx.lineTo(0.1*cW, 0.9*cH)
	ctx.lineTo(0.95*cW, 0.9*cH)
	ctx.lineTo(0.92*cW, 0.88*cH)
	ctx.moveTo(0.95*cW, 0.9*cH)
	ctx.lineTo(0.92*cW, 0.92*cH)
    ctx.stroke()
    ctx.translate(0.1*cW, 0.9*cH)
    ctx.scale(1,-1)
    ctx.stroke()
    
    var minX= Math.min.apply(null, arrX), minY= Math.min.apply(null, arrY)
    var maxX= Math.max.apply(null, arrX), maxY= Math.max.apply(null, arrY)    
    var wX=maxX-minX, wY=maxY-minY
    var gW=0.95*cW-0.1*cW, gH=0.9*cH-0.05*cH
    var facX=gW/wX, facY=gH/wY
    
    ctx.beginPath()
    ctx.fillStyle='Blue'
    ctx.strokeStyle='brown'    
    ctx.lineWidth= 0.002*(cW+cH)
	var sqW=0.02*cW, sqH=0.02*cH
	var newX, newY
	for (var i in arrX){
		newX= (arrX[i]-minX)*facX
		newY= (arrY[i]-minY)*facY
    	ctx.fillRect(newX-sqW/2, newY-sqH/2, sqW, sqH)
    	if (i==0)
    		ctx.moveTo(newX,newY) 
    	else 
    		ctx.lineTo(newX,newY)
    }
    ctx.stroke()
	
	ctx.scale(1,-1)
    ctx.fillStyle='darkblue'
 	ctx.textBaseline= 'middle'
	ctx.textAlign= 'center'	
	var fntSize=0.02*(cW+cH)
   	ctx.font= fntSize+"pt serif"
   	var txtB= '('+minX+','+minY+')'
   	var txtBW=ctx.measureText(txtB).width
   	if (txtBW>0.1*cW) txtBW=0.1*cW
    ctx.fillText(txtB, -txtBW/2, 0.05*gH, txtBW)
    ctx.beginPath()
    for (i=1;i<=5;i++){
    	ctx.moveTo(i*gW/6, 0.02*cH)
    	ctx.lineTo(i*gW/6, -0.02*cH)
	   	txtB= Math.round((i/6*wX+minX)*100)/100
	   	txtBW=ctx.measureText(txtB).width
	   	if (txtBW>0.06*cW) txtBW=0.06*cW	    
	    ctx.fillText(txtB, i*gW/6, 0.06*cH, txtBW)
    	
    	ctx.moveTo(0.02*cW, -i*gH/6)
    	ctx.lineTo(-0.02*cW, -i*gH/6)    	
	   	txtB= Math.round((i/6*wY+minY)*100)/100
	   	txtBW= ctx.measureText(txtB).width
	   	if (txtBW>0.06*cW) txtBW=0.06*cW	    
	    ctx.fillText(txtB, -0.06*cW, -i*gH/6, txtBW)
    }
    ctx.strokeStyle='magenta'
    ctx.stroke()

}

</script>
<div style="text-align: left"><font face="Tahoma"><br><a target="_blank" href="http://www.html5freecode.com"><span style="font-size: 8pt; text-decoration: none">HTML5 Free Code</span></a></font></div>                                              
                                            <a target='_blank' href='https://www.html5freecode.com' style='font-size: 8pt; text-decoration: none'>Html5 Free Codes</a>                                                
                                            

Example:


About @m_k_amin

This user is pending a biography.

M

Comments


Here you can leave us commments. Let us know what you think about this code tutorial!

0 / 300

TRENDING POST
1
2
3
4
5
VISITORS
Online Users: 12
Recent Members: Afzal, FOTPU
advertisement 2