TAChart Tutorial: Background design/fi
│
English (en) │
suomi (fi) │
Kaavion taustan suunnittelu
Johdanto
TChart-komponentin vakiokaavioissa on harmaa tausta. Muuttamalla Color
ominaisuutta on mahdollista muuttaa koko kaavion taustaväriä ja ominaisuutta BackColor
väriä vaihtamalla kaavion akselien rajaama alueen taustaväri muuttuu.
Joka tapauksessa tälläin tehty suunnittelu on aika perinteinen. Onko mahdollista tehdä kaavion taustalle muunlainen suunnittelu?
Tässä opetusohjelmassa esitetään että on suhteellisen helppoa tehdä muunkinlaisia taustoja hyödyntämällä yhtä tai kahta TChart:n tapahtumaa. Aluksi luodaan kaavio joka kartoittaa Lazaruksen latausten määrän muutoksia vuodessa joinakin vuosina. Kaaviota korostetaan näyttämällä Lazaruksen aloitusruutua taustakuvana
Esivalmistelu
Data
Sourceforge tarjoaa luettelon Lazaruksen latausmääristä kuukaudessa. Paikasta http://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2032%20bits/stats/timeline?dates=2003-01-01+to+2014-09-02 saadaan windows-32 asennustiedoston latausmääristä
Vuosi | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 |
---|---|---|---|---|---|---|---|---|---|
Lataukset | 53299 | 119613 | 158060 | 218915 | 190567 | 230108 | 267858 | 298335 | 280586 |
Nämä tiedot ovat kaavion perustana.
Kaavion tekeminen
Luo uusi projekti ja lisää TChart
lomakkeelle. Aseta Client-align siten, että kaavion täyttää koko lomakkeen.
Vedä lomakkeen rajoja siten, että ikkuna on noin 400 pikseliä leveä ja 300 pikseliä korkea.
Kaavio näytetään niin että vuodet (Years) ovat x
-akselilla ja latauksien määrä (Download count) y
-akselilla.
Siksi mene bottom akselille, löydä ominaisuus Title
ja kirjoita "Years" (tai "vuodet") kohtaan Caption
.
Jotta tämä Title näytetään, aseta sen kohta Visible
arvoon true
.
Sopeututa muut ominaisuudet mieleiseksesi: usein otsikko näyttää pärempana lihavoituna ja suurempana (12). Joskus ristikko on ärsyttävää, sen voi poistaa käytöstä asettamalla Grid
:n Visible
omaisuus arvoon false
.
Tee samantapaisia muutoksia pystyakselille. Otsikko voisi olla nimeltään "Downloads per year" tai "latauksia vuodessa".
Kaavion yläpuolella pitäisi myös laittaa otsikko. Kirjoita teksti "Lazarus lataukset" tai "Lazarus downloads" kaavion Title
ominaisuuteen Text
.
Jälleen asettamaan kohta Visible
arvoon true
jotta otsikko näytetään. Voit myös halutessasi vaihtaa otsikon fontin lihavoiduksi ja kasvattaa sen kokoa hieman.
Hyvä kuvaaja tyyppi aikasarjoille on bar series (palkkikuvaaja).
Aluksi lisäämme TBarSeries
kaavioon: Kaksoisklikkaa kaaviota. Se avaa "Muokkaa kuvaajia" (series editor) ikkunan. klikkaa "Lisää" ja valitse "Pylväskuvaaja" (Bar series) avautuvasta luettelosta. Emme näe kuvaajaa koska sillä ei vielä ole tietoja.
On olemassa useita erilaisia tapoja määrittää kuvaajan data. Koska meillä on vakiodata jotka eivät muutu ohjelman aikana niin on sopivaa käyttää TListSource
-komponenttia joka tarjoaa editorin tietojen tallentamiseen suunnitteluaikana.
ListChartSource löytyy "Chart"-komponenttipaletin toisesta kuvakkeesta. Syöttääksesi tietoja, klikkaamalla kolmea pistettä komponentin DataPoints
omaisuuden vieressä - tämä avaa "Datapisteiden muokkaimen" (DataPoints editor). Syötä tiedot edellä olevasta taulukosta muokkausikkunan taulukkoon: Siinä "vuosi" menee "X"-sarakkeeseen ja "lataukset" menee "Y"-sarakkeeseen. Mitään ei tarvitse syöttää "Väri" (Color) ja "Teksti" (Text) sarakkeisiin.
Lopuksi kytke ListChartSource pylväspalkkikuvaajaan. Jokaisella kuvaajalla on ominaisuusSource
. Klikkaa avattavaa nuolta ja valitse ListChartSource listasta. Välittömästi Pylväsdiagrammin näkyy.
TChart piirrostapahtumat
Toistaiseksi projekti on ollut aivan perustasolla. Joten tutkitaanpas piirtofunktioita...
TChart
tarjoaa useita tapahtumia, johon omaa koodia voidaan "koukuttaa":
- Aluksi on piirtoprosessi
OnChartPaint
. Tämä tapahtuma on haasteellinen ja siihen pääsee kiinni vain koodista ei komponenttimuokkaimesta. Se "koukku" on tarjolla ennenkuin mitään piirretään kaaviossa ja tarjoaavar
parametrinADoDefaultDrawing
Asettamalla se arvoon false
niin se sulkee koko sisäänrakennetun piirustusprosessin ja mahdollistaa maalata kaavion täysin oman maun mukaan. Erittäin jännittävä ominaisuus, mutta liian raju meidän tarkoitukseen ...
- Seuraava tapahtuma tapahtuu ennenkuin koko kaavion tausta on piirretty:
OnBeforeDrawBackground
. Siinäkin onADoDefaultDrawing
parametri. Jos asetamme sen arvoonfalse
voimme korvata kaavion taustan piirtämisen omalla tavalla. Erittäin hyvä tähän tarkoitukseen.
Jos jätämme sen arvoon true
niin kaavioon piirretään perustausta mutta voimme hallita sitä myös komponenttimuokkaimesta.
- Kun tausta on piirretty - joko oletuksen mukainen tai muokattu - on toinen tapahtuma
OnAfterDrawBackground
. Sitä voidaan käyttää piirtämään jotain taustassa, joka jää kuvaajan tai akselien alle, jotka piirretään myöhemmin. - Vielä aivan alkuvaiheessa, meillä on
OnBeforeDrawBackwall
tapahtuma. Se tapahtuu ennen kuin rajaavat akselin suorakulmion ( "takaseinä") täytetään sen taustan väri / kuvio. HyödyntämälläADoDefaultDrawing
parametrin taas voimme korvata takaseinään omilla menettelyä. Tämä on se mitä esimerkissä käytetään! - Sitten piirretään kaavion otsikot, akselit, ruudukko, kuvaajat ja legenda (otsikkopalkki). Valitettavasti ei ole olemassa tapahtumia siepata niiden piirtämistä (paitsi legenda joka tarjoaa
OnDrawLegend
tapahtuma). Mutta meillä on joitakin valvonta piirustus prosessin kuluessa ryhmän kaavioelementtejä avulla niidenZPosition
ominaisuudella. Jos esimerkiksi kaaviossa, jossa on pylväskuvaaja ja viivakuvaaja ja halua rivi sarja on osittain katettu baareissa joudut antamaan viivakuvaajalle suuremmanZPosition
arvon kuin pylväskuvaajalla - Ne joilla on suurempiZPosition
-arvo piirretään myöhemmin eli pienemmänZPosition
-arvon päälle . - Piirtämisen aivan lopussa on tapahtuma,
OnAfterDraw
. Se on yleensä tarkoitettu "hallinnollisiin" tarkoituksiin, esimerkiksi mittaamaan piirtämisen aikaa. Aloitusaika saadaan lukemalla kelloOnChartPaint
tapahtumassa.
Taustakuvan näyttäminen
Lazarus logo on tähän tarkoitukseen (Lazaruksen latauksien määrä) sopiva taustakuva. Tässä tämä halutaan akselien rajaamalle alueelle (back wall). Kuten yllä olevasta kaavion tapahtumaluettelosta nähdään niin OnBeforeDrawBackwall
-tapahtuma sopii tähän hyvin.
Ensin meidän täytyy saada logo saataville ohjelmaan. Logotiedoston on nimi "splash_logo.png" ja löytyy Lazarus asennuksen kansiosta "images". Yksinkertaisuuden vuoksi se kopioidaan kansioon johon syntyy ajettava ohjelma ns exe-tiedosto (tai sitten voidaan käyttää koko tiedostopolkua koodissa). Koska logo on png tiedosto tarvitsemme tyyppiä TPortableNetworkGraphic tai - mikä on joustavampi - TPicture. Määritellään muuttuja FBackImage
jälkimmäisen tyypin muotoon ja lisätään koodin lomakkeen onCreate tapahtumaan kuvatiedoston lataus. Tietenkään älä unohda vapauttaa kuvaa, kun ohjelma sulkeutuu:
type
TForm1 = class(TForm)
...
private
FBackImage: TPicture;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
FBackImage := TPicture.Create;
FBackImage.LoadFromFile('splash_logo.png');
// or: FBackImage.LoadFromFile('c:\lazarus\images\splash_logo.png');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FBackImage.Free;
end;
Kun kuvaa ladaan suoraan tiedostosta edellytetään, että kuva jaetaan yhdessä exe-tiedoston kanssa. Tämä voidaan välttää, jos kuva lisätään resurssina binaaritiedostoon. Tätä varten sinun täytyy luoda resurssi tiedoston, joka sisältää kuvan - katso wiki artikkeli .... miten se tehdään. Lazarus images kansio sisältää valmiin resurssitiedoston logosta: "splash_logo.res". Jos haluat käyttää tätä lähestymistapaa, kopioida tiedoston projektikansioon ja käyttää tätä vaihtoehtoa OnCreate
koodi (älä unohda lisätä {$R splash_logo.res}
unitin alussa olevaan implemenation
osaan):
...
implementation
{$R *.lfm}
{$R splash_logo.res}
procedure TForm1.FormCreate(Sender: TObject);
begin
FBackImage := TPicture.Create;
FBackImage.LoadFromResourceName(HInstance, 'splash_logo');
end;
Menetelmästä riippumatta mitä päätettiin käyttää - nyt on aika lisätä koodiin kaavion OnBeforeDrawBackwall
tapahtuma. Se on hyvin yksinkertainen: käytetään hyödyksi Canvas:n StretchDraw metodia ja - tietenkin - asetamme ADeDefaultDrawing
arvoon false
jolloin ohitetaan oletus piirtomenetelmä. On tärkeää, että käytetään parametrinä annetun ACanvas:a ja sen StretchDrawmetodia, ei kaavion kankaalle, koska kaavion piirron suorittaa erityinen backend luokka, jotka voivat tarjota erilaisia Canvas-luokkia, esimerkiksi jos kaavio on tulostettava.
procedure TForm1.Chart1BeforeDrawBackWall(ASender: TChart; ACanvas: TCanvas;
const ARect: TRect; var ADoDefaultDrawing: Boolean);
begin
ACanvas.StretchDraw(ARect, FBackImage.Graphic);
ADoDefaultDrawing := false;
end;
Koska tapahtumakäsittely on ajonaikaista koodia täytyy ohjelma kääntää jotta nähdään millainen kaavio on tällä hetkellä:
Taustan liukuvärjäys
Ulkoisella taustaalueella on vielä nähdään "kuuluisa" harmaa tausta. Miten se korvataan liukuvärjäyksellä? Koska Lazaruksen logo on pääosiltaan sininen voidaan liukuväritys aloittaa taivaan sinisellä (clSkyBlue
) ja päättää se valkoisella (clWhite
)
Piirtotapahtumien yhteenvedosta tiedetään että OnBeforeDrawBackground
on oikea tapahtuma, joka voidaan käyttää piirtämään kaavion taustan yksin. Mutta miten piirtää liukuvärjäys? Erittäin helppo: Canvas:lla on metodi GradientFill
jolle annetaan alkava ja päättyvä värit sekä liukuvärjäyksen suunta.
procedure TForm1.Chart1BeforeDrawBackground(ASender: TChart; ACanvas: TCanvas;
const ARect: TRect; var ADoDefaultDrawing: Boolean);
begin
ACanvas.GradientFill(ARect, clSkyBlue, clWhite, gdVertical);
ADoDefaultDrawing := false;
end;
Viimeistely
Pylväskuvaajan punaiset palkit näyttävät vähän "aggressiivisilta". Entä hillitympi taivaansininen? Valitse komponenttimuokkaimessa kyseinen BarSeries ja aseta SeriesColor
:n arvoksi clSkyBlue
.
Ja olisi parempi nähdä enemmän Lazaruksen gepardia joka on suurelta osalta pylväiden takana. Pylväskuvaajilla on ominaisuus Transparency
. Sen oletusarvo on nolla (0) joka tarkoittaa läpinäkymätön ja suurin sallittu arvo on 255 mikä tarkoittaa täysin läpinäkyvää. Pieni arvo, kuten 64 , lisää jonkin verran läpinäkyvyyttä ja näyttää enemmän gepardin yksityiskohtia, mutta ei työnnä pylväitä liikaa taustalle.
Ja nämä lisäykset tekee kaavion, joka näkyy tämän sivun yläreunassa.
Yhteenveto
Tässä on perusvaiheet käyttäjän tekemällä kaavion taustalle:
- Käytä
OnBeforeDrawBackWall
tapahtumaa kun haluataan piirtää oma tausta akselien rajaamaan suorakulmioon. - Vastaasti käytä
OnBeforeDrawBackground
tapahtumaa kun halutaan piirtää kaavion tausta. - Aseta näissä piirtometodeissa
ADoDefaultDrawing
arvoonfalse
jotta tapahtuu vain oma piirtäminen.
Lähdekoodi
Tämän opetusohjelman lähdekoodi löytyy TAChart:n kansiosta tutorials/background.
Project file
program backimage;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, main, tachartlazaruspkg
{ you can add units after this };
{$R *.res}
begin
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Unit main.pas
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, TAGraph, TASeries, TASources, Forms, Controls,
Graphics, Dialogs;
type
{ TForm1 }
TForm1 = class(TForm)
Chart1: TChart;
Chart1BarSeries1: TBarSeries;
ListChartSource1: TListChartSource;
procedure Chart1BeforeDrawBackground(ASender: TChart; ACanvas: TCanvas;
const ARect: TRect; var ADoDefaultDrawing: Boolean);
procedure Chart1BeforeDrawBackWall(ASender: TChart; ACanvas: TCanvas;
const ARect: TRect; var ADoDefaultDrawing: Boolean);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ private declarations }
FBackImage: TPicture;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
//{$R splash_logo.res}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
FBackImage := TPicture.Create;
FBackImage.LoadFromFile('splash_logo.png');
// this assumes that the logo is in the same folder as the binary
// or, using resources:
//FBackImage.LoadFromResourceName(HInstance, 'splash_logo');
// Don't forget ths {$R directive above...
end;
procedure TForm1.Chart1BeforeDrawBackWall(ASender: TChart; ACanvas: TCanvas;
const ARect: TRect; var ADoDefaultDrawing: Boolean);
begin
ACanvas.StretchDraw(ARect, FBackImage.Graphic);
ADoDefaultDrawing := false;
end;
procedure TForm1.Chart1BeforeDrawBackground(ASender: TChart; ACanvas: TCanvas;
const ARect: TRect; var ADoDefaultDrawing: Boolean);
begin
ACanvas.GradientFill(ARect, clSkyBlue, clWhite, gdVertical);
ADoDefaultDrawing := false;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FBackImage.Free;
end;
end.
Form file main.lfm
object Form1: TForm1
Left = 340
Height = 300
Top = 154
Width = 400
Caption = 'Form1'
ClientHeight = 300
ClientWidth = 400
OnCreate = FormCreate
OnDestroy = FormDestroy
LCLVersion = '1.3'
object Chart1: TChart
Left = 0
Height = 300
Top = 0
Width = 400
AxisList = <
item
Grid.Color = clSkyBlue
Grid.Visible = False
Marks.Format = '%.0n'
Marks.Style = smsCustom
Minors = <>
Title.LabelFont.Height = -16
Title.LabelFont.Orientation = 900
Title.LabelFont.Style = [fsBold]
Title.Visible = True
Title.Caption = 'Downloads per year'
end
item
Grid.Visible = False
Alignment = calBottom
Minors = <>
Title.LabelFont.Height = -16
Title.LabelFont.Style = [fsBold]
Title.Visible = True
Title.Caption = 'Year'
end>
Foot.Brush.Color = clBtnFace
Foot.Font.Color = clBlue
Title.Brush.Color = clBtnFace
Title.Brush.Style = bsClear
Title.Font.Color = clNavy
Title.Font.Height = -17
Title.Font.Style = [fsBold]
Title.Text.Strings = (
'Lazarus Downloads'
)
Title.Visible = True
OnBeforeDrawBackground = Chart1BeforeDrawBackground
OnBeforeDrawBackWall = Chart1BeforeDrawBackWall
Align = alClient
ParentColor = False
object Chart1BarSeries1: TBarSeries
Shadow.Color = clNavy
Shadow.OffsetX = 4
BarBrush.Color = clSkyBlue
Source = ListChartSource1
end
end
object ListChartSource1: TListChartSource
DataPoints.Strings = (
'2005|53299|?|'
'2006|119613|?|'
'2007|158060|?|'
'2008|218915|?|'
'2009|190567|?|'
'2010|230108|?|'
'2011|267858|?|'
'2012|298335|?|'
'2013|280586|?|'
)
left = 120
top = 56
end
end