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 (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;