11 Aralık 2011 Pazar 0 yorum

GDI+ ile Pasta Grafiği Çizimi

Daha önceki yazımda GDI+’ ın ne olduğunu, neler yapabileceğimizi basitçe göstermeye çalışmıştım. Bu sefer de GDI+ ile yapacağım olay bir “Pasta Grafiği” şekli olacak.

Pasta Grafiğimiz; Türkiye Liginde şampiyon olmuş takımların taraftarlarının oranını içerecek. Bunun için de Futbol takımları ile ilgili bilgileri içerecek bir class dosyası oluşturacağım. Sınıfımızın tasarımı şu şekilde olacak:

Burada 2 tane renk objesi oluşturmamın sebebi, o takıma ait pasta diliminin görünümünü o takımın renkleri ile oluşturmak.

Sınıfın tasarımını yaptıktan sonra sıra takımlarımızı oluşturmakta. “Form1_Load” kısmında “Takımları Oluştur” adlı metot yaratıp, o metot da takımları oluşturuyorum.

Yukarıdaki metot da takımlar oluşturulup, List dizisine eklenmekte.

Grafik pastasında, oluşturulacak takıma ait dilimi hesaplamak için, toplam taraftar sayısını bilmemiz gerekmekte. Bunun için “ToplamTaraftarSayisi” adlı bir metot oluşturup burada toplam taraftarı hesaplıyoruz.

Pasta Grafiğini, bu sefer Form yerine PictureBox’ da çizdireceğim. Form1 üzerine, Picturebox yerleştirip “Dock” özelliğini “Fill” yaptım. Fom1_Load kısmında ise; Picturebox’ın "Image" özelliğine geri dönüş değeri Image olan “PastaGrafiğiCiz” adlı bir metot değeri veririz. Bu metot çizim işleminin gerçekleşeceği yerdir.

“PastaGrafiğiCiz” adlı metot da çizim işlemi yapmak için Graphics nesnesine ihtiyacımız var, fakat Graphics nesnesini oluşturmadan önce, bizim çizim yapacağımız alanı oluşturmamız lazım. Çünkü Picturebox’ın Image özelliğinin geri dönüş değeri Image cinsinden, bizim de Image türünden bir alan oluşturup bu alanda çizim yapıp, geri olarak döndürmeliyiz. Bu alan Bitmap sınıfıdır. Bizim bir bitmap oluşturup, bu alan üzerinde çizim yapacağımız Graphics nesnesini oluşturacağız.

Graphics nesnesini oluşturduktan sonra artık hesap işlemlerine girebiliriz. Bizim yapacağımız hesap bir takımın ne kadar açılık bir dilime sahip olduğunu bulmaktır. Örneğin Galatasaray takımının diliminin hesaplanması:

Galatasaray taraftarının sayısı 25.000.000 kişi, Toplam taraftar sayısı ise 70.000.000. Galatasaray taraftar sayısını, Toplam taraftar sayısını bölerek, Galatasaray taraftarının toplam taraftara göreli oranını hesaplarız. Buradan çıkan sonucu 360 ile çarparsak, Galatasaray takımına ait açıyı buluruz. 360 ile çarpmamızın nedeni ise, Bir pasta grafiğinin toplam açısı 360 derecedir. Yukarıdaki bölme işleminden çıkan sonucu, 360 ile çarparak; 360 derecede ne kadarlık açıya sahip olduğunu bulmak.

Açıyı bulduktan sonra, sıra oluşturulacak dilimin takımın renklerine bürümeye. Bunun için fırça(Brush) sınıfını kullanacağız. Renk karışımını oluşturmak için “System.Drawing.Drawing2D” referansına ait “LinearGradientBrush” fırçasını kullanacağız. LinearGradientBrush incelemesi aşağıdaki şekildedir:

Bu hesaplamaları ve LinearGradientBrush’ ı öğrendikten sonra, Metodumuz şu şekilde olacaktır:

Graphics sınıfından instance alan cizim nesnesinin “FillPie” metodu ile takıma ait pasta dilimini çizebilmekteyiz. FillPie metodunu incelersek;

