Position of marks in self stacked bar chart

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Joschi
Newbie
Newbie
Posts: 26
Joined: Mon Oct 27, 2003 5:00 am
Location: Germany
Contact:

Position of marks in self stacked bar chart

Post by Joschi » Fri Apr 15, 2005 11:54 am

Hi.

I need to add a self stacked horizontal bar chart that shows the spreading of data. This is basically the same as a pie chart, but this fits better into the UI.

The problem that I have is that the marks are positioned just on the stacked chart. Is there any way to position the marks beside the chart?

Best regards,

Joachim Marder

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Fri Apr 15, 2005 1:21 pm

Hi Joachim,

Yes, you can do something similar to:

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  APosition:TSeriesMarkPosition;
begin
  Series1.FillSampleValues();
  Chart1.Draw();

  APosition:=TSeriesMarkPosition.Create;
  try
    for i:=0 to Series1.Count-1 do
    begin
      APosition.Custom:=True;
      APosition.LeftTop.X:=Series1.Marks.Positions[i].LeftTop.X;
      APosition.LeftTop.Y:=Series1.Marks.Positions[i].LeftTop.Y-35;
      Series1.Marks.Positions[i]:=APosition;
    end;
  finally
      APosition.Free;
  end;
end;
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Joschi
Newbie
Newbie
Posts: 26
Joined: Mon Oct 27, 2003 5:00 am
Location: Germany
Contact:

Post by Joschi » Wed Apr 20, 2005 5:07 pm

Dear Narcis.

I am using TeeChart Pro V6.01. If I use the code you posted, all marks in this series get transparent. Do you have any idea why?

And I wasn't able to find any documentation about the properties of TSeriesMarkPosition in the help file. Is this missing?

Best regards,

Joachim Marder

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Thu Apr 21, 2005 9:20 am

Hi Joachim,

Yes, you are right. Then you'd better use something similar to the code below not using TSeriesMarkPosition:

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  Series1.FillSampleValues();
  Chart1.Draw();

  for i:=0 to Series1.Count-1 do
  begin
    With Series1.Marks.Positions.Position[i] do
    Begin
      Custom:=True;
      LeftTop.Y := LeftTop.Y - 35;
    end;
  end;
  Series1.Marks.Arrow.Visible:=false;
  Series1.Repaint;
end;
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Joschi
Newbie
Newbie
Posts: 26
Joined: Mon Oct 27, 2003 5:00 am
Location: Germany
Contact:

Post by Joschi » Tue May 10, 2005 3:17 pm

Dear Narcis.

The solution you proposed is working quite OK. But The problem is that the call to the draw method makes the chart appear for a short time with the marks in their original position. This fklickering looks very odd.

Is there an alternative to the Draw() method that does fill the Marks.Positions property but does not update the chart on the screen?

Thanks and best regards,

Joachim

Marjan
Site Admin
Site Admin
Posts: 745
Joined: Fri Nov 07, 2003 5:00 am
Location: Slovenia
Contact:

Post by Marjan » Wed May 11, 2005 1:46 pm

Hi, Joachim.

Series marks positions are created when chart is drawn. The only way around this is to manually create series marks positions as Narcis demonstrated in one of his previous posts. Alternatively, it might help enclosing the code in the Chart.AutoRepaint := False; and Chart.AutoRepaint := True, but I'm not 100% sure it will stop flickering:

Code: Select all

  Chart1.AutoRepaint := False;
  // your code comes here
  Chart1.AutoRepaint := True;
Marjan Slatinek,
http://www.steema.com

Joschi
Newbie
Newbie
Posts: 26
Joined: Mon Oct 27, 2003 5:00 am
Location: Germany
Contact:

Post by Joschi » Mon Jun 06, 2005 8:27 am

Dear support team.

