TAChart Tutorial: Background design/fi

From Free Pascal wiki

English (en) suomi (fi)

Kaavion taustan suunnittelu

Johdanto

tachart background finished.png

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.


tachart background no data.png tachart background datapoints editor.png

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.

tachart background first version.png

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 tarjoaa var parametrin ADoDefaultDrawing

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 on ADoDefaultDrawing parametri. Jos asetamme sen arvoon false 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 niiden ZPosition ominaisuudella. Jos esimerkiksi kaaviossa, jossa on pylväskuvaaja ja viivakuvaaja ja halua rivi sarja on osittain katettu baareissa joudut antamaan viivakuvaajalle suuremman ZPosition arvon kuin pylväskuvaajalla - Ne joilla on suurempi ZPosition-arvo piirretään myöhemmin eli pienemmän ZPosition-arvon päälle .
  • Piirtämisen aivan lopussa on tapahtuma, OnAfterDraw . Se on yleensä tarkoitettu "hallinnollisiin" tarkoituksiin, esimerkiksi mittaamaan piirtämisen aikaa. Aloitusaika saadaan lukemalla kello OnChartPaint 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ä:


tachart background backwall.png

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;

tachart background backwall gradient.png

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 arvoon false 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