TAChart Tutorial: ListChartSource, Logarithmic Axis, Fitting/fi

From Free Pascal wiki
Jump to navigationJump to search

English (en) suomi (fi) русский (ru)


Johdanto

TAChart LogAx Tutorial15.png

Tiedätkö mikä on Mooren laki ? Siihen tutustutaan tässä esimerkissä.

Lukiessasi tätä olet todennäköisesti pöytätietokoneen, kannettavan tai älypuhelimen ääressä. Valtava edistyminen mikrotietokoneteknologiassa on tapahtunut viimeisten vuosikymmenten aikana ja on edelleen käynnissä. Tämä pienentäminen elektronissa laitteissa mahdollistaa pakata yhä enemmän toimintoja yhdelle piisirulle. Ja mitä Mooren laki on: transistoreiden määrä sirulla on kaksinkertaistunut noin kahden vuoden välein.

Tässä opetusohjelmassa otamme datan mikroprosessorien valmistajan julkaistuista tiedoista ja käytetään TAChart piirtämään transistoreihen määrää piirillä eri vuosina markkinoille tulleista tuotteista. Näiden tietojen avulla yritämme vahvistaa Mooren lain.

Tässä käytettävä data löytyy sivustolta www.intel.com/pressroom/kits/quickreffam.htm joka sisältää luettelon mikroprosessoreista, ajankohdista niiden tuomisista markkinoille ja niiden sisältämä transistorin määrä per piiri.

Tässä esimerkissä opitaan

  • miten syötetään dataa suunnitteluaikana
  • miten luodaan pistekuvaaja jossa nimiteksti kullakin datapisteellä
  • miten luodaan logaritminen akseli
  • miten sovittaa yhtälö tietoihin.


Sinulla pitäisi olla joitakin perustietoja miten työskennellä TAChart-komponentin kanssa jos ei ole niin katso TAChart:n aloitusopas. Tietenkin, sinun on tunnettava Lazarus ja Object Pascal . Eikä myöskään saisi pelätä matematiikkaa (käytössä logaritmit ja eksponenttifunktio).

Valmistautuminen

Kaavion tekeminen

  • Luo uusi projekti.
  • Koska laitamme joitakin pitkiä otsikoita akselille niin kasvata lomakkeen kokoa vähintään 540 x 320 pikseliin.
  • Lisää TChart komponentti, laita komponenttimuokkaimessa sen align arvoon alClient, Aseta sen BackColor arvoksi clWhite ja Grid.Color molemmille akselille arvoon clSilver.
  • Lisää otsikoksi x-akselille "Year of market introduction" (tai suomenkielisenä "Markkinoilletulo vuosi") ja y-akselille "Number of transistors" (Transistorien määrä).
  • Lisää teksti "Progress in Microelectronics" (tai "Mikroelektroniikan edistys") koko kaavion otsikoksi.
  • Aseta näiden fontin tyyliksi fsBold.
  • Näytä viitteenä datan lähde alatunnisteessa. Käytä kaavion ominaisuutta Foot siinä. Huomaa, että omaisuus Foot.Text (samoin kuin Title.Text ) voi syöttää usean rivin otsikon.

TAChart LogAx Tutorial1.png

Luodaan pistekuvaaja

Kun halutaan piirtää kullekin datatietueelle yksi piste - tätä usein kutsutaan pistekuvaajaksi muissa kaavio-ohjelmissa. TAChart kuvajaajissa ei ole tälläistä kuvaajaa koska TLineSeries voi tehdä tämän yhtähyvin. Laittamalla sen ominaisuus ShowPoints arvoon true ja poistamalla yhdistävät viivat (LineType = ltNone). Näytettävat datapisteet kuvataan ominaisuudessa Pointer.

Niin lisätään viivakuvaaja (LineSeries) ja asetetaan sen ominaisuudet niin että siitä tulee pistekuvaaja. Lisäksi asetetaan Pointer.Brush.Color arvoon clRed ja Pointer.Style arvoon psCircle tämä asettaa näyttämään kunkin datapisteen punaiselta ympyrältä.


Syötetään data

ListChartSource

