MultiBar for TCandleSeries

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
vas
Newbie
Newbie
Posts: 20
Joined: Wed Oct 17, 2007 12:00 am

MultiBar for TCandleSeries

Post by vas » Sat Apr 16, 2011 10:34 am

I would like to display multiple Candle series, but stagger them on the X axis, similar to MultiBar=mbSide
Is that possible?

I am really truing help my users visualize uncertainty.
AddCandle(X, u+1SD, u+2SD, u-2SD, u-1SD)

Multiple series overlap each other.

Thanks,
Steve

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: MultiBar for TCandleSeries

Post by Sandra » Mon Apr 18, 2011 9:58 am

Hello Steve,

I have added your request as a feature request in wish-list with number [TV52015508] to be considered for inclusion in future releases. On the other hand,
I recommend you try to work with only one series and adding slightly different X values when you want values side and achieve the same effect as Multibar= mbSide.

Thanks,
Best Regards,
Sandra Pazos / 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

vas
Newbie
Newbie
Posts: 20
Joined: Wed Oct 17, 2007 12:00 am

Re: MultiBar for TCandleSeries

Post by vas » Mon Apr 18, 2011 10:30 am

I have five series that the users can enable/disable with a checkbox in the legends.

might there be any other series that allows mbSide, with a error-box that I can control both the upper and lower location of the box, as well as the upper and lower limits of the error bars?

Or is there a work-around I can make in the source code to emulate mbSide?

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: MultiBar for TCandleSeries

Post by Sandra » Tue Apr 19, 2011 9:07 am

Hello Steve,
might there be any other series that allows mbSide, with a error-box that I can control both the upper and lower location of the box, as well as the upper and lower limits of the error bars?
Yes, you can try to do the same with error bar. I recommend take a look in Demo Project concretely in All features\Chart Style\Statistical .
Or is there a work-around I can make in the source code to emulate mbSide?
For now we don't have any work-around to it, but your request is in wish-list (TV52015508) to be considered inclusion in next versions, how I said previously.

Thanks,
Best Regards,
Sandra Pazos / 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

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

Re: MultiBar for TCandleSeries

Post by Yeray » Tue Apr 19, 2011 11:32 am

Hello Steve,

As an addition, I thought on a workaround.
You can inherit from the TBar3DSeries to create a new series that will have two errors.
Here you have a start point:

Code: Select all

uses Bar3D, Math;

type
  TBar3DErrorSeries = class(TBar3DSeries)
  private
    BarErrors, OffsetErrors: TChartValueList;
  protected
    procedure AddSample(Index: Integer; const Y: Double);
    procedure AddSampleValues(NumValues:Integer; OnlyMandatory:Boolean=False); override;
    procedure DrawBar(BarIndex,StartPos,EndPos:Integer); override;
  end;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D:=false;

  for i:=0 to 4 do
  begin
    with Chart1.AddSeries(TBar3DErrorSeries) as TBar3DErrorSeries do
    begin
      BarErrors:=TChartValueList.Create(Chart1[i], 'BarErrors');
      OffsetErrors:=TChartValueList.Create(Chart1[i], 'OffsetErrors');

      FillSampleValues();
      Marks.Visible:=false;
    end;
  end;
end;

{ TBar3DErrorSeries }

procedure TBar3DErrorSeries.AddSampleValues(NumValues: Integer;
  OnlyMandatory: Boolean);
var t : Integer;
begin
  inherited;

  for t:=0 to NumValues-1 do
      AddSample(t, Max(YValues.MaxValue, OffsetValues.MaxValue) - Min(YValues.MinValue, OffsetValues.MinValue));
end;

procedure TBar3DErrorSeries.AddSample(Index: Integer; const Y: Double);

  function TempRandom:Double;
  begin
    result:=(20+RandomValue(4));
  end;

begin
  BarErrors.Value[Index]:=Y/TempRandom;
  OffsetErrors.Value[Index]:=Y/TempRandom;
end;

procedure TBar3DErrorSeries.DrawBar(BarIndex,StartPos,EndPos:Integer);
var XPos, BarPos, OffsetPos, BarErrPos, OffsetErrPos: Integer;
begin
  inherited;

  XPos:=CalcXPos(BarIndex) + BarWidth div 2;
  BarPos:=CalcYPosValue(YValue[BarIndex]);
  OffsetPos:=CalcYPosValue(OffsetValues[BarIndex]);

  if (YValues[BarIndex] > OffsetValues[BarIndex]) then
  begin
    BarErrPos:=CalcYPosValue(YValue[BarIndex] + BarErrors[BarIndex]);
    OffsetErrPos:=CalcYPosValue(OffsetValues[BarIndex] - OffsetErrors[BarIndex]);
  end
  else
  begin
    BarErrPos:=CalcYPosValue(YValue[BarIndex] - BarErrors[BarIndex]);
    OffsetErrPos:=CalcYPosValue(OffsetValues[BarIndex] + OffsetErrors[BarIndex]);
  end;

  if BarErrors[BarIndex]<>0 then
  begin
    if ParentChart.View3D then
      ParentChart.Canvas.VertLine3D(XPos, BarPos, BarErrPos, MiddleZ)
    else
      ParentChart.Canvas.DoVertLine(XPos, BarPos, BarErrPos);
  end;

  if OffsetErrors[BarIndex]<>0 then
  begin
    if ParentChart.View3D then
      ParentChart.Canvas.VertLine3D(XPos, OffsetPos, OffsetErrPos, MiddleZ)
    else
      ParentChart.Canvas.DoVertLine(XPos, OffsetPos, OffsetErrPos);
  end;
end;
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

vas
Newbie
Newbie
Posts: 20
Joined: Wed Oct 17, 2007 12:00 am

Re: MultiBar for TCandleSeries

Post by vas » Wed Apr 20, 2011 2:19 pm

This is great, your sample code was very valuable.
I am down to a single issue, my left axis touches the left-most bar.

I am very appreciative of this level of support, including custom programming !

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

Re: MultiBar for TCandleSeries

Post by Yeray » Thu Apr 21, 2011 3:35 pm

Hello Steve,

I'm happy to hear that! :D
vas wrote:I am down to a single issue, my left axis touches the left-most bar.
You could try setting some bottom axis MinimumOffset.
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

vas
Newbie
Newbie
Posts: 20
Joined: Wed Oct 17, 2007 12:00 am

Re: MultiBar for TCandleSeries

Post by vas » Thu Apr 21, 2011 8:40 pm

I tried setting the MinimumOffset, which I really like, but failed.


Here is my feeble coding:

Code: Select all

unit EBar3D;

interface

uses
  Windows, Messages, SysUtils, Classes,
  Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
  Bar3D,TeEngine, TeeProcs, Chart, Series;

type
  TBar3DErrorSeries = class(TBar3DSeries)
  public
    Constructor Create(AOwner: TComponent); override;
    Function AddEBar( Const AX,ABHi,AEHi,AElo,ABLo:Double;
                      Const AXLabel:String='';
                      AColor:TColor=clTeeColor):Integer;
  private
     ErrValHi, ErrValLo: TChartValueList;
  protected
    procedure DrawBar(BarIndex,StartPos,EndPos:Integer); override;
  end;


  TBarChForm = class(TForm)
    Chart1: TChart;
    procedure CreateForm(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var
  BarChForm: TBarChForm;

implementation

{$R *.dfm}

    { TBar3DErrorSeries }

    Constructor TBar3DErrorSeries.Create(AOwner: TComponent);
    begin
      inherited;
      ErrValHi := TChartValueList.Create(Self, 'ErrValHi');
      ErrValLo := TChartValueList.Create(Self, 'ErrValLo');
    end;

    Function TBar3DErrorSeries.AddEBar( Const AX,ABHi,AEHi,AElo,ABLo:Double;
                                        Const AXLabel:String='';
                                        AColor:TColor=clTeeColor):Integer;
    begin
      Marks.Visible:=false;
      XValues.DateTime := true;

      ErrValHi.TempValue := AEHi;
      ErrValLo.TempValue := AELo;
      Result := AddBar( AX, ABHi, ABLo, AXLabel, AColor );
    end;

    procedure TBar3DErrorSeries.DrawBar(BarIndex,StartPos,EndPos:Integer);
    var XPos, BarHiPos, BarLoPos, ErrHiPos, ErrLoPos: Integer;
    begin
      inherited;

      XPos:=CalcXPos(BarIndex) + BarWidth div 2;
      BarHiPos:=CalcYPosValue(YValue[BarIndex]);
      BarLoPos:=CalcYPosValue(OffsetValues[BarIndex]);

      ErrHiPos:=CalcYPosValue(ErrValHi[BarIndex]);
      ErrLoPos:=CalcYPosValue(ErrValLo[BarIndex]);

      if ErrValHi[BarIndex]<>0 then with ParentChart.Canvas do begin
        DoVertLine(XPos-1, BarHiPos, ErrHiPos);
        DoVertLine(XPos,   BarHiPos, ErrHiPos);  // make thicker error bars
        DoVertLine(XPos+1, BarHiPos, ErrHiPos);
        end;

      if ErrValLo[BarIndex]<>0 then with ParentChart.Canvas do begin
        DoVertLine(XPos-1, BarLoPos, ErrLoPos);
        DoVertLine(XPos,   BarLoPos, ErrLoPos);
        DoVertLine(XPos+1, BarLoPos, ErrLoPos);
        end;
    end;



procedure TBarChForm.CreateForm(Sender: TObject);
begin

  with Chart1 do begin
    AddSeries(TBar3DErrorSeries.Create(Chart1));
    AddSeries(TBar3DErrorSeries.Create(Chart1));
    BottomAxis.MinimumOffset := 10;
    BottomAxis.MaximumOffset := 10;

    View3D := false;
    with Series[0] as TBar3DErrorSeries do begin
      AddEBar(30000,20,25,10,15);
      AddEBar(30020,25,30,15,20);
      AddEBar(30040,30,35,20,25);
      AddEBar(30060,35,40,25,30);
      end;

    with Series[1] as TBar3DErrorSeries do begin
      AddEBar(30000,40,50,25,30);
      AddEBar(30020,35,45,20,25);
      AddEBar(30040,30,40,15,20);
      AddEBar(30060,25,35,10,15);
      end;

    ShowModal;
    end;
end;

end.

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

Re: MultiBar for TCandleSeries

Post by Yeray » Fri Apr 22, 2011 8:07 am

Hello Steve,

Here's what I get with your code.
chart.png
chart.png (9.83 KiB) Viewed 20032 times
It seems that the left axis needs some adjustment, more than the bottom. You could calculate the min and max values and set them with the SetMinMax method or, alternatively, you could override the CalcVerticalMargins and CalcHorizontalMargins. Here you have the heathers:

Code: Select all

Procedure CalcVerticalMargins(Var TopMargin,BottomMargin:Integer); override;
Procedure CalcHorizMargins(var LeftMargin,RightMargin:Integer); override;
FYI:
- You may want to change is the Bar series CustomBarWidth to make the bars a little thiner.

- To make the error lines wider you could change the Pen.Width instead of drawing three lines:

Code: Select all

      ParentChart.Canvas.Pen.Width:=3;

      if ErrValHi[BarIndex]<>0 then with ParentChart.Canvas do
        DoVertLine(XPos,   BarHiPos, ErrHiPos);

      if ErrValLo[BarIndex]<>0 then with ParentChart.Canvas do
        DoVertLine(XPos,   BarLoPos, ErrLoPos);
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

vas
Newbie
Newbie
Posts: 20
Joined: Wed Oct 17, 2007 12:00 am

Re: MultiBar for TCandleSeries

Post by vas » Fri Apr 22, 2011 12:48 pm

This service is beyond fantastic.
I implemented your suggestions about CustomBarWidth and PenWidth.

But my chart results differs from yours. I suspect I have an install error in Delphi,
so I am likely linked to an earlier version. I cannot see TeeChart Help either.

In any case, I am close enough.

Thank you very much.

Steve

vas
Newbie
Newbie
Posts: 20
Joined: Wed Oct 17, 2007 12:00 am

Re: MultiBar for TCandleSeries

Post by vas » Fri Apr 22, 2011 7:28 pm

Here are my results.
I am guessing I have an install failure somewhere.
EBarFail.png
EBarFail.png (5.88 KiB) Viewed 20058 times

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

Re: MultiBar for TCandleSeries

Post by Narcís » Tue Apr 26, 2011 10:00 am

Hi Steve,

Thank you very much for your compliments, much appreciated!

Which TeeChart version are you using? Have you tried using the latest version available at the client download area?

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

Post Reply