Page 1 of 2
Stacked bar chart problems
Posted: Wed Feb 10, 2016 8:27 am
by 16566546
I am currently using stacked bar charts to represent lithology down a well. I formerly used the mbSelfStack mode, but this does not allow positioning of the bar chart on the horizontal axis, so now I am using the mbStacked mode. The data source is a memory table, IntervalQuery, which records the Strata Top, Strata Bottom, Rock Type Code and Color of each lithology down the well. I step through IntervalQuery and assign each layer to a new series, as shown in the code below.
However, when I call Chart.RefreshData, I get n x n layers overlying each other (where n is the number of layers). How do I control RefreshData so only one chart layer is drawn for each record of IntervalQuery? I have attached a diagram showing how a nine-layer well (one layer missing) should look (achieved using mbSelfStack) and how it looks using mbStacked.
Thanks in advance
Errol
Code: Select all
procedure AddRockSeries(AXValue,AYValue:double;ALabel:string;AColor:integer);
var
LTitle,LXUnitType,LYUnitType: string;
begin
LTitle := IntToStr(owner.Chart.SeriesList.Count);
if (SeriesListB.IndexOf(LTitle) = -1) then
SeriesListB.AddObject(LTitle,TUnitBarSeries.Create(Owner));
iIndex := SeriesListB.IndexOf(LTitle);
with TBarSeries(SeriesListB.Objects[iIndex]) as TBarSeries do
begin
bMarksVisible := LMarksVisible;
MultiBar := mbStacked;
CustomBarWidth := LBarWidth;
MarksLocation := mlCenter;
MarksOnBar := True;
ShowInLegend := False;
XValues.ValueSource := 'ProfileDistance';
YValues.ValueSource := 'Depth';
XLabelsSource := 'Rock Type Code; // marks!!!
ColorSource := 'Foreground';
VertAxis := aLeftAxis;
HorizAxis := aBottomAxis;
ParentChart := self.Owner.Chart;
DataSource := IntervalQuery;
AddXY(AXValue,AYValue,ALabel,AColor);
end;
end;
Re: Stacked bar chart problems
Posted: Wed Feb 10, 2016 11:58 am
by yeray
Hello,
I see you are adding values to the series manually through the AddXY() function and also assigning a DataSource. I'd choose of the two methods.
Here an example using DataSource simplifying and completing your code without unknown references:
Code: Select all
uses Series;
var myTable: TTable;
procedure TForm1.FormCreate(Sender: TObject);
procedure AddRockSeries;
begin
with DBChart1.AddSeries(TBarSeries) as TBarSeries do
begin
Marks.Visible := true;
MultiBar := mbSelfStack;
CustomBarWidth := 100;
MarksLocation := mlCenter;
MarksOnBar := True;
ShowInLegend := False;
XValues.ValueSource := 'ProfileDistance';
YValues.ValueSource := 'Depth';
XLabelsSource := 'Rock Type Code'; // marks!!!
ColorSource := 'Foreground';
VertAxis := aLeftAxis;
HorizAxis := aBottomAxis;
DataSource := myTable;
//AddXY(AXValue,AYValue,ALabel,AColor);
end;
end;
var i: Integer;
begin
myTable:=TTable.Create(Self);
with myTable do
begin
FieldDefs.Add('ProfileDistance', ftInteger);
FieldDefs.Add('Depth', ftFloat);
FieldDefs.Add('Rock Type Code', ftInteger);
FieldDefs.Add('Foreground', ftInteger);
TableName:='MyValues';
CreateTable;
EmptyTable;
Open;
for i:=0 to 5 do
begin
Append;
FieldByName('ProfileDistance').AsFloat:=0;
FieldByName('Depth').AsFloat:=5+random*5;
FieldByName('Rock Type Code').AsInteger:=Round(random*50);
FieldByName('Foreground').AsInteger:=RGB(Round(random*255), Round(random*255), Round(random*255));
Post;
end;
Close;
end;
DBChart1.View3D:=false;
myTable.Open;
AddRockSeries;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DBChart1.RefreshData;
end;
Re: Stacked bar chart problems
Posted: Thu Feb 11, 2016 2:21 am
by 16566546
Good afternoon Yeray
I am unable to reproduce a stacked bar chart using the code you have suggested. I have attached the actual code I have used. As TTable seemed to be always interpreted as a paradox table with some network error, I have used a TkbmMemTable memory table.
I need to use the mbStacked mode to be able to specify the horizontal position of the bar, but your example used the SelfStack mode. However, I have tried both options, but nothing is displayed when I click on Button1. Have you any ideas why this does not work.
Best regards
Errol
Code: Select all
unit StackChart;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, TeeGDIPlus, ExtCtrls, TeeProcs, TeEngine, Chart, StdCtrls, DB,
Series, DBChart, kbmMemTable;
type
TForm1 = class(TForm)
Button1: TButton;
DBChart1: TDBChart;
procedure Button1Click(Sender: TObject);
procedure Form1Create(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
myTable: TkbmMemTable;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
DBChart1.RefreshData;
end;
procedure TForm1.Form1Create(Sender: TObject);
procedure AddRockSeries;
begin
with DBChart1.AddSeries(TBarSeries) as TBarSeries do
begin
Marks.Visible := true;
// MultiBar := mbSelfStack;
MultiBar := mbStacked;
CustomBarWidth := 100;
MarksLocation := mlCenter;
MarksOnBar := True;
ShowInLegend := False;
XValues.ValueSource := 'ProfileDistance';
YValues.ValueSource := 'Depth';
XLabelsSource := 'Rock Type Code'; // marks!!!
ColorSource := 'Foreground';
VertAxis := aLeftAxis;
HorizAxis := aBottomAxis;
DataSource := myTable;
//AddXY(AXValue,AYValue,ALabel,AColor);
end;
end;
var
i: Integer;
begin
myTable:=TkbmMemTable.Create(Self);
with myTable do
begin
FieldDefs.Add('ProfileDistance', ftInteger);
FieldDefs.Add('Depth', ftFloat);
FieldDefs.Add('Rock Type Code', ftInteger);
FieldDefs.Add('Foreground', ftInteger);
CreateTable;
EmptyTable;
Open;
for i:=0 to 5 do
begin
Append;
FieldByName('ProfileDistance').AsFloat:=0;
FieldByName('Depth').AsFloat:=5+random*5;
FieldByName('Rock Type Code').AsInteger:=Round(random*50);
FieldByName('Foreground').AsInteger:=RGB(Round(random*255), Round(random*255), Round(random*255));
Post;
end;
Close;
end;
DBChart1.View3D:=false;
myTable.Open;
AddRockSeries;
end;
end.
Re: Stacked bar chart problems
Posted: Thu Feb 11, 2016 2:36 pm
by yeray
Hello Errol,
Errol wrote:I need to use the mbStacked mode to be able to specify the horizontal position of the bar, but your example used the SelfStack mode.
I understand you only want a single column with stacked values, is this correct?
- mbStacked mode stacks values from different Bar series with the same XValue. To have a single column you'd need to have x Bar series with a single value. Assigning a table as a series datasource loads all the values from the table to that series. So to have a single stacked column you'd need to have x tables with a single row.
- mbSelfStack mode stacks all the values from a Bar series. If the only problem is with the position of the stacked column, maybe you could try to play with the bottom axis scale. What about this?
Code: Select all
DBChart1.Axes.Bottom.SetMinMax(-0.5, 1);
Re: Stacked bar chart problems
Posted: Thu Feb 11, 2016 8:24 pm
by 16566546
Hello Yeray
Thanks for your reply. I wish to develop a graph with many stacked bars at specified horizontal positions, corresponding to the position of wells along a profile line. At present, this is possible only by using mbStacked. I find the TeeChart code difficult to understand, but I suspected that I would have to create a separate table containing a single row for each layer of each stacked bar, a fairly tedious process.
I do not understand why the mbSelfStack option was developed without allowing the bars to be positioned on the horizontal axis, which is available with mbStacked. This functionality has been requested for some time now, and I am deeply disappointed that this is not yet available. Self stacking is the logical way to handle stacked bar charts for many data streams, and it should have full functionality.
Thanks and regards
Errol
Re: Stacked bar chart problems
Posted: Fri Feb 12, 2016 11:59 am
by yeray
Hello Errol,
Errol wrote:I do not understand why the mbSelfStack option was developed without allowing the bars to be positioned on the horizontal axis, which is available with mbStacked.
As the other series, the TBarSeries has XValues and YValues. In mbSelfStack, the YValues are stacked in the same column and the XValues are ignored. The SeriesIndex is used to set the position of the series in the horizontal axis. See the MinXValue function:
Code: Select all
Function TBarSeries.MinXValue:Double;
Begin
if MultiBar=mbSelfStack then
result:=SeriesIndex
else
result:=inherited MinXValue;
end;
You could use a custom series inheriting from TBarSeries to make it use the first XValue in the series as the position in the horizontal axis. Ie:
Code: Select all
type TMyBarSeries = class(TBarSeries)
public
Function MinXValue:Double; override;
end;
Function TMyBarSeries.MinXValue:Double;
Begin
result:=XValues[0];
end;
Errol wrote:This functionality has been requested for some time now, and I am deeply disappointed that this is not yet available. Self stacking is the logical way to handle stacked bar charts for many data streams, and it should have full functionality.
Can you point us to where it was requested? It could be a feature request.
Re: Stacked bar chart problems
Posted: Sat Feb 13, 2016 12:15 am
by 16566546
Hello Yeray
Thank you for your suggestions regarding developing a custom series to set the position of a self stacked bar chart on the horizontal axis. I have previously attempted to develop a custom series without success, but your suggestions may help, so I will continue with this.
The request for controlling the x-position of a (vertical) self-stacked bar is Bug 646, made on 19-Mar-2014. My name is not associated with it, as the request was made in response to an email conversation.
Thanks and regards
Errol
Re: Stacked bar chart problems
Posted: Mon Feb 15, 2016 2:16 pm
by yeray
Hello Errol,
I've added a project with the mentioned bug-fix attempt in the public tracker:
http://bugs.teechart.net/show_bug.cgi?id=646
Note you can add your mail to the CC list to be automatically notified when an update arrives.
Re: Stacked bar chart problems
Posted: Thu Feb 18, 2016 6:18 am
by 16566546
Thank you Yeray for your suggestions. Using MinXValue worked a treat, as you can see in the attached image. However, I have a few small problems that I am still having problems with.
Problem 1. Numeric labels on the x-axis
I am using the following code snippet, but this does not put labels on the axis (although does write the correct title)
Code: Select all
DataSource := IntervalQuery; // after parent chart
XLabelDisplay := ldField
YLabelDisplay := ldField;
MultiBar := mbSelfStack;
CustomHorizAxis := tmpHorizAxis;
CustomHorizAxis.Labels := True;
if SameText(LIndepField,'Elevation') then
YPosition := LWellElev
else
YPosition := 0;
XValues.ValueSource := 'Cross-Section Distance';
YValues.ValueSource := self.Owner.IndependentField;
XLabelsSource := aFldCode; // marks!!!
ColorSource := 'Foreground';
VertAxis := aLeftAxis;
Problem 2. Auto-Scale on the y-Axis
When I plot data against elevation, it does not auto-scale from the highest well elevation to the deepest well elevation, but starts at the highest base of the first bar segment from the top. The code uses YPosition, set to the elevation of each well, and an override version of PointOrigin
Code: Select all
function PointOrigin(ValueIndex: Integer; SumAll: Boolean): Double; override;
function TUnitBarSeries.PointOrigin(ValueIndex: Integer;
SumAll: Boolean): Double;
begin
Result := inherited PointOrigin(ValueIndex, SumAll);
if not SumAll then
Result := Result + YPosition;
end;
Can you suggest a fix to this problem?
Problem 3 Titles for each bar
I would like to write the well name above each well, or perhaps above the top axis or below the bottom axis. D oyou have any ideas on how to do this?
Thanks and regards
Errol
Re: Stacked bar chart problems
Posted: Thu Feb 18, 2016 9:33 am
by yeray
Errol wrote:Problem 1. Numeric labels on the x-axis
I am using the following code snippet, but this does not put labels on the axis (although does write the correct title)
Could you please modify the example
here or arrange a simple example project we can run as-is to reproduce the problem here?
Thanks in advance.
Errol wrote:Problem 2. Auto-Scale on the y-Axis
When I plot data against elevation, it does not auto-scale from the highest well elevation to the deepest well elevation, but starts at the highest base of the first bar segment from the top. The code uses YPosition, set to the elevation of each well, and an override version of PointOrigin
[...]
Can you suggest a fix to this problem?
I don't see what YPosition exactly is in that code.
A simple example would help us to focus on the issue.
Errol wrote:Problem 3 Titles for each bar
I would like to write the well name above each well, or perhaps above the top axis or below the bottom axis. D oyou have any ideas on how to do this?
You may want to try to use TAnnotationTools to do this.
Re: Stacked bar chart problems
Posted: Fri Feb 19, 2016 4:57 am
by 16566546
Here is some test code to illustrate the problems I am experiencing. This is written using a memory table (kbmmemtable) as I have problems using TTable. This shows that the horizontal axis labels are the first mark for each chart, not numerical values of ProfileDistance. Also the automatic scale on the vertical axis always starts at the second stratum with the highest elevation.
I look forward to your suggestions.
Thanks and regards
Errol
Code: Select all
unit StackChart;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, TeeGDIPlus, ExtCtrls, TeeProcs, TeEngine, Chart, StdCtrls, DB,
Series, DBChart, kbmMemTable, teetools;
type
TForm1 = class;
TForm1 = class(TForm)
Button1: TButton;
DBChart1: TDBChart;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Form1Create(Sender: TObject);
procedure RegenerateChart(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TMyBarSeries = class(TBarSeries)
private
fYPosition: double;
procedure SetYPosition(const Value: Double);
public
property YPosition: Double read fYPosition write SetYPosition;
function MinXValue:Double; override;
function PointOrigin(ValueIndex: Integer; SumAll: Boolean): Double; override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Form1Create(Sender: TObject);
var
i,j,iRTC: Integer;
RTC, LTitle: string;
R,G,B,iIndex: integer;
DragTool: TDragMarksTool;
LProfDist,LWellElev: double;
MyTable: TkbmMemTable;
SeriesListB: TStringList;
procedure AddRockSeries;
begin
LTitle := IntToStr(j);
if (SeriesListB.IndexOf(LTitle) = -1) then
SeriesListB.AddObject(LTitle,TMyBarSeries.Create(Owner));
iIndex := SeriesListB.IndexOf(LTitle);
// with DBChart1.AddSeries(TMyBarSeries) as TBarSeries do
with TMyBarSeries(SeriesListB.Objects[iIndex]) do
begin
Marks.Visible := true;
MultiBar := mbSelfStack;
CustomBarWidth := 60;
MarksLocation := mlCenter;
MarksOnBar := True;
ShowInLegend := False;
ParentChart := DBChart1;
DataSource := myTable;
YPosition := LWellElev;
XValues.ValueSource := 'ProfileDistance';
YValues.ValueSource := 'Depth';
XLabelsSource := 'Rock Type Code'; // marks!!!
ColorSource := 'Foreground';
VertAxis := aLeftAxis;
HorizAxis := aBottomAxis;
end;
end;
begin
DBChart1.ClearChart;
DragTool := DBChart1.Tools.Add(TDragMarksTool) as TDragMarksTool;
DragTool.Active := true;
DBChart1.View3D:=false;
DBChart1.LeftAxis.Inverted := False;
DBChart1.BottomAxis.Title.Caption := 'Profile Distance';
DBChart1.LeftAxis.Title.Caption := 'Elevation';
SeriesListB := TStringList.Create;
for j := 1 to 3 do
begin
myTable := TkbmMemTable.Create(Owner);
with myTable do
begin
FieldDefs.Add('ProfileDistance', ftInteger,0,false);
FieldDefs.Add('Depth', ftFloat,0,false);
FieldDefs.Add('Rock Type Code', ftString,10,false);
FieldDefs.Add('Foreground', ftInteger,0,false);
CreateTable;
EmptyTable;
Open;
LProfDist := random*5000;
LWellElev := random*500;
for i:=0 to 5 do
begin
Append;
FieldByName('ProfileDistance').AsFloat:=LProfDist;
FieldByName('Depth').AsFloat:= -(100+random*100); // negative
case i of
0: RTC := IntToStr(j)+'-'+'BAS';
1: RTC := IntToStr(j)+'-'+'PYR';
2: RTC := IntToStr(j)+'-'+'NO';
3: RTC := IntToStr(j)+'-'+'TUF';
4: RTC := IntToStr(j)+'-'+'PYR';
5: RTC := IntToStr(j)+'-'+'MD';
end;
FieldByName('Rock Type Code').AsString := RTC;
R := Round(random*255);
G := Round(random*255);
B := Round(random*255);
FieldByName('Foreground').AsInteger:=RGB(R,G,B);
Post;
end;
AddRockSeries;
end;
end;
end;
procedure TForm1.RegenerateChart(Sender: TObject);
begin
Form1Create(owner);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DBChart1.RefreshData;
end;
Function TMyBarSeries.MinXValue:Double;
Begin
result:=XValues[0];
end;
procedure TMyBarSeries.SetYPosition(const Value: Double);
begin
if FYPosition <> Value then
begin
FYPosition := Value;
Repaint;
end;
end;
function TMyBarSeries.PointOrigin(ValueIndex: Integer;
SumAll: Boolean): Double;
begin
Result := inherited PointOrigin(ValueIndex, SumAll);
if not SumAll then
Result := Result + YPosition;
end;
end.
Re: Stacked bar chart problems
Posted: Fri Feb 19, 2016 9:00 am
by yeray
Hello Errol,
Errol wrote:Here is some test code to illustrate the problems I am experiencing. This is written using a memory table (kbmmemtable) as I have problems using TTable.
Thanks. I don't have kbmmemtable but I can switch that for a TTable and it works without problems for me here. This is what I get:
- first.png (19.42 KiB) Viewed 25295 times
Errol wrote: This shows that the horizontal axis labels are the first mark for each chart, not numerical values of ProfileDistance.
Adding this I think makes it to behave as you wish:
Code: Select all
DBChart1.Axes.Bottom.LabelStyle:=talPointValue;
- PointValue.png (19.06 KiB) Viewed 25297 times
Errol wrote: Also the automatic scale on the vertical axis always starts at the second stratum with the highest elevation.
You could override the MaxYValue function also to get it right:
Code: Select all
function TMyBarSeries.MaxYValue:Double;
Begin
result:=YPosition;
end;
- MaxYValue.png (19.14 KiB) Viewed 25300 times
Re: Stacked bar chart problems
Posted: Sun Feb 21, 2016 2:47 am
by 16566546
Good afternoon Yeray
Thank you for the MaxYValue suggestion to correct the autoscale. However, for the labels on the x-axis, I prefer a normal axis label format (e.g. every 200 from say 1800 to 4000, rather than labelling the position of each bar chart. Is this possible?
I am also having some problems with the annotation tools to write the well name above each bar chart. I was hoping for series-dependent annotation. I seems quite difficult to write using a chart property, especially keeping the labels aligned when zooming or scrolling. Can you point me to code examples that deal with this.
Thanks and regards
Errol
Re: Stacked bar chart problems
Posted: Mon Feb 22, 2016 4:03 am
by 16566546
Hello Yeray
Nearly there. I have annotations working but they do not appear until I either mouse over a chart or press Refresh. How do I get these to draw automatically. Also, can I remove the box around the text and just show the name, with no background.
The annotations are also lined up to the left of the bar chart, not the centre. Is there any easy way to automatically centre these?
I have introduced a ToolCount parameter, as I will have other tools on the chart.
Looking forward to your comments
Errol
Code: Select all
unit StackChart;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, TeeGDIPlus, ExtCtrls, TeeProcs, TeEngine, Chart, StdCtrls, DB,
Series, DBChart, kbmMemTable, teetools,contnrs;
type
TForm1 = class;
TForm1 = class(TForm)
Button1: TButton;
DBChart1: TDBChart;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Form1Create(Sender: TObject);
procedure RegenerateChart(Sender: TObject);
procedure DBChart1AfterDraw(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TMyBarSeries = class(TBarSeries)
private
fYPosition: double;
procedure SetYPosition(const Value: Double);
public
property YPosition: Double read fYPosition write SetYPosition;
function MinXValue:Double; override;
function PointOrigin(ValueIndex: Integer; SumAll: Boolean): Double; override;
function MaxYValue:Double; override;
end;
var
Form1: TForm1;
SeriesListB: TStringList;
WellElev,ProfDist: double;
WellName: string;
MyTable: TkbmMemTable;
implementation
{$R *.dfm}
procedure TForm1.DBChart1AfterDraw(Sender: TObject);
var
j: integer;
begin
for j := 0 to 2 do
with (DBChart1.Tools[j] as TAnnotationTool) do
begin
case j of
0: WellName := 'AT-103';
1: WellName := 'AT-201';
2: WellName := 'AT-604';
end;
Shape.CustomPosition := True;
Text := WellName;
Left := TMyBarSeries(SeriesListB.Objects[j]).CalcXPos(0);
end;
end;
procedure TForm1.Form1Create(Sender: TObject);
var
i,j,iRTC: Integer;
RTC, LTitle: string;
R,G,B,iIndex: integer;
DragTool: TDragMarksTool;
LTemp1,LTemp2: integer;
procedure AddRockSeries;
begin
LTitle := IntToStr(j);
if (SeriesListB.IndexOf(LTitle) = -1) then
SeriesListB.AddObject(LTitle,TMyBarSeries.Create(Owner));
iIndex := SeriesListB.IndexOf(LTitle);
// with DBChart1.AddSeries(TMyBarSeries) as TBarSeries do
with TMyBarSeries(SeriesListB.Objects[iIndex]) do
begin
Marks.Visible := true;
MultiBar := mbSelfStack;
CustomBarWidth := 60;
MarksLocation := mlCenter;
MarksOnBar := True;
Marks.Clip := True;
ShowInLegend := False;
ParentChart := DBChart1;
DataSource := myTable;
YPosition := WellElev;
XValues.ValueSource := 'ProfileDistance';
YValues.ValueSource := 'Depth';
XLabelsSource := 'Rock Type Code'; // marks!!!
ColorSource := 'Foreground';
VertAxis := aLeftAxis;
HorizAxis := aBottomAxis;
end;
end;
begin
DBChart1.ClearChart;
DBChart1.Tools.Clear;
DBChart1.View3D:=false;
DBChart1.LeftAxis.Inverted := False;
DBChart1.BottomAxis.Title.Caption := 'Profile Distance';
DBChart1.LeftAxis.Title.Caption := 'Elevation';
DBChart1.Axes.Bottom.LabelStyle:=talPointValue;
SeriesListB := TStringList.Create;
for j := 0 to 2 do
begin
case j of
0: WellName := 'AT-103';
1: WellName := 'AT-201';
2: WellName := 'AT-604';
end;
myTable := TkbmMemTable.Create(Owner);
with myTable do
begin
FieldDefs.Add('ProfileDistance', ftInteger,0,false);
FieldDefs.Add('Depth', ftFloat,0,false);
FieldDefs.Add('Rock Type Code', ftString,10,false);
FieldDefs.Add('Foreground', ftInteger,0,false);
CreateTable;
EmptyTable;
Open;
ProfDist := random*5000;
WellElev := (random*500);
for i:=0 to 5 do
begin
Append;
FieldByName('ProfileDistance').AsFloat:=ProfDist;
FieldByName('Depth').AsFloat:= -(150+random*150); // negative
case i of
0: RTC := IntToStr(j)+'-'+'BAS';
1: RTC := IntToStr(j)+'-'+'PYR';
2: RTC := IntToStr(j)+'-'+'NO';
3: RTC := IntToStr(j)+'-'+'TUF';
4: RTC := IntToStr(j)+'-'+'PYR';
5: RTC := IntToStr(j)+'-'+'MD';
end;
FieldByName('Rock Type Code').AsString := RTC;
R := Round(random*255);
G := Round(random*255);
B := Round(random*255);
FieldByName('Foreground').AsInteger:=RGB(R,G,B);
Post;
end;
AddRockSeries;
end;
DBChart1.Tools.Add(TAnnotationTool.Create(self));
with (DBChart1.Tools[j] as TAnnotationTool) do
begin
Shape.CustomPosition := True;
PositionUnits := muPixels;
Left := TMyBarSeries(SeriesListB.Objects[j]).CalcXPos(0);
end;
end;
DragTool := DBChart1.Tools.Add(TDragMarksTool) as TDragMarksTool;
DragTool.Active := true;
end;
procedure TForm1.RegenerateChart(Sender: TObject);
begin
Form1Create(owner);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DBChart1.RefreshData;
end;
Function TMyBarSeries.MinXValue:Double;
Begin
result:=XValues[0];
end;
procedure TMyBarSeries.SetYPosition(const Value: Double);
begin
if FYPosition <> Value then
begin
FYPosition := Value;
Repaint;
end;
end;
function TMyBarSeries.PointOrigin(ValueIndex: Integer;
SumAll: Boolean): Double;
begin
Result := inherited PointOrigin(ValueIndex, SumAll);
if not SumAll then
Result := Result + YPosition;
end;
function TMyBarSeries.MaxYValue:Double;
var
LMaxY: double;
Begin
result:=YPosition + 20;
end;
end.
Re: Stacked bar chart problems
Posted: Mon Feb 22, 2016 10:21 am
by yeray
Hello,
Regarding the bottom axis labels, try changing the bottom axis LabelStyle from talPointValue to talValue. Ie:
Code: Select all
DBChart1.Axes.Bottom.LabelStyle:=talValue;
Regarding the annotations, try forcing a chart repaint at the end of your OnCreate. Ie: