Create horizonal bar chart with captions

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Ed Dressel
Newbie
Newbie
Posts: 20
Joined: Wed Aug 16, 2023 12:00 am

Create horizonal bar chart with captions

Post by Ed Dressel » Wed Jun 18, 2025 11:03 pm

My graphic designer came up with a horizontal bar chart for my report that I am trying to duplicate--I can get close, but I don't know how to get the captions in the gray bars. You can see it here:
SNGOUT2188.jpg
SNGOUT2188.jpg (58.11 KiB) Viewed 915 times
https://app.screencast.com/8Y1ajzb41nsjr

How can I achieve this?

TIA,

Ed Dressel

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

Re: Create horizonal bar chart with captions

Post by Yeray » Fri Jun 20, 2025 1:56 pm

Hello,

Here a simple example using TeeChart:
HorizBars.png
HorizBars.png (15.55 KiB) Viewed 916 times

Code: Select all

uses Chart, Series, TeEngine, TeeProcs, TeeTools;

var Chart1: TChart;

procedure TForm1.FormCreate(Sender: TObject);
const
  myData: array[0..3] of array[0..3] of double =
    ((2.5, 0.5, 0.5, 0),
     (1.75, 0.5 / 3, 0.5 / 3, (0.5 / 3) + 1.25),
     (1.5, 0.5 / 4, 0.5 / 4, 1.75),
     (1.4, 0.1, 0.1, 1.9));
  myLabels: array[0..3] of array[0..3] of string =
    (('Total payout is from <strong>$2,631,372</strong> to <strong>$3,515,867</strong>', '', '', ''),
     ('<strong>$1,748,067</strong> to $2,065,468', '', '', '<strong>3%</strong> rate of return'),
     ('<strong>$1,550,285</strong> to $1,777,693', '', '', '<strong>4%</strong> rate of return'),
     ('<strong>$1,385,225</strong> to $1,548,800', '', '', '<strong>5%</strong> rate of return'));
  myColors: array[0..3] of TColor = ($805400, $cdaa66, $86cca8, $9b9b9b);
  myTitles: array[0..3] of string = ('95', '100', '105', '');
begin
  FormatSettings.DecimalSeparator:='.';

  Chart1:=TChart.Create(Self);
  Chart1.OnDblClick:=ChartDoubleClick;

  with Chart1 do
  begin
    Parent:=Self;
    Align:=alClient;
    Color:=clWhite;
    Gradient.Visible:=False;
    Walls.Hide;
    View3D:=False;

    Legend.Alignment:=laBottom;
    Legend.Transparent:=True;

    Axes.Left.Title.Text:='Retirement'+sLineBreak+'rates'+sLineBreak+'of return';
    Axes.Left.Title.Angle:=0;
    Axes.Left.Title.TextAlignment:=taRightJustify;
    Axes.Left.Axis.Hide;
    Axes.Left.Ticks.Hide;
    Axes.Left.MinorTicks.Hide;
    Axes.Left.Increment:=1;
    Axes.Left.Inverted:=True;
    Axes.Left.LabelStyle:=talValue;
    Axes.Left.Texts.MarginToAxis:=50;
    Axes.Left.LabelsFont.Size:=9;
    Axes.Left.OnDrawLabel:=LeftAxisDrawLabel;

    Axes.Bottom.Axis.Hide;
    Axes.Bottom.Ticks.Hide;
    Axes.Bottom.MinorTicks.Hide;
    Axes.Bottom.Increment:=0.5;
    Axes.Bottom.Texts.MarginToAxis:=50;
    Axes.Bottom.LabelsFont.Size:=9;
    Axes.Bottom.OnDrawLabel:=BottomAxisDrawLabel;

    for var i:=0 to 3 do
      with THorizBarSeries(AddSeries(THorizBarSeries)) do
      begin
        MultiBar:=mbStacked;
        MarksOnBar:=True;
        MarksLocation:=mlStart;
        Marks.Transparent:=True;
        Marks.Font.Color:=clWhite;
        Marks.TextFormat:=ttfHtml;
        Marks.Style:=smsLabel;
        OnGetMarkText:=SeriesGetMarkText;
        Pen.Hide;
        Color:=myColors[i];
        Title:=myTitles[i];
        BarWidthPercent:=80;

        if i=3 then
          ShowInLegend:=False;

        for var v:=0 to High(myData) do
          AddXY(myData[v][i], v+2, myLabels[v][i], clTeeColor);
      end;

    with TAnnotationTool(Chart1.Tools.Add(TAnnotationTool)) do
    begin
      Shape.Transparent:=True;
      Text:='Life expentancy (years):';
    end;

    Draw;

    with TAnnotationTool(Chart1.Tools[0]) do
    begin
      Left:=Legend.Left - Width - 10;
      Top:=Legend.Top + 2;
    end;
  end;
end;

procedure TForm1.SeriesGetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: string);
var
  LPosition: TSeriesMarkPosition;
  XPos, YPos: Integer;
begin
  inherited;
  LPosition := Sender.Marks.Positions[ValueIndex];
  if LPosition <> nil then
  begin
    LPosition.Custom := true;
    LPosition.LeftTop.Y := Sender.CalcYPos(ValueIndex) + 6;
  end;
end;

procedure TForm1.LeftAxisDrawLabel(Sender:TChartAxis; var X,Y,Z:Integer;
                                   var Text:String; var DrawLabel:Boolean);
begin
  if Text='2' then
  begin
    Text:='';
    Exit;
  end;

  Text:=Text+'%';
end;

procedure TForm1.BottomAxisDrawLabel(Sender:TChartAxis; var X,Y,Z:Integer;
                                     var Text:String; var DrawLabel:Boolean);
begin
  if Text='0.5' then
  begin
    Text:='500K';
    Exit;
  end;

  if Text='0' then
    Exit;

  if Text='3.5' then
    Text:='$'+Text;

  Text:=Text+'M';
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

Post Reply