HTML5 Canvas ve Chart uygulaması
Merhaba arkadaşlar;
HTML5 ile alakalı paylaşımlarda bulunacağımı daha önceki süreçlerde bahsetmiştim ve HTML5 için bir başlangıç yapmıştık. HTML5 ile gelen en önemli yeniliklerden birisinin Canvas olduğu kesindir. Canvas (Tuval) elementini kullanarak her pikseli eksiksiz bir kontrol imkanı ile dinamik olarak grafikleri, cizelgeleri, resimleri ve animasyonlarını oluşturabilir ve işleyebiliriz.. Bunun elbetteki çok büyük avantajları var. Örneğin sayfalarımıza koyduğumuz yüksek boyutlu image lerden Canvas sayesinde kurtulabilir ve sayfalarımızın boyutunu küçültebiliriz. Tabi Canvas için iyi bir JavaScript bilgisinin olması gerektiğini unutmamak gerekir. Hatta HTML5'in sırtını JavaScript'e dayadığı düşünülürse ve HTML5'in geleceğin standartlarını belirleyeceği gerçeği ile JavaScript kitaplarımızın raflardan indirilmesi gerektiğini söylemem gerekir.
Canvas öğelerini web sayfanızda kullandığımız zaman sayfamızda default olarak 300px genişliğinde ve 150px yüksekliğinde bir dikdörtgen oluşur. Ama genişlik ve yükseklik gibi boyutları yanısıra diğer canvas(tuval) elemanlarının niteliklerini özelleştirebiliriz.
<canvas></canvas>
Canvas Coordinates (Tuval Kordinatları) aşağıdaki şekilde gösterildiği gibi x ve y kordinatları ile belirlenir. En üst sol köşeden başlar ve genel itibari bu nokta orjin olarak adlandırılır. Yatay olarak X ekseni, dikey olarak da Y ekseni olarak işlem yapılır.
.png)
Tabi sayfamızda Canvas API lerini kullanmak oldukça kolaydır.
<canvas height="250" width="250"></canvas>
Bu durumda canvası 250’ye 250 piksel ölçülerinde bir dikdörtgen olarak sayfanıza eklenmiş olur. Eğer yazının devamını okumadan bu işlemi yaptıysanız ve sayfanızda birşey görmüyorsanız "offf olmadu yahu" diye homurdanmayın. İşlemi başarı ile gerçekleştirdiniz. Fakat çevresinde bir kenarlık olmadığından görünmüyor olması gayet normal. Çevresine bir kenarlık eklemek isterseniz aşağıdaki gibi bir bildirim işinizi görecektir.,
<canvas id="cnvs1" style="border: 1px solid;" width="250" height="250">
</canvas>
Yukarıda dikkat ederseniz Canvas için birde ID bildiriminde bulunduk. Canvas'a programsal olarak erişmemiz için olmaz olmaz durumundadır.
Şimdi dilerseniz bir çizgi ile Canvas için bir örnekleme yapalım...

Projeyi çalıştırdığımızda ;

Sonuç oldukça keyif verici bir görüntü :)
Şimdi olayı biraz daha verimli halen getirmek için başka bir örnek üzerinden makaleye devam edelim..
Artık projelerimizde raporlamalar ve bu raparlamaların bazılarının sayfalarımızda grafiksel olarak gösterimi kaçınılımaz. Bu noktada HTML5 Canvas API lerinden faydalanarak bu grafik tasarımını gerçekleştirmeye çalışalım..