I spent hours and hours to get this simple task to work properly, but yet without success.
The only way around this is to manually create series marks positions as Narcis demonstrated in one of his previous posts.
If I do that, I need to not only fill in the postion, but also the Width, Height etc., because Marks.Positions is completely empty. But how should I know how many pixels my marks have to be wide and high? If I call TChart.Draw before, then there are default values that I can adjust, but then the chart flickers.
Alternatively, it might help enclosing the code in the Chart.AutoRepaint := False; and Chart.AutoRepaint := True, but I'm not 100% sure it will stop flickering
It won't stop flickering. The problem is that I need to call TChart.Draw to get the Marks.Positions filled with default values (see above). Is there any possibility to fill the Marks.Positions with default values without actually drawing the chart?

I am using a self stacked horizontal bar chart. The problem is that the mark of each segment is displayed right of this segment on top of the next segment. I find this very irritating because the user may think the mark he sees on a segment belongs to this segment, which is not true. So I just want to move the marks a little bit. A rather simply task I thought initially...

Are there any improvemnts in TeeChart V7 that would help me to solve this problem?

Best regards,

Joachim Marder
JAM Software

kualoa1
Newbie
Newbie
Posts: 27
Joined: Fri Nov 21, 2008 12:00 am

labeling points

Post by kualoa1 » Tue Nov 25, 2008 4:13 pm

I added a series1 using the editor so it exists at design time. I then set the onegetmark code to this

Code: Select all

procedure Tbubble1f.Series1GetMarkText(Sender: TChartSeries;
  ValueIndex: Integer; var MarkText: String);
var
  i: Integer;
  APosition:TSeriesMarkPosition;
begin
  Series1.FillSampleValues();
  Chart1.Draw();

  APosition:=TSeriesMarkPosition.Create;
  try
    for i:=0 to Series1.Count-1 do
    begin
      APosition.Custom:=True;
      APosition.LeftTop.X:=Series1.Marks.Positions[i].LeftTop.X;
      APosition.LeftTop.Y:=Series1.Marks.Positions[i].LeftTop.Y-35;
      Series1.Marks.Positions[i]:=APosition;
    end;
  finally
      APosition.Free;
  end;

end;
from the example. I has no impact. any ideas? thank you.

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Tue Nov 25, 2008 4:30 pm

Hi kualoa1,

Could you please send us a simple example project we can run "as-is" to reproduce the problem here?

You can either post your files at news://www.steema.net/steema.public.attachments newsgroup or at our upload page.

Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

kualoa1
Newbie
Newbie
Posts: 27
Joined: Fri Nov 21, 2008 12:00 am

labeling points

Post by kualoa1 » Tue Nov 25, 2008 6:56 pm

sending project snippet for as-is review too involved. uses components you do not have. i create series1a at design time. i set this series1a ongetmarktext code:

Code: Select all

procedure Tbubble1f.Series1aGetMarkText(Sender: TChartSeries;
  ValueIndex: Integer; var MarkText: String);
var
  i: Integer;
  APosition:TSeriesMarkPosition;
begin
//  Series1.FillSampleValues();
  Chart1.Draw();

  APosition:=TSeriesMarkPosition.Create;
  try
    for i:=0 to Series1.Count-1 do
    begin
      APosition.Custom:=True;
      APosition.LeftTop.X:=Series1.Marks.Positions[i].LeftTop.X;
      APosition.LeftTop.Y:=Series1.Marks.Positions[i].LeftTop.Y-35;
      Series1.Marks.Positions[i]:=APosition;
    end;
  finally
      APosition.Free;
  end;
end;

in my loop that draws the chart I have this code:

Code: Select all

 Series1:=TBubbleSeries.Create(self);
 Chart1.AddSeries(Series1);
--> Series1.OnGetMarkText:=Series1a.onGetMarkText;
but when I run this code it does not display chart and freezes.

it was workling without line marked -->

thoughts?

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Wed Nov 26, 2008 8:37 am

Hi kualoa1,

The problem here is that OnGetMarkText event is not designed for what you are using it and, moreover, you shouldn't call Chart1.Draw on it as you'll make your application fall in an endless loop.

Code below works fine for me here:

Code: Select all

Uses BubbleCh;

procedure TForm1.FormCreate(Sender: TObject);
var Series1 : TBubbleSeries;
    i       : Integer;
    x       : Double;
    y       : Double;
    radius  : Double;
begin
  Chart1.View3D:=false;
  Series1:=TBubbleSeries.Create(self);
  Chart1.AddSeries(Series1);

  Series1.Marks.Visible:=true;

  for i := 0 to 10 do
  begin
    x:=i;
    y:=random*10;
    radius:=random;
    Series1.AddBubble(x,y,radius);
  end;

  Chart1.Draw();
end;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var
  i: Integer;
  APosition:TSeriesMarkPosition;
begin

  APosition:=TSeriesMarkPosition.Create;
  try
    for i:=0 to Chart1[0].Count-1 do
    begin
      APosition.Custom:=True;
      APosition.LeftTop.X:=Chart1[0].Marks.Positions[i].LeftTop.X;
      APosition.LeftTop.Y:=Chart1[0].Marks.Positions[i].LeftTop.Y-35;
      Chart1[0].Marks.Positions[i]:=APosition;
    end;
  finally
      APosition.Free;
  end;
end;
OnGetMarkText event is for modifying marks text not its position.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

kualoa1
Newbie
Newbie
Posts: 27
Joined: Fri Nov 21, 2008 12:00 am

labeling points

Post by kualoa1 » Wed Nov 26, 2008 11:41 am

thank you. I get this code to execute. however, the central purpose is to "wrap a long label". in your demo, you are not showing a label. when I tun this with a "long label" (eg 90 char), it still displays the full width.

Code: Select all

    lbl:=getcfield(b_labelfield1); 
    Series1.addbubble(x,y,radius,lbl);
lbl in above case can be 90 char; it still shows full with your afterdraw code.

thoughts?

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Wed Nov 26, 2008 11:57 am

Hi kualoa1,

Yes, as I already told you, my code is not parsing marks text. You should manually parse it using the OnGetMarkText event. You can use string provided by MarkText parameter, do the parsing you wish and then assign resulting string to MarkText again.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

kualoa1
Newbie
Newbie
Posts: 27
Joined: Fri Nov 21, 2008 12:00 am

labeling points

Post by kualoa1 » Wed Nov 26, 2008 12:29 pm

thank you. i am close to giving up on this. a simple, common task has become an ordeal.

I keyed in on your recent note "The problem here is that OnGetMarkText event is not designed for what you are using it and, moreover, you shouldn't call Chart1.Draw on it as you'll make your application fall in an endless loop. " and therefore removed that code. I had set that code up in the manner that you had suggested before. now, i am totally adrift on this.

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Wed Nov 26, 2008 2:28 pm

Hi kualoa1,

Sorry if I haven't been clear enough.

In the case we have been speaking about, OnAfterDraw is better suited for setting custom position for marks. OnGetMarkText is for customizing the marks text itself, not its position.

I've arranged a simple example where every blank space in the marks is automatically replaced by a line break. In the same maner you should parse marks text to fit your needs.

Code: Select all

procedure TForm3.FormCreate(Sender: TObject);
var i: Integer;
begin
  for i := 0 to 10 do
    Series1.Add(random, 'Point number ' + IntToStr(i+1));
end;

procedure TForm3.Series1GetMarkText(Sender: TChartSeries; ValueIndex: Integer;
  var MarkText: string);
var tmp: Integer;
begin
  tmp:=pos(' ', MarkText);

  while tmp<>0 do
  begin
    MarkText:=copy(MarkText, 0, tmp-1) + #13 +
              copy(MarkText, tmp+1, Length(MarkText));
    tmp:=pos(' ', MarkText);
  end;
end;
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Post Reply