Page 1 of 1

Values on top of Stacked Bar Columns

Posted: Wed Nov 16, 2022 6:52 am
by 16590249
Hi,

1.
Is there a way to show on graph the total sum on top of every stacked bar column?

2.
Is there a way to format the text values on the X AXis?
My SQL Query shows the X Values on graph like "202205" (YearMonth)
& I would like to show the X Values on graph like "05-2022". (Month-Year)

Thank you in advance
Vasilis

Re: Values on top of Stacked Bar Columns

Posted: Wed Nov 16, 2022 10:17 am
by yeray
Hello Vasilis,
vasilis wrote:
Wed Nov 16, 2022 6:52 am
Is there a way to show on graph the total sum on top of every stacked bar column?
You could use OnGetMarkText event as follows:

Code: Select all

uses Series;

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

  Chart1.View3D:=False;
  Chart1.Legend.Hide;

  Chart1.Color:=clWhite;
  Chart1.Gradient.Visible:=False;
  Chart1.Walls.Back.Color:=clWhite;
  Chart1.Walls.Back.Gradient.Visible:=False;

  for i:=0 to 1 do
    with TBarSeries(Chart1.AddSeries(TBarSeries)) do
    begin
      MultiBar:=mbStacked;
      FillSampleValues;
    end;

  Chart1[0].Marks.Hide;
  Chart1[1].OnGetMarkText:=SeriesGetMarkText;
end;

procedure TForm1.SeriesGetMarkText(Sender:TChartSeries; ValueIndex:Integer; var MarkText:string);
var i: Integer;
    t: Double;
begin
  if ValueIndex<>-1 then
  begin
    t:=0;
    for i:=0 to Chart1.SeriesCount-1 do
      if (Chart1[i] is TBarSeries) and (TBarSeries(Chart1[i]).MultiBar=mbStacked) and (ValueIndex<Chart1[i].Count) then
        t:=t+Chart1[i].YValue[ValueIndex];

    MarkText:=FormatFloat(Sender.ValueFormat, t);
  end;
end;
vasilis wrote:
Wed Nov 16, 2022 6:52 am
Is there a way to format the text values on the X AXis?
My SQL Query shows the X Values on graph like "202205" (YearMonth)
& I would like to show the X Values on graph like "05-2022". (Month-Year)
There are several options here. If your sql query returns a string, you can convert it to a TDateTime and use it as XValues in the series. Of course this will make the bars to be drawn in irregular spaces if the datetimes are not regular:
Project1_2022-11-16_11-13-41.png
Project1_2022-11-16_11-13-41.png (14.66 KiB) Viewed 5349 times

Code: Select all

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var i, j: Integer;
const s: array of string=['202205', '202206', '202207', '202208', '202209'];
var x: TDateTime;
begin
  Chart1.Align:=alClient;

  Chart1.View3D:=False;
  Chart1.Legend.Hide;

  Chart1.Color:=clWhite;
  Chart1.Gradient.Visible:=False;
  Chart1.Walls.Back.Color:=clWhite;
  Chart1.Walls.Back.Gradient.Visible:=False;

  for i:=0 to 1 do
    with TBarSeries(Chart1.AddSeries(TBarSeries)) do
    begin
      MultiBar:=mbStacked;

      Xvalues.DateTime:=True;
      for j:=0 to Length(s)-1 do
      begin
        x:=StrToDate('01/'+Copy(s[j],5,2)+'/'+Copy(s[j],1,4));
        AddXY(x, 50+random*10);
      end;
    end;

  Chart1.Axes.Bottom.LabelStyle:=talPointValue;
  Chart1.Axes.Bottom.DateTimeFormat:='mm-yyyy';
  Chart1[0].Marks.Hide;
  Chart1[1].OnGetMarkText:=SeriesGetMarkText;
end;

procedure TForm1.SeriesGetMarkText(Sender:TChartSeries; ValueIndex:Integer; var MarkText:string);
var i: Integer;
    t: Double;
begin
  if ValueIndex<>-1 then
  begin
    t:=0;
    for i:=0 to Chart1.SeriesCount-1 do
      if (Chart1[i] is TBarSeries) and (TBarSeries(Chart1[i]).MultiBar=mbStacked) and (ValueIndex<Chart1[i].Count) then
        t:=t+Chart1[i].YValue[ValueIndex];

    MarkText:=FormatFloat(Sender.ValueFormat, t);
  end;
end;
Another option is to add that string as series labels. This way you can convert your string from a format to the other before adding the points to the series. Then, the XValues will be regular (0, 1, 2,...).

Code: Select all

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var i, j: Integer;
const s: array of string=['202205', '202206', '202207', '202208', '202209'];
var x: TDateTime;
begin
  Chart1.Align:=alClient;

  Chart1.View3D:=False;
  Chart1.Legend.Hide;

  Chart1.Color:=clWhite;
  Chart1.Gradient.Visible:=False;
  Chart1.Walls.Back.Color:=clWhite;
  Chart1.Walls.Back.Gradient.Visible:=False;

  for i:=0 to 1 do
    with TBarSeries(Chart1.AddSeries(TBarSeries)) do
    begin
      MultiBar:=mbStacked;

      for j:=0 to Length(s)-1 do
        Add(50+random*10, Copy(s[j],5,2)+'-'+Copy(s[j],1,4));
    end;

  Chart1[0].Marks.Hide;
  Chart1[1].OnGetMarkText:=SeriesGetMarkText;
end;

procedure TForm1.SeriesGetMarkText(Sender:TChartSeries; ValueIndex:Integer; var MarkText:string);
var i: Integer;
    t: Double;
begin
  if ValueIndex<>-1 then
  begin
    t:=0;
    for i:=0 to Chart1.SeriesCount-1 do
      if (Chart1[i] is TBarSeries) and (TBarSeries(Chart1[i]).MultiBar=mbStacked) and (ValueIndex<Chart1[i].Count) then
        t:=t+Chart1[i].YValue[ValueIndex];

    MarkText:=FormatFloat(Sender.ValueFormat, t);
  end;
end;