canvasChart.js
var CanvasChart = function () {
var ctx;
var margin = { top: 40, left: 75, right: 0, bottom: 75 };
var chartHeight, chartWidth, yMax, xMax, data;
var maxYValue = 0;
var ratio = 0;
var renderType = { lines: 'lines', points: 'points' };
var render = function(canvasId, dataObj) {
data = dataObj;
getMaxDataYValue();
var canvas = document.getElementById(canvasId);
chartHeight = canvas.getAttribute('height');
chartWidth = canvas.getAttribute('width');
xMax = chartWidth - (margin.left + margin.right);
yMax = chartHeight - (margin.top + margin.bottom);
ratio = yMax / maxYValue;
ctx = canvas.getContext("2d");
renderChart();
};
var renderChart = function () {
renderBackground();
renderText();
renderLinesAndLabels();
//render data based upon type of renderType(s) that client supplies
if (data.renderTypes == undefined || data.renderTypes == null) data.renderTypes = [renderType.lines];
for (var i = 0; i < data.renderTypes.length; i++) {
renderData(data.renderTypes[i]);
}
};
var getMaxDataYValue = function () {
for (var i = 0; i < data.dataPoints.length; i++) {
if (data.dataPoints[i].y > maxYValue) maxYValue = data.dataPoints[i].y;
}
};
var renderBackground = function() {
var lingrad = ctx.createLinearGradient(margin.left, margin.top, xMax - margin.right, yMax);
lingrad.addColorStop(0.0, '#D4D4D4');
lingrad.addColorStop(0.2, '#fff');
lingrad.addColorStop(0.8, '#fff');
lingrad.addColorStop(1, '#D4D4D4');
ctx.fillStyle = lingrad;
ctx.fillRect(margin.left, margin.top, xMax - margin.left, yMax - margin.top);
ctx.fillStyle = 'black';
};
var renderText = function() {
var labelFont = (data.labelFont != null) ? data.labelFont : '20pt Arial';
ctx.font = labelFont;
ctx.textAlign = "center";
//Title
var txtSize = ctx.measureText(data.title);
ctx.fillText(data.title, (chartWidth / 2), (margin.top / 2));
//X-axis text
txtSize = ctx.measureText(data.xLabel);
ctx.fillText(data.xLabel, margin.left + (xMax / 2) - (txtSize.width / 2), yMax + (margin.bottom / 1.2));
//Y-axis text
ctx.save();
ctx.rotate(-Math.PI / 2);
ctx.font = labelFont;
ctx.fillText(data.yLabel, (yMax / 2) * -1, margin.left / 4);
ctx.restore();
};
var renderLinesAndLabels = function () {
//Vertical guide lines
var yInc = yMax / data.dataPoints.length;
var yPos = 0;
var yLabelInc = (maxYValue * ratio) / data.dataPoints.length;
var xInc = getXInc();
var xPos = margin.left;
for (var i = 0; i < data.dataPoints.length; i++) {
yPos += (i == 0) ? margin.top : yInc;
//Draw horizontal lines
drawLine(margin.left, yPos, xMax, yPos, '#E8E8E8');
//y axis labels
ctx.font = (data.dataPointFont != null) ? data.dataPointFont : '10pt Calibri';
var txt = Math.round(maxYValue - ((i == 0) ? 0 : yPos / ratio));
var txtSize = ctx.measureText(txt);
ctx.fillText(txt, margin.left - ((txtSize.width >= 14) ? txtSize.width : 10) - 7, yPos + 4);
//x axis labels
txt = data.dataPoints[i].x;
txtSize = ctx.measureText(txt);
ctx.fillText(txt, xPos, yMax + (margin.bottom / 3));
xPos += xInc;
}
//Vertical line
drawLine(margin.left, margin.top, margin.left, yMax, 'black');
//Horizontal Line
drawLine(margin.left, yMax, xMax, yMax, 'black');
};
var renderData = function(type) {
var xInc = getXInc();
var prevX = 0,
prevY = 0;
for (var i = 0; i < data.dataPoints.length; i++) {
var pt = data.dataPoints[i];
var ptY = (maxYValue - pt.y) * ratio;
if (ptY < margin.top) ptY = margin.top;
var ptX = (i * xInc) + margin.left;
if (i > 0 && type == renderType.lines) {
//Draw connecting lines
drawLine(ptX, ptY, prevX, prevY, 'black', 2);
}
if (type == renderType.points) {
var radgrad = ctx.createRadialGradient(ptX, ptY, 8, ptX - 5, ptY - 5, 0);
radgrad.addColorStop(0, 'Green');
radgrad.addColorStop(0.9, 'White');
ctx.beginPath();
ctx.fillStyle = radgrad;
//Render circle
ctx.arc(ptX, ptY, 8, 0, 2 * Math.PI, false)
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = '#000';
ctx.stroke();
ctx.closePath();
}
prevX = ptX;
prevY = ptY;
}
};
var getXInc = function() {
return Math.round(xMax / data.dataPoints.length) - 1;
};
var drawLine = function(startX, startY, endX, endY, strokeStyle, lineWidth) {
if (strokeStyle != null) ctx.strokeStyle = strokeStyle;
if (lineWidth != null) ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
ctx.closePath();
};
return {
renderType: renderType,
render: render
};
} ();
Evettt şimdi de sonucumuzu görelim..

Sanırım etkilenmemek mümkün değil..
Canvas için örneklemelere ve HTML5 paylaşımlarıma devam ediyor olacağım.
Faydalı olması dileğiyle kalın sağlıcakla....
Mahmut TEMUR
http://www.mahmuttemur.com
e-posta : mahmuttemur@windowslive.com
Takip Ediyorum
Faydalı Projeler
Yorumlar
Sizde Yorumda Bulunun
Konuya dair fikir ve sorularınızı paylaşın