On monia tapoja, joilla tietoja voidaan syöttää kaavioon. Nyt tässä käytetään ListChartSource:a. Yleensä tiedot ladataan tähän dynaamisesti ajon aikana, esimerkiksi lukemalla tiedot tiedostosta. Tässä projektissa kuitenkin data syötetään suunnitteluaikana käyttämällä datapisteen päätoimittaja ListChartSource. Tämän suurin etu on että kaikki muutokset, jotka tehdään kaavioon näytetään heti, ei tarvitse edes kääntää projektia. Kuten , on kuitenkin olemassa joitakin haittoja samoin.

ListChartSource tallentaa piirrettävän datan luetteloon - siitähän sen englanninkielinen nimi tulee. Luettelossa olevia kohteita kutsutaan TChartDataItem :ksi. Se sisältää datapisteen tietoja:

  • x ja y koordinaatit,
  • Text jota käytetään datan merkintään
  • Color eli väri-tieto joka ylikirjoittaa kuvaajan oletusvärin (SeriesColor)
  • YList joka sisältää lisää y:n arvoja joita tarvitaan joissakin erikoistapauksissa.

ListChartSource on samantyyppinen kaavion lähde, joka on käytössä monien kuvaajien luokkien sisällä. Kun se on erillinen komponentti on siitä kuitenkin etua, että samaa kaavion lähdettä voidaan käyttää uudelleen muissa kuvaajissa - tarvitsemme tätä ominaisuutta myöhemmin sovellettaessa FitSeries.

TAChart LogAx Tutorial2.png

Lisäämällä TListChartSource lomakkeelle. Tämä löytyy toisena kuvakeena chart-komponenttipaletilta. Kytke kuvaaja osoittamaan tähän lähteeseen asettamalla ominaisuus Source uuteen arvoon ListChartSource1.


ListChartSource datapisteiden muokkain

TAChart LogAx Tutorial16.png

Klikkaamalla kolmeapistepainiketta ominaisuudessa DataPoints avautuu datapisteiden muokkain. Tämä on ruudukko, johon syötetään tiedot. Kirjoita tiedot yllä olevasta kuvasta. Ne ovat otettu verkkosivuilta joka mainitaan johdannossa. Tämä sivusto näyttää markkinoille tulon ajan vuosittain ja kuukausittain - yksinkertaisuuden vuoksi ohitetaan kuukausi ja pyöristetään se lähimpään kalenterivuoteen. Anna vuosi sarakkeeseen X. Sarake Y saa transistorien määrä per piiri. Jokaisen mikroprosessorin nimi siirtyy sarakkeeseen Teksti. Koska ei anneta yksittäisen datapisteen väriä ohitetaan sarake Väri - mutta tietenkin sitä ominaisuutta voi kokeilla muuttaa.

Kun datapisteiden muokkain suljetaan niin sarja päivitetään automaattisesti ja näkyvissä on päivitetty tietojoukko. Vau!

Näytetään datapisteen nimi

Miksi emme näe prosessorien nimiä jotka asetettiin ruudukossa? Datapisteen nimi on oletuksena pois päältä. Valitse kuvaaja ja siirry kohtaan Marks . Katso aliominaisuutta Style , se on smsNone joka tarkoittaa "off" eli poispäältä. Avaa kyseisen kohdan pudotusvalikko. Näet erilaisia ​​vaihtoehtoja kuinka datapisteiden nimi voidaan merkitä. Testaa eri asetuksia. Jo suunnitteluaikana nähdään mitä ne tarkoittavat. Ota lopuksi käyttöön smsLabel joka näyttää tekstin.

On myös yhdistävä viiva nimen ja datapisteen välillä. Sen väri on oletuksena valkoinen, siksi sitä ei nähdä valkoisella taustalla. Tämän viivan ominaisuuksia muutetaan LinkPen kohdan alla. Aseta LinkPen.Color arvoon clGray .

Näiden nimien paikkaa pystyy jossain määrin muuttamaan MarkPositions ominaisuudessa.

TAChart LogAx Tutorial3.png

Jos ohjelma käännetään nyt niin mitään uutta ei tule verrattuna suunnitteluaikaiseen näkymään. Tämä on suuri etu kun työskentelee ListChartSource:n datapisteiden muokkaimella.

On kaksi asiaa, joita voidaan parantaa tässä vaiheessa:

  • Kaavion reunoilla datapisteiden nimet leikkautuvat pois. Sitä ei voi korjata lisäämällä kaavion Margin.Left ja Margin.Right arvoksi 24. Koska Margin määrittää ympäröivän tilan sisemmällä alueella pitää sen vapaana datapisteistä. On myös ominaisuus MarginExternal joka ympäröi kaavion ulompaa aluetta ja sillä voidaan muuttaa etäisyyttä naapurikontrolleihin.
  • Koska lähes kaikki datapisteet ovat kaavion alareunassa niin se ei ole kovin mielekästä. Tämän vuoksi tarvitsemme logaritmistä akselia.

Otetaan logaritminen akseli käyttöön

Datan näyttäminen logaritmisella akselilla tarkoittaa, että logaritmit data-arvot on piirretty, ei arvoja suoraan. Kaaviossa Y: n arvot vaihtelevat välillä 2300 ja 731 miljoonaa. Kun lasketaan (decadic/log10) logaritmit, alue on vain noin 3,3 ja 7,1 - tällaisessa kaaviossa tämä data voidaan erottaa paljon helpommin toisistaan.


TChartTransformations and LogarithmicAxisTransform

TAChart LogAx Tutorial4.png

Calculating the logarithm can be done by TAChart automatically. The main advantage is that the original data units are drawn on the axis while the logarithms are used for plotting.

In fact, there is an entire group of components for axis transformations: TChartAxisTransformations. An axis transformation is a function which maps "real world" data in units as displayed on the axis ("axis coordinates") to internal units that are common to all series in the same chart ("graph coordinates"). The axis coordinate of the transistor count of the 4004 processor, for example, is 2300, the graph coordinate is the logarithm of that number, i.e. log10(2300) = 3.36.

TAChart provides a variety of transforms. In addition to the logarithm transform, there is a linear transform which allows to multiply the data by a factor and to add an offset. The auto-scaling transform is useful when several independently scaled series have to be drawn on the same axis. The user-defined transform allows to apply any arbitrary transformation.

TAChart LogAx Tutorial5.png

Add a TAChartTransformations component to the form, double-click on it (or right-click on it in the object tree and select "Edit axis transformations"), click on "Add" and select "Logarithmic". This will create a ChartAxisTransformations1LogarithmAxisTransform1 component - what a name! Anyway, there's a high chance that you will not have to type it...

In the object inspector, you will see only a few properties - the most important one is Base. This is the base of the logarithm to be calculated. Change it to 10, since we want to calculate the decadic logarithms - this case comprises 99% of all logarithmic charts.

A side-note: it is very important that you save the project at this time. Why? You will see in a minute...

Now we must identify the axis which is to be transformed. For this purpose each axis has a property Transformations. In our case, the huge numbers are plotted on the y axis. So, go to the left axis and set its property Transformations to ChartAxisTransformations1.

TAChart LogAx Tutorial17.png

Oh - what's that? An error message pops up reporting a range check error. Hopefully you had saved the project. If you click on Cancel Lazarus will shut down, everything will be lost. If you click on OK suddenly the chart is gone, it reappears when you click somewhere, but the faulty axis is hidden ...

Are you getting desperate?

This is the main disadvantage of working at design-time. If something goes wrong, there is no debugger, no indication of what caused the trouble. Since components are compiled into Lazarus you would have to debug the IDE. Sounds complicated...

Let's sit down and think what we did. We assigned the logarithmic transform to the y axis. The transform does not yet have any connection to the data, therefore the data are still in "real" units, their maximum is 731 million. But the transform "thinks" that the data are already in graph units (logarithms). When it calculates the axis labels in axis units it takes hundreds of millions to the power of 10! That's what causes the range check error. However, the situation is not always so dramatic; the least thing that could happen is that the data are not transformed, but the axis is.

What can we do against that? Each series has properties AxisIndexX and AxisIndexY. The transform can use this information to calculate the logarithms of the correct coordinates before the axis labels are updated. This solves our problem.

So, click on Cancel to shutdown Lazarus. Restart and reload the project. In the saved state, the transformation is not yet connected to the axis.

Now have a look at the object tree above the object inspector and you will see that the left axis has index 0. So set the series' AxisIndexY to this value. Although not necessary it may be a good idea to disarm also the x axis by assigning its index 1 to the AxisIndexX of the series - who can guarantee that we won't transform the x axis in the future?

After this is done you can set the LeftAxis.Transformation to ChartTransformations1 without the range check error.

With the logarithm transform activated the data points spread nicely across the y axis range now. But what's wrong with the y axis labels? And the years on the x axis are too close and partly overlap.

TAChart LogAx Tutorial6.png

Finding axis labels is a non-trivial task, in particular when transformations are active that heavily distort the axis intervals. Unfortunately, logarithmic axes belong to that group. Basically, there are two ways to control label positioning, an automatic and a manual way.

Automatic finding of axis labels

For automatic label positioning, each axis has a property Intervals which gives access to several, partly mutually excluding parameters - please see TAChart documentation for an explanation. In case of the logarithmic axis the issue is usually caused by the fact that the option aipGraphCoordinates is not set. This option, if set, enforces calculation of the tick intervals for the transformed data ("graph coordinates"), not the "real world" data ("axis coordinates"). So, set aipGraphCoordinates in the LeftAxis.Intervals.Options. The labels jump to more evenly distributed locations.

TAChart LogAx Tutorial7.png

Depending on the size of your form you may get quite nice, or not so good labels. If you resize the form you will see some "crooked" labels jump in.

You can improve the quality of label presentation in the following way:

  • Moderately increase the Intervals.Tolerance to something like 5.
  • Adjust the range in which the label distance can vary. This is defined by the properties Intervals.MaxLength and Intervals.MinLength. The optimum value depends on the size of the chart and on the range of the data. In our example project, good labels are obtained by setting these properties to 100 and 50, respectively.

In the same way, the overlapping year labels of the x axis can be addressed. Just increase the BottomAxis.Intervals.MaxLength to 70.

What is left now is the "1" that appears at the y axis between "10000000" and "1E009". This is due to a bug in some FPC versions. If you have that as well, simply change the property LeftAxis.Marks.Format. This string is passed to the Format function to convert the numbers to strings. The format specifier "%0.0n" for example avoids that conversion error and, additionally, adds nice thousand separators to the labels which makes them much more readable.

TAChart LogAx Tutorial8.png

Manual finding of axis labels

This is the best we can do with automatic label positioning. It is not perfect because when we increase the height of the window, or zoom in, the half-decade values may appear, or the label interval may be two decades as in above figure.

If you are not happy with that you have to use manual axis label selection. For this purpose, each axis has a property Source which can be linked to a ListChartSource containing only the allowed axes labels. So when this chart source contains only full-decade labels there is no risk of half-decade labels or omitting every other label. On the other hand, when you zoom into the chart you may come to a point where no labels are visible any more.

Add a second ListChartSource to the form. You can use the DataPoints editor again to enter the full-decade numbers. This has the advantage that you can complete most of this project without writing a single line of code!

But you could also populate the listsource easily in the FormCreate event:

procedure TForm1.FormCreate(Sender: TObject);
const
  MIN = 0;
  MAX = 12;
var
  i: Integer;
  value: double;
begin
  for i:=MIN to MAX do begin
    value := Power(10, i);
    ListChartSource2.Add(value, value);
  end;
end;

This procedure adds powers of 10 in a wide enough range to the ListChartSource by means of its method Add.

Connect ListChartSource1 to LeftAxis.Marks.Source to activate the manual labels of the ListChartSource. You should also remove all flags from the Options property. Otherwise automatic tick finding will still be active to some degree. If you did not use the DataPoints editor you must compile to see the effect.

TAChart LogAx Tutorial9.png

Minor tick marks

Very often minor tick marks are placed between the major tick marks. TAChart allows to add several sets of minor ticks to each axis. We only need one here. Go to LeftAxis and click on the ellipsis button next to the property Minors. This opens the editor for Chart1.AxisList[0].Minors. Click on "Add" and on the "M" in the list below. Now you can adjust the parameters in the object inspector to get "good" minor ticks. If the major ticks on a logarithmic axis are at full decades then the minor ticks usually are at 2, 3, 4,..., 8, 9, and, of course, powers of 10. This can be achieved easily by turning off all Intervals.Options except for aipUseCount and setting Intervals.Count = 9. Of course, this makes sense only when the major labels are fixed at full decades like in the manual approach above.

Usually the plot gets too crowded by the minor grid which appears now, you should set the minor's Grid.Visible to false.

TAChart LogAx Tutorial10.png

Fitting

Now let's look for a relation between the data, i.e. we want to find a mathematical formula which describes the dependence of transistor count on market introduction year. This is called "fitting": we select a formula with parameters and adjust the parameters such that the deviation to the data is as small as possible.

