Marks inside of stacked bars?
-
- Newbie
- Posts: 10
- Joined: Thu Nov 06, 2003 5:00 am
- Location: Switzerland
- Contact:
Marks inside of stacked bars?
The marks of a stacked TBarSeries appear above the top of each bar. I'd like to have the marks appear inside of each stack (with the same distance for each stack from the bottom of the stack) and with a mark at
the top of the topmost stack showing the total of all the Series in the
stack.
I've already searched in the demo application but wasn't able to find a way to set the position of the marks
Is there any way to do this?
Thanks in advance
Pascal
the top of the topmost stack showing the total of all the Series in the
stack.
I've already searched in the demo application but wasn't able to find a way to set the position of the marks
Is there any way to do this?
Thanks in advance
Pascal
Hi, Pascal.
One easy workarund for this is to set marks ArrowLength propety to negative (reasonable) value. For example, the following code:
will display marks inside bars. Of course, the problem might arise if bars heights are less than 25 pixels, but in other cases it will work fine. There are additional refinements you can introduce - calculate best negative value to position series marks in the middle of bars, add code for the eventuality bar height is too small for mark, ...
One easy workarund for this is to set marks ArrowLength propety to negative (reasonable) value. For example, the following code:
Code: Select all
Series1.Marks.ArrowLength := -25;
-
- Newbie
- Posts: 10
- Joined: Thu Nov 06, 2003 5:00 am
- Location: Switzerland
- Contact:
This is what i currently do, but for the reasons you mentioned it's not an acceptable solution for me.Marjan wrote: One easy workarund for this is to set marks ArrowLength propety to negative (reasonable) value.
Do you have any code examples for this?Marjan wrote: calculate best negative value to position series marks in the middle of bars, add code for the eventuality bar height is too small for mark, ...
Is there also a solution for displaying an additional mark with the total of the entire bar (sum of all stacks) at the top of each bar?
Yes, sure. Try using the following code:8577662 wrote:Do you have any code examples for this?
Code: Select all
procedure CenterMarks(barSeries: TBarSeries);
var i : Integer;
yPos,yPos1,yPos2: Integer;
xPos: Integer;
MarkPos: TSeriesMarkPosition;
begin
MarkPos := TSeriesMarkPosition.Create;
for i := 0 to barSeries.Count - 1 do
begin
// just an example, you can do further customization here
MarkPos.Width := barSeries.BarWidth - 10;
MarkPos.Height := 16;
yPos1 := barSeries.CalcYPos(i); // get y screen pixel coordinate
if barSeries.UseYOrigin then yPos2 := barSeries.CalcYPosValue(0.0)
else yPos2 := barSeries.GetHorizAxis.PosAxis;
yPos := (YPos1+YPos2-MarkPos.Height) div 2;
xPos := barSeries.CalcXPos(i);
MarkPos.Custom := True;
MarkPos.LeftTop.X := xPos;
MarkPos.LeftTop.Y := yPos;
barSeries.Marks.Positions[i] := MarkPos;
end;
MarkPos.Free;
barSeries.Repaint;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Series1.Marks.Arrow.Visible := False;
Series1.Marks.Visible := True;
Series1.Add(5);
Series1.Add(11);
Series1.Add(-3);
Series1.Add(2.5);
end;
procedure TForm1.Series1BeforeDrawValues(Sender: TObject);
begin
CenterMarks(Sender as TBarSeries);
end;
Yes, it can be done. Basically, hide all other marks and display only last (top) series marks. Then in it's OnGetMarkText event, calculate the sum for each stack. Something like this:8577662 wrote:Is there also a solution for displaying an additional mark with the total of the entire bar (sum of all stacks) at the top of each bar?
Code: Select all
procedure TForm1.LastSeriesGetMarkText(Sender: TChartSeries;
ValueIndex: Integer; var MarkText: String);
var i:integer;
tmp:double;
begin
//sweeps through all values and calculates total
tmp:=0;
for i:=0 to Chart1.SeriesList.Count-1 do
if Chart1.Series[i].Active then
tmp:=tmp+Chart1.Series[i].YValue[ValueIndex]; //sum YValues
MarkText:=FloatToStr(tmp); //write a new MarkText
end;
procedure TForm1.FormCreate(Sender: TObject);
var i:Integer;
begin
for i:=0 to Chart1.SeriesList.Count-1 do
with Chart1.Series[i] do
begin
FillSampleValues(10);
Marks.Visible:=false; //we don't want marks for series
end;
with Chart1.Series[i-1] do
begin
OnGetMarkText:=LastSeriesGetMarkText; //assign OnGetMarkText event to last series
Marks.Visible:=true; //on the other hand, we want a mark for last series
end;
end;
-
- Newbie
- Posts: 10
- Joined: Thu Nov 06, 2003 5:00 am
- Location: Switzerland
- Contact:
Is there also a possibility to have the summary *AND* the marks (the summary in an additional mark above all stacks?Marjan wrote: Yes, it can be done. Basically, hide all other marks and display only last (top) series marks. Then in it's OnGetMarkText event, calculate the sum for each stack
Thanks
Pascal
Hi. Pascal.
Not automatically. But you can do several things:
1) Add extra line (summary) to existing mark text. This can be done in TChartSeries.OnGetMarkText event.
2) Manually draw required texts above series marks in TChart OnAfterDraw event. Basically, use TChart.Canvas.TextOut method to paint specific text at given screen coordinate.
3) Use series of TAnnotationTool tools to add extra text above series marks,
I hope any of these methods will help you
Not automatically. But you can do several things:
1) Add extra line (summary) to existing mark text. This can be done in TChartSeries.OnGetMarkText event.
2) Manually draw required texts above series marks in TChart OnAfterDraw event. Basically, use TChart.Canvas.TextOut method to paint specific text at given screen coordinate.
3) Use series of TAnnotationTool tools to add extra text above series marks,
I hope any of these methods will help you
-
- Newbie
- Posts: 10
- Joined: Thu Nov 06, 2003 5:00 am
- Location: Switzerland
- Contact:
The problem with this code is, that it will center the Marks for the size of all stacked bars. What I need is to center the mark between the top of a stack and the bottom of a stack (and not the bottom of the bar / position of the x axes).Marjan wrote: Yes, sure. Try using the following code:
Is there a way to get the bottom position of a stack? or the top position of the underlying stack?
-
- Newbie
- Posts: 10
- Joined: Thu Nov 06, 2003 5:00 am
- Location: Switzerland
- Contact:
I think you misunderstood my question. My problem is, that the code you've posted for centering the marks in the stacks (CenterMarks procedure), does only work for the first stack.Marjan wrote:You'll have to calculate it manually. First calculate the sum of all values, except the last series value. Then the middle of last bar will be equal to ("sum of all values" + "sum of all except the last value")*0.5.
For every other stack the mark is centered in the *full* bar height and not in the *stack* height
Thanks
Pascal
How about using the following code ? :
Josep Lluis Jorge
http://support.steema.com
Code: Select all
procedure TForm1.PositionChartMarks(BarSeries: TBarSeries);
var
i: integer;
YPos: integer;
BarTop: integer;
BarBottom: integer;
XPos: integer;
MarkPos: TSeriesMarkPosition;
begin
MarkPos := TSeriesMarkPosition.Create;
try
for i := 0 to BarSeries.Count - 1 do begin
// just an example, you can do further customization here
MarkPos.Width := BarSeries.BarWidth;
MarkPos.Height := 16;
BarTop := BarSeries.CalcYPos(i); // get y screen pixel coordinate
BarBottom := BarSeries.CalcYPosValue(BarSeries.PointOrigin(i,false));
YPos := (BarTop + BarBottom - MarkPos.Height) div 2;
// Make sure that the value isn't painted below the X Axis
if YPos > (BarSeries.GetHorizAxis.PosAxis - (MarkPos.Height)) then begin
YPos := BarSeries.GetHorizAxis.PosAxis - (MarkPos.Height);
end;
XPos := BarSeries.CalcXPos(i);
MarkPos.Custom := True;
MarkPos.LeftTop.X := XPos;
MarkPos.LeftTop.Y := YPos;
BarSeries.Marks.Positions[i] := MarkPos;
end;
finally
MarkPos.Free;
end;
BarSeries.Repaint;
end;
procedure TForm1.Series1BeforeDrawValues(Sender: TObject);
begin
PositionChartMarks(Sender as TBarSeries);
end;
http://support.steema.com
-
- Newbie
- Posts: 10
- Joined: Thu Nov 06, 2003 5:00 am
- Location: Switzerland
- Contact:
Ok, I'll add on our wish list to be considered for the next releases.
Josep Lluis Jorge
http://support.steema.com
Josep Lluis Jorge
http://support.steema.com