- Lithology_Chart_Labels.png (12.22 KiB) Viewed 20742 times
Stacked Bar Chart and Marks
Stacked Bar Chart and Marks
I am using a Stacked Bar Chart to represent a lithology column from a well. As an alternative to drawing a legend, I want to be able to put labels directly on the bar chart. However, they always draw in the next lithology, and there does not appear to be a command akin to Marks | Arrows | Distance in the Chart Editor that I could set to a negative value and shift the labels to the centre of the strata. As a result, the labels end up as in the attachment. Any suggestions welcomed.
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Re: Stacked Bar Chart and Marks
Hi Errol,
Yes, you can do this:
However, there's new MarksOnBar property to achieve what you request:
Yes, you can do this:
Code: Select all
Series1.Marks.ArrowLength:=-20;
Code: Select all
Series1.MarksOnBar:=True;
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Re: Stacked Bar Chart and Marks
Narcis
Thanks for your reply. I agree that Marks.ArrowLength can be set to a negative value (I had a code error before) but I am still unable to individually position each mark. The marks offset is always the same and in pixels so that when I zoom the label is no longer in the centre of the bar. The MarksOnBar command worked but put the marks just below each bar rather than in the centre of the bar. The code I use is shown below (Depth is the vertical length of each bar in the stack), and the results are in the attachment.
Clearly I am doing something wrong - what might it be?
Thanks for your reply. I agree that Marks.ArrowLength can be set to a negative value (I had a code error before) but I am still unable to individually position each mark. The marks offset is always the same and in pixels so that when I zoom the label is no longer in the centre of the bar. The MarksOnBar command worked but put the marks just below each bar rather than in the centre of the bar. The code I use is shown below (Depth is the vertical length of each bar in the stack), and the results are in the attachment.
Clearly I am doing something wrong - what might it be?
Code: Select all
procedure TUnitBarSeries.DrawBar(BarIndex, StartPos, EndPos: Integer);
begin
// go to dataset record for this index
TkbmMemTable(self.DataSource).RecNo := BarIndex + 1;
Brush.Style :=
TBrushStyle(TkbmMemTable(self.DataSource).FieldByName('Pattern').asInteger);
Brush.Color :=
TColor(TkbmMemTable(self.DataSource).FieldByName('Background').asInteger);
Marks.Visible := True;
Marks.ArrowLength :=
-(TkbmMemTable(self.DataSource).FieldByName('Depth').asInteger) div 2;
ShowInLegend := False;
inherited DrawBar(BarIndex,StartPos,EndPos);
end;
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Re: Stacked Bar Chart and Marks
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Re: Stacked Bar Chart and Marks
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Stacked Bar Chart and Marks
Hi Yeray and Narcis
I am pleased to report that the following code places the marks in the center of each bar, and they remain in place when the chart is zoomed.
Many thanks
Errol
I am pleased to report that the following code places the marks in the center of each bar, and they remain in place when the chart is zoomed.
Many thanks
Errol
Code: Select all
procedure TQSCollection.InsertGeologicalSeries(aCodeFld,aFld:string);
begin
// code here to load data from dataset into kbmMemTable and calculate depth increments
SeriesListB.AddObject(sTitle, TUnitBarSeries.Create(Owner));
iIndex := SeriesListB.IndexOf(sTitle);
with TUnitBarSeries(SeriesListB.Objects[iIndex]) do
begin
AutoMarkPosition := false;
MultiBar := mbSelfStack;
CustomBarWidth := 80;
Marks.Visible := True;
MarksLocation := mlCenter;
MarksOnBar := True;
// additional code here
end;
end;
Re: Stacked Bar Chart and Marks
I am able to place marks in the center of each bar on my stacked bar chart as required, and they stay in the correct place when I pan or zoom the chart. However, if I first drag one of the marks, this appears to lock the marks in the chart (see attachments). The only way to reset is to select another data set. How can I reset the marks to auto as I pan or zoom? I use an OnAfterDraw event to allow marks dragging (see code snippet).
Code: Select all
procedure TQSCollection.ChartAfterDraw(Sender: TObject);
var
DragTool: TDragMarksTool;
begin
self.Owner.Chart.Tools.Add(TDragMarksTool);
DragTool.Active := true;
end;
Re: Stacked Bar Chart and Marks
Hi Errol,
http://www.teechart.net/support/viewtop ... 033#p34033
Even more, you are defining a variable (DragTool) and not initializing it. I guess the program doesn't crash because the compiler probably detects setting DragTool.Active:=true has little sense and skips it.
Sounds better to me like this:
Take a look at the answer here:Errol wrote:I am able to place marks in the center of each bar on my stacked bar chart as required, and they stay in the correct place when I pan or zoom the chart. However, if I first drag one of the marks, this appears to lock the marks in the chart (see attachments). The only way to reset is to select another data set. How can I reset the marks to auto as I pan or zoom?
http://www.teechart.net/support/viewtop ... 033#p34033
Is this code working for you? Note the AfterDraw event is fired every time the chart is redrawn. This could be many times if you allow scroll or zoom. In that case, you could be creating more and more TDragMarksTool objects and adding to the chart list of tools. I'd strongly suggest you to move that code to the Form.Create or similar.Errol wrote:I use an OnAfterDraw event to allow marks dragging (see code snippet).
Code: Select all
procedure TQSCollection.ChartAfterDraw(Sender: TObject); var DragTool: TDragMarksTool; begin self.Owner.Chart.Tools.Add(TDragMarksTool); DragTool.Active := true; end;
Even more, you are defining a variable (DragTool) and not initializing it. I guess the program doesn't crash because the compiler probably detects setting DragTool.Active:=true has little sense and skips it.
Sounds better to me like this:
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
var
DragTool: TDragMarksTool;
begin
Chart1.AddSeries(TBarSeries).FillSampleValues();
DragTool:=Chart1.Tools.Add(TDragMarksTool) as TDragMarksTool;
DragTool.Active := true;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Stacked Bar Chart and Marks
Yeray
Thanks for the suggestion regarding the OnAfterDraw event. I inherited this code and hadn't really thought about it, but zooming and panning now works much better since I adopted your suggestions.
I have overcome the "sticky" marks by simply calling Chart.RefreshData on Zoom, UndoZoom and Scroll. However, it would be nice to do this only if a mark has been dragged. Is there a Marks.HasBeenDragged boolean that I can interrogate to see if I need to refresh the chart?
Thanks and regards
Errol
Thanks for the suggestion regarding the OnAfterDraw event. I inherited this code and hadn't really thought about it, but zooming and panning now works much better since I adopted your suggestions.
I have overcome the "sticky" marks by simply calling Chart.RefreshData on Zoom, UndoZoom and Scroll. However, it would be nice to do this only if a mark has been dragged. Is there a Marks.HasBeenDragged boolean that I can interrogate to see if I need to refresh the chart?
Thanks and regards
Errol
Re: Stacked Bar Chart and Marks
Hi Errol,
You're welcome!Errol wrote:Thanks for the suggestion regarding the OnAfterDraw event. I inherited this code and hadn't really thought about it, but zooming and panning now works much better since I adopted your suggestions.
No but you can create you own boolean, initialize it at OnCreate and change it at with the TDragMarksTool OnDraggedMark event. Ie:Errol wrote:I have overcome the "sticky" marks by simply calling Chart.RefreshData on Zoom, UndoZoom and Scroll. However, it would be nice to do this only if a mark has been dragged. Is there a Marks.HasBeenDragged boolean that I can interrogate to see if I need to refresh the chart?
Code: Select all
var HasBeenDragged: Boolean;
procedure TForm1.FormCreate(Sender: TObject);
begin
Chart1.Legend.Visible:=false;
Chart1.View3D:=false;
Chart1.AddSeries(TBarSeries).FillSampleValues;
HasBeenDragged:=false;
(Chart1.Tools.Add(TDragMarksTool) as TDragMarksTool).OnDraggedMark:=DraggedMark;
end;
procedure TForm1.DraggedMark(Sender:TDragMarksTool; Index:Integer; Button:TMouseButton; Shift: TShiftState; X,Y: Integer);
begin
HasBeenDragged:=true;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Stacked Bar Chart and Marks
Good afternoon Yeray
Is there any way to left justify and offset marks on a (vertical) stacked bar chart. Properties such as MarksLocation and Marks.TextAlignment seem to control placement in the vertical direction, but I would like to control in the horizontal direction.
Regards
Errol
Is there any way to left justify and offset marks on a (vertical) stacked bar chart. Properties such as MarksLocation and Marks.TextAlignment seem to control placement in the vertical direction, but I would like to control in the horizontal direction.
Regards
Errol
Re: Stacked Bar Chart and Marks
Hi Errol,
Here you have an example of custom positioning for the Bar Marks:
Here you have an example of custom positioning for the Bar Marks:
Code: Select all
uses Series;
procedure TForm1.FormCreate(Sender: TObject);
var s, i: Integer;
begin
Chart1.Legend.Visible:=false;
Chart1.View3D:=false;
for s:=0 to 4 do
with Chart1.AddSeries(TBarSeries) as TBarSeries do
begin
for i:=0 to 4 do
Add(25+random*75, 'S' + IntToStr(s) + ', I' + IntToStr(i));
MultiBar:=mbStacked;
MarksLocation:=mlCenter;
MarksOnBar:=true;
end;
PlaceMarks;
end;
procedure TForm1.PlaceMarks;
var s, i, tmpSize: Integer;
begin
Chart1.Draw;
for s:=0 to Chart1.SeriesCount-1 do
if Chart1[s] is TBarSeries then
with Chart1[s] as TBarSeries do
begin
for i:=0 to Count-1 do
with Marks.Positions[i] do
begin
Custom:=true;
LeftTop.X:=CalcXPos(i);
if MarksLocation=mlEnd then
LeftTop.Y:=CalcYPos(i)
else
begin
tmpSize:=CalcYSizeValue(YValue[i]);
if MarksLocation=mlStart then
LeftTop.Y:=CalcYPos(i)+tmpSize-Marks.Height
else
LeftTop.Y:=CalcYPos(i)+(tmpSize div 2)-(Marks.Height div 2);
end;
end;
end;
end;
procedure TForm1.Chart1Scroll(Sender: TObject);
begin
PlaceMarks;
end;
procedure TForm1.Chart1Zoom(Sender: TObject);
begin
PlaceMarks;
end;
procedure TForm1.Chart1UndoZoom(Sender: TObject);
begin
PlaceMarks;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Stacked Bar Chart and Marks
Hi again Errol,
I added the possibility to have some property to horizontally align the marks in the Bars into the wish list so it can be considered for inclusion in future releases:
http://bugs.teechart.net/show_bug.cgi?id=645
I added the possibility to have some property to horizontally align the marks in the Bars into the wish list so it can be considered for inclusion in future releases:
http://bugs.teechart.net/show_bug.cgi?id=645
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Stacked Bar Chart and Marks
Good morning Yeray
Thanks for all your help on this topic, and I look forward to tools to control basic marks positioning without having to go down the custom positioning route.
I have another problem which puzzles me - I am unable to hide the marks on my self-stacked bar chart. In the code snippet, the font size changes but the Marks.Visible setting is ignored, regardless of the value of the boolean ShowLabelText. Any ideas why this might be occurring?
Best regards
Errol
Thanks for all your help on this topic, and I look forward to tools to control basic marks positioning without having to go down the custom positioning route.
I have another problem which puzzles me - I am unable to hide the marks on my self-stacked bar chart. In the code snippet, the font size changes but the Marks.Visible setting is ignored, regardless of the value of the boolean ShowLabelText. Any ideas why this might be occurring?
Best regards
Errol
Code: Select all
with TUnitBarSeries(SeriesListB.Objects[iIndex]) do
begin
MultiBar := mbSelfStack;
CustomBarWidth := 80;
MarksLocation := mlCenter;
MarksOnBar := True;
Marks.Visible := self.owner.ShowLabelText;
Marks.Font.Size := self.owner.LabelFont;
ShowInLegend := false;
HorizAxis := aBottomAxis;
VertAxis := aLeftAxis;
...
active := true;
end;
Re: Stacked Bar Chart and Marks
Hi Yeray
Can you please abandon my last request regarding hiding marks. I see that the program calls an override version of DrawBar that overrides the Marks visible setting. Sorry about this.
Regards
Errol
Can you please abandon my last request regarding hiding marks. I see that the program calls an override version of DrawBar that overrides the Marks visible setting. Sorry about this.
Regards
Errol