TAChart does not contain a full-fledged fitting engine. It uses the fitting routines from the FPC numerical library numlib. Therefore, TAChart cannot address all variants of fitting, but it covers the most important case, fitting of a polynomial by means of the linear least squares technique. This is about the level available to Excel users when they add a "trend line" to their chart.

TFitSeries

TAChart provides a specialized TFitSeries for fitting. This series has a property FitEquation which defines the formula that is used:

  • fePolynomial: y = b0 + b1x + b2x2 + … + bnxn. Specify the number of fitting parameters ai by the property ParamCount = n + 1.
  • feLinear: y = a + bx -- this is a special case of the general polynomial with n = 1 and fitting parameters a and b. It is made available as a separate item because straight lines define the most important fitting conditions.
  • feExp: y = a * ebx -- This equation can also be reduced to the polynomial case although this is not straightforward to see. But take the (natural) logarithm of this equation, and you get to ln(y) = a + bx. Now when we fit ln(y) instead of y we have the linear case again.
  • fePower: y = a * xb. Again, this can be reduced to a linear equation by a logarithmic transformation.

TAChart LogAx Tutorial11.png

Enough of theory. Let's add a FitSeries to the chart: double-click on the chart, and in the series editor click on "Add" and select the entry "Least squares fit series" from the dropdown list.

At first, we need to tell the fit series where it finds its data. For this purpose, we connect the series' Source with ListChartSource1 as we had done with the line series. You see: the same chart source can be used for several series.

You hopefully remember the disaster above with the AxisIndex. So, set the AxisIndexY to the index of the left axis as we did with the line series.

Which one of the four FitEquation possibilities do we select? Well, the data look like lying on a straight line. So let's select feLinear.

TAChart LogAx Tutorial12.png

Oops... We see the black fitted curve, but it does not "fit" at all. And we wanted a straight line, but we get a twisted curve. How can this be?

The reason is the logarithmic transform that we applied to the y data. Therefore, our plot shows the logarithms, but the fit takes the "raw" data. We are effectively fitting the straight line to the data in the screenshot in the section Displaying datapoint marks where the log transform had not yet been introduced - it is clear that the line would not "fit" there. And when the fitted function is drawn the log transform distorts the straight line to the twisted curve that we see.

On the other hand, if the log data follow a straight line our fitting law is not linear, but exponential. Let's set FitEquation to feExp and try again.

TAChart LogAx Tutorial13.png

Ah - much better!

Now we know that the exponential law, y = a * xb, is a good description of our data. But how do we get the fitting parameters a and b?

Fit results

The fit series has a public array property Param which contains the fitting parameters. a is in Params[0], and b is in Params[1]. Of course, these values are correct only when a valid fit has been performed. How do we know that? Well, the fit series provides an event OnFitComplete that is generated when the fit complete successfully. That's where we can evaluate the obtained fit parameters. As an example, let's display the fit results in a message along with the fit equation:

procedure TForm1.Chart1FitSeries1FitComplete(Sender: TObject);
begin
  with Chart1FitSeries1 do
    ShowMessage(Format(
      'Fit result: a = %g, b = %g', [
      Param[0], Param[1]
    ]));
end;

And that's what we get:

TAChart LogAx Tutorial14.png

Now we want to calculate the time T until the number of transistors on a chip is doubled. As an exercise try to show that

T = ln(2) / b

It would be nice to show the doubling time as an additional line of the chart title. For this, we modify the OnFitComplete event handler as follows:

procedure TForm1.Chart1FitSeries1FitComplete(Sender: TObject);
begin
  Chart1.Title.Text.Add(Format(
    'The number of transistors doubles every %.0f years',
    [ln(2) / Chart1FitSeries1.Param[1]]
  ));
end;

TAChart LogAx Tutorial15.png

Vau! Tämä on Mooren laki: "Transistoreiden määrä per siru kaksinkertaistuu kahden vuoden välein" ...

Lähdekoodi

Project file

program project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, Unit1, tachartlazaruspkg
  { you can add units after this };

{$R *.res}

begin
  //RequireDerivedFormResource := True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Unit1.pas

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, TAGraph, TASeries, TASources, Forms, Controls,
  Graphics, Dialogs, TACustomSource, TATransformations, TAFuncSeries;

type

  { TForm1 }

  TForm1 = class(TForm)
    Chart1: TChart;
    Chart1FitSeries1: TFitSeries;
    Chart1LineSeries1: TLineSeries;
    ChartAxisTransformations1: TChartAxisTransformations;
    ChartAxisTransformations1LogarithmAxisTransform1: TLogarithmAxisTransform;
    ListChartSource1: TListChartSource;
    ListChartSource2: TListChartSource;
    procedure Chart1FitSeries1FitComplete(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

uses
  math;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
const
  MIN = 0;
  MAX = 12;
var
  i: Integer;
  value: double;
begin
  for i:=MIN to MAX do begin
    value := IntPower(10, i);
    ListChartSource2.Add(value, value);
  end;
  Chart1FitSeries1.ExecFit;
end;

procedure TForm1.Chart1FitSeries1FitComplete(Sender: TObject);
begin
  {
  with Chart1FitSeries1 do
    ShowMessage(Format(
      'Fit result: a = %g, b = %g', [
      Param[0], Param[1]
    ]));
  }
  Chart1.Title.Text.Add(Format(
    'The number of transistors doubles every %.0f years',
    [ln(2) / Chart1FitSeries1.Param[1]]
  ));
end;

end.

Unit1.lfm

object Form1: TForm1
  Left = 244
  Height = 356
  Top = 193
  Width = 552
  Caption = 'Form1'
  ClientHeight = 356
  ClientWidth = 552
  OnCreate = FormCreate
  LCLVersion = '1.1'
  object Chart1: TChart
    Left = 0
    Height = 356
    Top = 0
    Width = 552
    AxisList = <    
      item
        Grid.Color = clSilver
        Marks.Format = '%0:.0n'
        Marks.Source = ListChartSource2
        Marks.Style = smsCustom
        Minors = <        
          item
            Grid.Visible = False
            Intervals.Count = 9
            Intervals.MinLength = 5
            Intervals.Options = [aipUseCount]
          end>
        Title.LabelFont.Orientation = 900
        Title.LabelFont.Style = [fsBold]
        Title.Visible = True
        Title.Caption = 'Number of transistors'
        Transformations = ChartAxisTransformations1
      end    
      item
        Grid.Color = clSilver
        Intervals.MaxLength = 60
        Alignment = calBottom
        Minors = <>
        Title.LabelFont.Style = [fsBold]
        Title.Visible = True
        Title.Caption = 'Year of market introduction'
      end>
    BackColor = clWhite
    Foot.Alignment = taLeftJustify
    Foot.Brush.Color = clBtnFace
    Foot.Font.Color = clBlue
    Foot.Text.Strings = (
      'Source:'
      'http://www.intel.com/pressroom/kits/quickreffam.htm'
    )
    Foot.Visible = True
    Margins.Left = 24
    Margins.Right = 24
    Title.Brush.Color = clBtnFace
    Title.Font.Color = clBlue
    Title.Font.Style = [fsBold]
    Title.Text.Strings = (
      'Progress in Microelectronics'
    )
    Title.Visible = True
    Align = alClient
    ParentColor = False
    object Chart1LineSeries1: TLineSeries
      Marks.Format = '%2:s'
      Marks.LinkPen.Color = clGray
      Marks.Style = smsLabel
      AxisIndexY = 0
      LineType = ltNone
      Pointer.Brush.Color = clRed
      Pointer.Style = psCircle
      ShowPoints = True
      Source = ListChartSource1
    end
    object Chart1FitSeries1: TFitSeries
      AxisIndexX = 1
      AxisIndexY = 0
      FitEquation = feExp
      OnFitComplete = Chart1FitSeries1FitComplete
      ParamCount = 2
      Source = ListChartSource1
    end
  end
  object ListChartSource1: TListChartSource
    DataPoints.Strings = (
      '1972|2300|?|4004'
      '1974|6000|?|8080'
      '1978|29000|?|8086'
      '1982|134000|?|80286'
      '1986|275000|?|80386'
      '1989|1200000|?|80486'
      '1993|3100000|?|Pentium'
      '1997|7500000|?|Pentium II'
      '2001|42000000|?|Xeon'
      '2006|152000000|?|Core Duo'
      '2009|731000000|?|Core i7'
    )
    left = 240
    top = 40
  end
  object ChartAxisTransformations1: TChartAxisTransformations
    left = 243
    top = 96
    object ChartAxisTransformations1LogarithmAxisTransform1: TLogarithmAxisTransform
      Base = 10
    end
  end
  object ListChartSource2: TListChartSource
    left = 243
    top = 176
  end
end