Page 1 of 2
Stacked Bar Chart and Marks
Posted: Thu Feb 20, 2014 5:14 am
by 16566546
- Lithology_Chart_Labels.png (12.22 KiB) Viewed 20753 times
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.
Re: Stacked Bar Chart and Marks
Posted: Thu Feb 20, 2014 9:44 am
by narcis
Hi Errol,
Yes, you can do this:
However, there's new
MarksOnBar property to achieve what you request:
Re: Stacked Bar Chart and Marks
Posted: Thu Feb 20, 2014 10:56 pm
by 16566546
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?
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;
- Lithology_Chart_Labels002.png (6.82 KiB) Viewed 20713 times
Re: Stacked Bar Chart and Marks
Posted: Fri Feb 21, 2014 9:45 am
by narcis
Hi Errol,
You can use custom marks position, something as the example Yeray Alonso made
here.
Re: Stacked Bar Chart and Marks
Posted: Fri Feb 21, 2014 10:16 am
by yeray
Hi Errol,
You can also try with:
Re: Stacked Bar Chart and Marks
Posted: Mon Feb 24, 2014 3:16 am
by 16566546
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
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
Posted: Thu Mar 06, 2014 3:22 am
by 16566546
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).
- Marks_Dragged_1.png (8.26 KiB) Viewed 20651 times
- BarChart_Panned_2.png (7.57 KiB) Viewed 20662 times
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
Posted: Thu Mar 06, 2014 3:03 pm
by yeray
Hi Errol,
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?
Take a look at the answer here:
http://www.teechart.net/support/viewtop ... 033#p34033
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;
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.
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;
Re: Stacked Bar Chart and Marks
Posted: Fri Mar 07, 2014 6:01 am
by 16566546
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
Re: Stacked Bar Chart and Marks
Posted: Fri Mar 07, 2014 9:59 am
by yeray
Hi Errol,
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.
You're welcome!
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?
No but you can create you own boolean, initialize it at OnCreate and change it at with the TDragMarksTool OnDraggedMark event. Ie:
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;
Re: Stacked Bar Chart and Marks
Posted: Sat Mar 15, 2014 5:12 am
by 16566546
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
Re: Stacked Bar Chart and Marks
Posted: Mon Mar 17, 2014 3:35 pm
by yeray
Hi Errol,
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;
Re: Stacked Bar Chart and Marks
Posted: Wed Mar 19, 2014 9:48 am
by yeray
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
Re: Stacked Bar Chart and Marks
Posted: Sun Mar 23, 2014 10:57 pm
by 16566546
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
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
Posted: Sun Mar 23, 2014 11:18 pm
by 16566546
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