Stacked Bar Chart

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Errol
Newbie
Newbie
Posts: 75
Joined: Thu Jul 11, 2013 12:00 am

Stacked Bar Chart

Post by Errol » Thu Feb 13, 2014 5:46 am

I wish to use the Stacked Bar Chart to draw lithology columns direct from a table of data in a database. I also want to use as much of existing line chart code as possible, which uses a custom TLineSeries to convert data from the underlying SI values to user units (for instance, m to ft).

The line series code is as follows, using fields in the table such as Depth on Independent Axis, and Temperature and Pressure on two independent axes:
ChangeNode Move to a different header/detail table
GenerateGraph Set up the graph to be drawn
ClearAll Remove all series from chart, clear datasources, clear series from collections (for each dependent axis)
InsertSeries Insert UnitLineSeries (with unit conversion code) into a collection for each dependent axis.
Set X/Y ValueSource Fields in the table
Set DataSource Detail table query based on header record
RefreshAllSeries Calls TChartSeries.RefreshSeries for each collection.
Chart.RefreshData Calls TCustomDBChart.RefreshData

When I move to another record in the header table, the program simply Calls RefreshAllSeries and Chart.RefreshData.

This works fine, but when I apply the same technique to a stacked bar chart, I have a lot of problems. Typical fields in table are Strata Top, Strata Bottom, Rock Type, Pattern, Foreground, Background. In this case, the InsertSeries step has to carry out calculations to calculate the depth increments, insert missing sections, so I need to call it again every time I move from record to record. I am having trouble with the following:
1. Coloring the foreground and background of the selected patterns. I set ColorSource = 'Foreground' which doesn't seem to color the foreground correctly - it starts of well but for repeat rock types the pattern is correct but the color has changed. And how can I use the Background values to color the background.
2. Legend. Rocktypes are repeated but I want only one instance of each rocktype in the legend (and preferably in alphabetical order). Is there any easy way to do this (remember I am sending a BarSeries to the chart, not drawing the chart record by record.
3. Labels. I want to label each strata with a comment from the table that stays with the bar chart when I zoom. I don't seem to have much success here.
3. How can I control the position of the bar chart on the chart. I have used a dummy numeric x-axis (Depth is on the y-axis) and the bar chart is located at the value zero. in the middle of the chart window. When I zoom (vertical only) the chart jumps to the left-hand axis.
4. Multiple bar charts. If I select a number of sets of lithology data, I want to place them side by side on a common y-axis, at user-specified positions. Any ideas on how to do this?

I look forward to any comments and suggestions.

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Stacked Bar Chart

Post by Narcís » Fri Feb 14, 2014 12:08 pm

Hello Errol,

Thanks for the explanation. It's difficult to be able to provide accurate replies without seeing how do you exactly implement such functionality with TeeChart though. To be able to help you and give effective suggestions and solutions, it would be very helpful if you arranged a simple example project we can run "as-is" to reproduce those issues here.

Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Errol
Newbie
Newbie
Posts: 75
Joined: Thu Jul 11, 2013 12:00 am

Re: Stacked Bar Chart

Post by Errol » Wed Feb 19, 2014 6:14 am

Lithology_Chart.png
Lithology_Chart.png (16.93 KiB) Viewed 19325 times
I have made some progress with the stacked bar chart. I use two procedures, firstly InsertGeologicalSeries which puts the data queried from the database in a memory table, and calculates depth increments. The program then creates a unit bar series and links the DataSource to the memory table. TUnitBarSeries.DrawBar overrides Series.TBarSeries.DrawBar.

I am now able to colour the foreground and background, but I am unable to draw a legend apart from one showing the Name of the TUnitBarSeries and a random colour. (see attachment). I have searched the entire TeeChart Help and am unable to find out how to do this. Any suggestions welcome.

Code: Select all

procedure TQSCollection.InsertGeologicalSeries(aCodeFld,aFld:string);

var
  iIndex,k : integer;
  stitle,sxfield,syfield : string;
  tmpHorizAxis: TChartAxis;
  sDepField : string; 

begin
  self.Owner.Chart.LeftAxis.Inverted := True;
  self.Owner.IndependentField := 'Depth';
  self.owner.IntervalQuery := TkbmMemTable.Create(self.Owner);
  self.owner.IntervalQuery.FieldDefs.Assign(self.Owner.UnitDataSet.GetDataSet.FieldDefs);
  self.owner.IntervalQuery.FieldDefs.Add(self.Owner.IndependentField, ftFloat, 0, false);
  self.owner.IntervalQuery.Open;
  self.Owner.UnitDataSet.GetDataSet.First;

  while not self.Owner.UnitDataSet.GetDataSet.Eof do
  begin
    self.owner.IntervalQuery.Append;
    self.owner.IntervalQuery.CopyFields(self.Owner.UnitDataSet.GetDataSet);
    self.owner.IntervalQuery.FieldByName('Depth').asFloat :=
      self.owner.IntervalQuery.FieldByName('Strata Bottom').asFloat
       - self.Owner.IntervalQuery.FieldByName('Strata Top').asFloat;
    self.owner.IntervalQuery.Post;
    self.Owner.UnitDataSet.GetDataSet.Next;
  end;

  self.owner.IntervalQuery.First;
  sTitle := 'Lithology Profile';

  SeriesListB.AddObject(sTitle, TUnitBarSeries.Create(Owner));
    iIndex := SeriesListB.IndexOf(sTitle);
    with TUnitBarSeries(SeriesListB.Objects[iIndex]) do
    begin
      FirstDraw := true;
      MultiBar := mbSelfStack;
      CustomBarWidth := 80;
      ParentChart := self.Owner.Chart;
      ShowInLegend := true;   //self.Owner.EnableLinerLegend;
      Name := GetValidName(sTitle);  // removes spaces

      ColorSource := 'Foreground';
      YValues.ValueSource := self.Owner.IndependentField;  // Depth increments
      XValues.ValueSource := sDepField;   // an attempt to place the bar chart in a defined position        
      DataSource := self.Owner.IntervalQuery; 
      HorizAxis := aBottomAxis;
      VertAxis := aLeftAxis;

      sxField := sDepField;
      syField := Self.Owner.IndependentField;
      XUnitType := self.Owner.UnitSystem.GetFieldType(sxfield);  // for unit changing
      YUnitType := self.Owner.UnitSystem.GetFieldType(syfield);  // for unit changing
  end; 

procedure TUnitBarSeries.DrawBar(BarIndex, StartPos, EndPos: Integer);
begin
  // go to dataset record for this index
  TkbmMemTable(self.DataSource).RecNo := BarIndex + 1;
  Brush.Style := TBrushStyle(TkbmMemTable(self.DataSource).FieldByName('Pattern').asInteger);  // hard-coded pattern field name
  Brush.Color := TColor(TkbmMemTable(self.DataSource).FieldByName('Background').asInteger);
  ShowInLegend := True;
  inherited DrawBar(BarIndex,StartPos,EndPos);
end;


Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Stacked Bar Chart

Post by Narcís » Thu Feb 20, 2014 9:21 am

Hi Errol,
Errol wrote:I am unable to draw a legend apart from one showing the Name of the TUnitBarSeries and a random colour. (see attachment).
I'm not sure about how you'd like the legend to be. According to your previous post:
Errol wrote: 2. Legend. Rocktypes are repeated but I want only one instance of each rocktype in the legend (and preferably in alphabetical order). Is there any easy way to do this (remember I am sending a BarSeries to the chart, not drawing the chart record by record.
So I assume you'd like to have all values in the series being represented in the legend. You can do that using default legend style:

Code: Select all

  Chart1.Legend.LegendStyle:=lsAuto;
Or force that setting it like this:

Code: Select all

  Chart1.Legend.LegendStyle:=lsValues;
If that's not what you are looking for, please provide more information with a simple code example we can run here to reproduce the problem.

Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Errol
Newbie
Newbie
Posts: 75
Joined: Thu Jul 11, 2013 12:00 am

Re: Stacked Bar Chart

Post by Errol » Thu Feb 20, 2014 11:30 pm

Hi Narcis

Thanks for your reply and pointing me to your previous post that I had somehow overlooked. However, I have had no success with your suggestions. I have attached a code snippet below - but all this does is draw a legend with a random pattern and the name of the bar series. Clearly I am not pointing the Legend at the correct field in the DataSource but I cannot find out how to do this.

Code: Select all

procedure TQSCollection.InsertGeologicalSeries(aCodeFld,aFld:string);

begin

// code to populate IntervalQuery, a kbmMemTable, from the database table

  self.owner.IntervalQuery.First;

// construct title
  sTitle := self.Owner.UnitSystem.GetPreferredName('Lithology Profile'); 

  SeriesListB.AddObject(sTitle, TUnitBarSeries.Create(Owner));
  iIndex := SeriesListB.IndexOf(sTitle);
  with TUnitBarSeries(SeriesListB.Objects[iIndex]) do
  begin
    MultiBar := mbSelfStack;
    CustomBarWidth := 80;

    self.Owner.Chart.Legend.Visible := True;
    self.Owner.Chart.Legend.LegendStyle := lsAuto;

    Name := GetValidName(sTitle);

    ColorSource := 'Foreground';
    XLabelsSource := 'Rock Type Code';
    YValues.ValueSource := self.Owner.IndependentField;
    XValues.ValueSource := sDepField;
    DataSource := self.Owner.IntervalQuery; // assumes query is active

    YLabelDisplay := ldUnit;
    HorizAxis := aBottomAxis;
    VertAxis := aLeftAxis;
    sxField := sDepField;
    syField := Self.Owner.IndependentField;
    active := true;
  end;
end;

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Stacked Bar Chart

Post by Narcís » Fri Feb 21, 2014 10:13 am

Hi Errol,

What about setting LegendStyle to lsValues? Does it make any difference?

Could you please arrange a simple example project we can run "as-is" to reproduce the problem here? You could use random/manual data simulating your real environment.

Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Errol
Newbie
Newbie
Posts: 75
Joined: Thu Jul 11, 2013 12:00 am

Re: Stacked Bar Chart

Post by Errol » Mon Feb 24, 2014 5:54 am

Hi Narcis

Thank you for your suggestion. I set LegendStyles to lsValues and sure enough I obtained a legend (see attachment). However, there are a couple of issues:
1. The legend symbols show only the foreground colour of the corresponding bar, not the whole pattern. Can the symbol be modified to duplicate the bar pattern, foreground and background? I draw the pattern by using ColorSource, Brush.Style and Vrush.Color.
2. The legend text gives both the incremental depth and the Rock Type Code. I see that XLabelsSource controls the text field (in this case Rock Type Code). How do I suppress the incremental depth value?
3. Can I turn individual items of the legend on and off?

Thanks in advance

Errol
Lithology_Chart_Labels003.png
Lithology_Chart_Labels003.png (21.75 KiB) Viewed 19203 times

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Stacked Bar Chart

Post by Narcís » Mon Feb 24, 2014 12:58 pm

Hi Errol,
1. The legend symbols show only the foreground colour of the corresponding bar, not the whole pattern. Can the symbol be modified to duplicate the bar pattern, foreground and background? I draw the pattern by using ColorSource, Brush.Style and Vrush.Color.
In that case I recommend you to use the legend Picture property as explained here. Notice this is included with the version we published earlier today. This might not be suitable for different symbol pictures in a single series, in which case you could do as in the All Features\Welcome!\Miscellaneous\Legend\Symbol OnDraw example in the new features demo, available at TeeChart's program group.
2. The legend text gives both the incremental depth and the Rock Type Code. I see that XLabelsSource controls the text field (in this case Rock Type Code). How do I suppress the incremental depth value?
You can either set the LegendStyle property or use the OnGetLegendText event to parse and remove it or Chart1.Legend.Items list as in the All Features\Welcome!\Miscellaneous\Legend\Items property.
3. Can I turn individual items of the legend on and off?
This can only be done with legend checkboxes or using the ShowInLegend property with multiple series.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Errol
Newbie
Newbie
Posts: 75
Joined: Thu Jul 11, 2013 12:00 am

Re: Stacked Bar Chart

Post by Errol » Tue Feb 25, 2014 4:02 am

Hi Narcis

Thanks for your reply. However, I am stuck on one thing - you refer to "All Features\Welcome!\Miscellaneous\Legend\... in the new features demo, available at TeeChart's program group". However, I have no idea of how to find this new features demo. Is it on your website or is it part of my TeeChart installation? I have installed the binary version and see a file called Tee9New.exe but this doesn't run (an entry point cannot be found in Tee911.bpl). Please advise.

Many thanks

Errol

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Stacked Bar Chart

Post by Narcís » Tue Feb 25, 2014 8:09 am

Hi Errol,

Yes, that's Tee9New.exe. Given the error message you mentioned, you should open the demo project and compile it at your end.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Errol
Newbie
Newbie
Posts: 75
Joined: Thu Jul 11, 2013 12:00 am

Re: Stacked Bar Chart

Post by Errol » Tue Feb 25, 2014 9:46 pm

Hi Narcis

Thanks for your suggestions regarding the Steema demo project. I opened C:\Program Files (x86)\Steema Software\TeeChart 2013 for Delphi 2007\Examples\Features\Tee9New.dpr. This failed to compile with the following error:
[DCC Error] Tee9new.dpr(639): F2063 Could not compile used unit 'Tools_Clustering.pas'

I then downloaded and installed TeeChart2012_Examples.zip from the Steema website. TeeChart2010_Examples\Tee9new.exe runs without problems. The file date is 29/01/2013 so I presume it is up-to-date even though it is located in TeeChart2010_Examples folder.

Regards

Errol

Errol
Newbie
Newbie
Posts: 75
Joined: Thu Jul 11, 2013 12:00 am

Re: Stacked Bar Chart

Post by Errol » Tue Feb 25, 2014 10:07 pm

I have a query about patterns used to fill bar charts. At present I use the standard Windows patterns (bsSolid, bdDiagonal, etc). These have the advantage of displaying with a constant pattern size (no stretching or compressing to fit the bar rectangle) and auto-clipping at the bar boundaries. I understand that any bitmap can be used as a pattern. Are these bitmaps displayed at a constant pattern size (using some auto-repeat to fill large bars) or are they stretched to fit? Also is there a library of well-behaved patterns available (for instance thick diagonal, brick, etc) so I do not have to create these.

Thanks in advance

Errol

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Stacked Bar Chart

Post by Yeray » Wed Feb 26, 2014 12:36 pm

Hi Errol
Errol wrote:Thanks for your suggestions regarding the Steema demo project. I opened C:\Program Files (x86)\Steema Software\TeeChart 2013 for Delphi 2007\Examples\Features\Tee9New.dpr. This failed to compile with the following error:
[DCC Error] Tee9new.dpr(639): F2063 Could not compile used unit 'Tools_Clustering.pas'

I then downloaded and installed TeeChart2012_Examples.zip from the Steema website. TeeChart2010_Examples\Tee9new.exe runs without problems. The file date is 29/01/2013 so I presume it is up-to-date even though it is located in TeeChart2010_Examples folder.
We'll try to update the precompiled examples as soon as possible. In the meanwhile note you can also find an up to date version of the versions in the v2014.10 installers recently published.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Stacked Bar Chart

Post by Yeray » Wed Feb 26, 2014 3:37 pm

Hi Errol,
Yeray wrote: We'll try to update the precompiled examples as soon as possible. In the meanwhile note you can also find an up to date version of the versions in the v2014.10 installers recently published.
Just done!
http://www.steema.com/download/vcl
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Stacked Bar Chart

Post by Yeray » Wed Feb 26, 2014 3:59 pm

Hi again Errol,
Errol wrote:I have a query about patterns used to fill bar charts. At present I use the standard Windows patterns (bsSolid, bdDiagonal, etc). These have the advantage of displaying with a constant pattern size (no stretching or compressing to fit the bar rectangle) and auto-clipping at the bar boundaries. I understand that any bitmap can be used as a pattern. Are these bitmaps displayed at a constant pattern size (using some auto-repeat to fill large bars) or are they stretched to fit? Also is there a library of well-behaved patterns available (for instance thick diagonal, brick, etc) so I do not have to create these.
You can set any image you like as a brush:

Code: Select all

Series1.Brush.Image.LoadFromFile('E:\tmp\flower.jpg');
The same can be done through the editor at the Series/Pattern/Custom tab
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply