A few (hopefully!) simple problems

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Andrew S
Newbie
Newbie
Posts: 42
Joined: Wed Jul 28, 2004 4:00 am

A few (hopefully!) simple problems

Post by Andrew S » Thu Aug 26, 2004 2:26 pm

I initially posted these questions as a reply to another thread, but figured they merited a thread of their own...

I tried using the Marks tip tool to display tool tips for my chart. Unfortunatly, since I have so many points, with so little space between, it's difficult to tell exactly which point the tooltip refers to. I'm wondering how difficult it would be to have it so when you left click on the chart, a vertical line across the whole chart denotes which point you've selected, and a display of the x and y values for that point appears.

I also have another problem. How do I stop the grid lines from the left axis from being drawn over top of my legend? I don't suppose there's some sort of chart1.LeftAxis.Grid.SendToBack function or something is there?

How do I detect which legend checkbox was clicked? Here's my problem. I have 4 series in my graph. I want the ability to activate/deactivate any number of them, so I can't use radio buttons. However, I don't want it to be possible to deactivate them all at once. Right now I have a simple one liner in the Chart1ClickLegend event that goes something like:

if not(Series1.Active) and not(Series2.Active) then Series1.Active := true;

...this however means that when you try to deactivate all of them, it jumps to displaying the first series, which I don't like too much.

Lastly, my bottom axis is a datetime axis, with data for each second. I have my labels at the min and max of the axis displaying hh:nn:ss. I want to have the vertical gridlines in my chart denote the start of each day. How would I do that? I can't seem to figure out how to draw grid lines at differing intervals from the labels. I was thinking of just creating a series per day, but don't like that solution, as I have no way of knowing how many days we're talking about. I read in one of the posts about manually drawing a line at particular points in the graph, but I'm not sure how to go about doing that.

You help is greatly appreciated. Let me know if you need any more information,

Andrew

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

Post by Marjan » Mon Aug 30, 2004 3:41 pm

Hi, Andrew.
you left click on the chart, a vertical line across the whole chart denotes which point you've selected, and a display of the x and y values for that point appears.
Sure, you can do this. You could use Chart OnClickSeries event to retrieve clicked series index and then chart OnAfterDraw event to draw the pointer and display values. Something like this

Code: Select all

  private
    { Private declarations }
    ClickedSeries: TChartSeries;
    Index: Integer;
procedure TForm1.Chart1ClickSeries(Sender: TCustomChart;
  Series: TChartSeries; ValueIndex: Integer; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Index := ValueIndex;
  ClickedSeries := Series;
  Sender.Repaint;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Series1.FillSampleValues(10);
  ClickedSeries := nil;
  Index := -1;
end;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var x,y: integer;
    text: String;
begin
  if (ClickedSeries<>nil) and (Index<> -1)
    and (ClickedSeries.ParentChart<>nil) then
  begin
    x := ClickedSeries.CalcXPos(Index);
    y := ClickedSeries.CalcYPos(Index);
    With ClickedSeries.ParentChart do
    begin
      Canvas.ClipRectangle(ClientRect);
      Canvas.Pen.Style := psSolid;
      Canvas.Pen.Width := 2;
      Canvas.Pen.Color := ClickedSeries.Color;
      Canvas.Line(x,ChartRect.Top,x,ChartRect.Bottom);
      Canvas.Line(ChartRect.Left,y,ChartRect.Right,y);
      text := '('+FormatFloat('0.00',ClickedSeries.XValue[Index])+' ; '+
        FormatFloat('0.00', ClickedSeries.YValue[Index])+')';
      Canvas.TextOut(x+1,y-Canvas.TextHeight('W')-1,text);
      Canvas.UnclipRectangle;
      end;
  end;
end;
grid lines from the left axis from being over top of my legend
Normally the axes are drawn before the legend is drawn so this shouldn't happen. Can you send me test application (sources only!) which demonstrates this problem. You can post it at attahments newsgroup or send it directly to my "marjan at steema dot com" email address.
How do I detect which legend checkbox was clicked?
This is something not yet implemented. State of checkbox is determined by the series Active/Visible property. But if you simply want to show/hide some series, why isn't the existing implementation enough? Clicking on checkboxes does show/hide series you selected in the legend.
line at particular points in the graph, but I'm not sure how to go about doing that.
Use the same approach I used in the example above to draw cursor (in the Chart OnAfterDraw event).
Marjan Slatinek,
http://www.steema.com

Andrew S
Newbie
Newbie
Posts: 42
Joined: Wed Jul 28, 2004 4:00 am

Post by Andrew S » Mon Aug 30, 2004 4:49 pm

Marjan,

Thanks for your response.

Regarding the legend checkboxes, clicking on checkboxes does show/hide series as you say. However, as I mentioned previously, it's important that the user not be able to unselect ALL of the series. I need the ability to allow the user to select/unselect any number of series between 1 and Chart1.SeriesList.Count

Regarding the grid lines drawing over the legend I will send you a sample project via email a little later this afternoon.

Thanks very much for the sample code on manually drawing lines. I will try it out this afternoon and let you know how it goes.

Andrew

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

Post by Marjan » Tue Aug 31, 2004 5:53 am

Hi, Andrew.
I will send you a sample project
Got it, thanks. In your example you've set Legend.ResizeChart property to false meaning chart will be drawn over the legend area. In this case the solution might be to initially hide the legend and then (re)draw it in chart OnBeforeDrawSeries event.

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
begin
  Chart1.Legend.Visible := False;
end;

procedure TForm1.Chart1BeforeDrawSeries(Sender: TObject);
begin
  Chart1.Legend.DrawLegend;
end;
does show/hide series as you
Using the latest TeeChart version (7.01) it works fine. Which TeeChart version are you using ? I've posted a test application demonstrating this at our attachments newgroup (subject : "for Andrew"). Does it work as expected ?
Marjan Slatinek,
http://www.steema.com

Andrew S
Newbie
Newbie
Posts: 42
Joined: Wed Jul 28, 2004 4:00 am

Post by Andrew S » Tue Aug 31, 2004 3:55 pm

Calling drawLegend in the BeforeDrawSeries procedure worked perfectly. Now my legend isn't obscured by the gridlines. I'm still playing with drawing lines. I'll let you know how that goes. Thanks for the help.

Just FYI,

Andrew

Post Reply