Burada dikkat edilmesi gereken bir diğer konu ise, başlangıç açısının, kendisi ve taraftar açısının toplamına eşitlenmesi. Bunu yapmamızda ki sebep, bir takıma ait dilimi oluşturduktan sonra, onun bittiği açıdan itibaren diğer takımın açısını çizmek istememiz.

Projeyi çalıştırdığımızda ise sonuç şekilde olacaktır:

Şekilde görüldüğü Sarı-Kırmızı, Siyah-Beyaz gibi renk karışımını LinearGradientBrush sayesinde sağlamış olduk.
6 Aralık 2011 Salı 0 yorum

GDI+

GDI+(Graphical Device Interface) bize çizim imkânı sunan bir yapı. İçinde bize ekrana çizim yapmamızı sağlayacak bir takım sınıfılar içermekte.

Windows’un popüler olmasındaki sebeplerden biri de kullanıcıya arka planda yaptıklarını saklaması. Mesela işletim sistemi ekrana bir şeyler çizerken, arka planda ekran kartına çizim için bir takım emirler vermekte ve bu emirleri(istekleri) biden gizleyerek yapmakta. Yalnız bu basit gibi gözüken yapıda şöyle bir sorun var, binlerce farklı ekran kartının bulunması. Yani işletim sistemi bu farklı ekran kartlarını tanıyıp nasıl emir vere bilmekte. İşte GDI’ da burada devreye girmekte. GDI ekran kartımızın driver’ı aracılığıyla ekran kartımıza emirler verebilmekte.

Çizim işlemlerini “System.Drawing” referansının içinde yer alan Graphics sınıfı ile yapabilmekteyiz. Çizim işlemlerini Çizim yapılacak kontrolün “Paint” eventinde gerçekleştiriyoruz. Graphics sınıfına ait bir nesne oluştururken “new” anahtar kelimesi ile oluşturamıyoruz. Çünkü Graphics nesnesi bizde, çizim yapılacak yerin(Form, Panel, vb.) Graphics nesnesini istemektedir.

Örneğin ekrana bir daire çizelim, Graphics objesi bizden kalem(Pen) sınıfını ait bir obje istemekte. Kalem sınıfı bize eğim ve çizgiler oluşturmamıza sağlamakta.

Yukarıdaki kodda Aqua renginde, 6 pixel kalınlıkta bir kalem oluşturur.

Kalem objesini oluşturduktan sonra, daire şeklini oluşturabiliriz. Bunun için “DrawEllipse” metodunu kullanırız.

DrawEllipse metodu bizden bir takım parametreler istemekte. İlk parametre kalem parametresi, 2 ve 3. Parametreler formumuzun x ve y koordinatlarını belirtmekte. Ben başlangıç noktasından(0,0)’ dan itibaren çizmesini istedim. 4 ve 5. Parametreler çizilecek şeklin genişlik ve yüksekliğini belirtmekte.

Şimdi ise bu oluşturduğumuz çemberin içini doldurmakta. Bunun için Fırça(Brush) sınıfını kullanacağız. Visual Studio içerisinde bir takım fırçalar yer almakta. Örneğin; SolidBrush, TextureBrush, vb…

SolidBrush; oluşturulacak şeklini içini düz bir şekilde boyar.

TextureBrush; şeklin içini sizin belirlediğiniz resim ile doldurur.

FillEllipse metodu ile içi boyanmış bir şekilde, Formun (0,0) koordinatlarından başlayıp, formun genişlik ve yüksekliği kadar çizer.

Bu sefer de Fırça olarak TextureBrush kullanalım. TextureBrush’ ı kullanabilmemiz için bize çizilecek resmi tutan bir Bitmap sınıfı lazım.

Formumuz şu şekilde olacaktır:

Son olarak şunu belirtmek istiyorum; bütün bu çizim işlemlerini Form1’in “Paint” metodu ile gerçekleştirdik. Bunun sebeplerinden bir tanesi de şu: Eğer çizim kodlarını Formun Constructorına yerleştirip, çalıştırdığımızda şekil oluşacaktır. Fakat formu simge durumuna getirip, tekrar büyüttüğümüzde şeklin yok olduğunu görmekteyiz, bunun sebebi bu işlemde çizim ile ilgili sistem kaynaklarının boşaltılması. Bu yüzden “Paint” eventinde çizim işlemlerini gerçekleştirmekteyiz.
 
;