Yazılım Bir Tutku

Tecrübe ilimden üstündür !

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.



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