Undesired effect from code added values to TLineSeries help!

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Metegrity
Newbie
Newbie
Posts: 13
Joined: Tue Sep 25, 2007 12:00 am
Contact:

Undesired effect from code added values to TLineSeries help!

Post by Metegrity » Wed Aug 18, 2010 7:24 pm

Version: 8.01.10798

I have a problem when I'm populating a TLineSeries with values through code:

Code: Select all

for iC := 0 to slReadingTypes.Count - 1 do
   begin
      csSeries := TLineSeries.Create(self);
      csSeries.Marks.ArrowLength := 1;
      csSeries.Pointer.Style := psCircle;
      csSeries.Pointer.Visible := true;
      csSeries.Pointer.Size := 2;
      csSeries.XValues.DateTime := true;
      csSeries.Title := slReadingTypes[iC];

      fraGTGraphNew.chtGraph.AddSeries(csSeries);

      ldsGraph.Filtered := True;
      ldsGraph.Filter := 'READTYPE = ''' + slReadingTypes[iC] + '''';
      ldsGraph.First;

      while not ldsGraph.eof do
      begin
         csSeries.AddXY(ldsGraph['TESTDATE'],ldsGraph['READING']);
         ldsGraph.Next;
      end;

   end;
The code is evoked after the form and the chart have been created, it's triggered withing an OnShow tab object event.
Perhaps I'm populating the values at an incorrect time?

The problem is that when I for example add only two dates (i.e. 1/5/2007 and 7/2/2009) the Bottom Axis displays ticks for values which don't exist and is a very undesirable formatting problem (so on the bottom axis instead of only seeing 1/5/2007 and 7/2/2009 and nothing in between I see all dates in between and the Y-Axis values aren't even aligned with the Bottom Axis grid).
Normally when a Client Data Set is assigned to a series it only shows values which exist.

I spend quite a bit of time playing around with the Chart settings, as well as somehow trying to tell the Chart through code to only display ACTUAL values, but I can't seem to be able to figure it out.

Please help, I've been stuck with this problem for quite some time now and need to have it corrected before our next release (which is scheduled very soon).

I can't attach a screen shot "Sorry, the board attachment quota has been reached."

Marcin.

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Yeray » Fri Aug 20, 2010 7:48 am

Hi Marcin,

If I understand well, you want the axis labels to only show values where there is a point (something like talText and talMark LabelStyle but showing Values instead of labels or the mark text).
It is already in the wish list to be implemented asap (TV52015098) a new LabelStyle to do it.

In the meanwhile you could use talText LabelStyle and format the text shown with OnGetAxisLabel. Something as following:

Code: Select all

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var point1: TPointSeries;
begin
  Chart1.View3D:=false;

  point1:=Chart1.AddSeries(TPointSeries) as TPointSeries;
  point1.XValues.DateTime:=true;
  point1.FillSampleValues(4);

  Chart1.Axes.Bottom.LabelStyle:=talText;
end;

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis;
  Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
begin
  if ((Sender = Chart1.Axes.Bottom) and (Sender.LabelStyle = talText)) then
  begin
    if ((Series <> nil) and (ValueIndex > -1)) then
    begin
      if (Sender.IsDateTime) then
        LabelText:=FormatDateTime(Sender.DateTimeFormat, Series.XValues[ValueIndex])
      else
        LabelText:=FloatToStr(Series.XValues[ValueIndex]);
    end;
  end;
end;
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Metegrity
Newbie
Newbie
Posts: 13
Joined: Tue Sep 25, 2007 12:00 am
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Metegrity » Fri Aug 20, 2010 3:09 pm

That's actually exactly what I needed.
To show only Bottom Labels where there is a point. No need for anything else here, just displaying the date's only for points with values. It works like a charm.

Perfect!

Thank you so much!

Marcin.

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Yeray » Fri Aug 20, 2010 3:25 pm

Hi Marcin,

You're welcome!
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Metegrity
Newbie
Newbie
Posts: 13
Joined: Tue Sep 25, 2007 12:00 am
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Metegrity » Fri Aug 20, 2010 3:28 pm

Hmm.

Except now my Bottom Axis Title, and Bottom aligned Legend don't format properly and the Labels run into those elements.
Any suggestions?

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Yeray » Mon Aug 23, 2010 10:48 am

Hi Marcin,

I've added the following code to the example above but couldn't reproduce any problem.

Code: Select all

  Chart1.Axes.Bottom.LabelStyle:=talText;
  Chart1.Axes.Bottom.Title.Caption:='My bottom axis title';
  Chart1.Legend.Alignment:=laBottom;
Anyway, it's possible that you'll have to calculate and define the margins manually, and maybe the legend position too.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Metegrity
Newbie
Newbie
Posts: 13
Joined: Tue Sep 25, 2007 12:00 am
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Metegrity » Mon Aug 23, 2010 3:27 pm

Unfortunately the formatting does get messed up for me.
I tried a variety of things, such as trying to repaint/refresh the chart or it's objects at different trigger times.
I was unable do correct the issue.

I did hope for setting some form of padding/spacing/margins on these objects (i.e. the Bottom Title and the Legend) but I'm having a really hard time finding a place where I could set any of these (in either the Chart Editor or in code).

I have to get this compiled and out the door by tomorrow. Any additional help would be appreciated!

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Yeray » Tue Aug 24, 2010 9:21 am

Hi Marcin,

We'll be pleased to try to find a way that works for you if we can reproduce the problem here so please, try to arrange a simple example project we can run as-is to reproduce the problem here.
My suspect is that you could be suffering a similar problem to what has been discussed here but an example project would help us to understand the problem better.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Metegrity
Newbie
Newbie
Posts: 13
Joined: Tue Sep 25, 2007 12:00 am
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Metegrity » Tue Aug 24, 2010 1:53 pm

graphissuesbottomx.jpg
graphissuesbottomx.jpg (120.79 KiB) Viewed 13102 times
This is the screen shot of the issue I am having.
The axis title and the legend are not shifted relative to the height of the labels, or maybe rather the chart area is not shifting leaving enough margin for the title and legend not to overlap.

My code still remains the same as mentioned above with the addition of what you described for the talText setting and the GetAxisLabel code.

Metegrity
Newbie
Newbie
Posts: 13
Joined: Tue Sep 25, 2007 12:00 am
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Metegrity » Tue Aug 24, 2010 2:00 pm

In addition the chart on run time goes through this initialization:

Code: Select all

procedure miChartInit(Graph: TDBChart;
   ReadLabelFlag: boolean;
   {FilterReadingLabel: string;}
   const XAxisLabelPosition: String {= 'horizontal'};
   const LeftAxisMaxOffset: integer {= 5};
   const RightAxisMaxOffset: integer {= 5};
   const BottomAxisMinOffset: integer {= 5};
   const BottomAxisMaxOffset: integer {= 5};
   const HideReadingLabels: string {= ''});
var
   iC: integer;
   bSetClipFlag: boolean;
begin

   ReadLabelFlag:= false;

   bSetClipFlag:= false;

   with Graph do
   begin

      for iC := 0 to Axes.Count - 1 do
         Axes[iC].Title.Font.InterCharSize:=0;


      LeftAxis.LabelsAngle:= 0;
      RightAxis.LabelsAngle:= 0;

      LeftAxis.MaximumOffset:= LeftAxisMaxOffset;
      RightAxis.MaximumOffset:= RightAxisMaxOffset;
      BottomAxis.MinimumOffset := BottomAxisMinOffset;
      BottomAxis.MaximumOffset := BottomAxisMaxOffset;

      ShowHint := false;

      if XAxisLabelPosition = 'horizontal' then
         BottomAxis.LabelsAngle:= 0
      else if XAxisLabelPosition = 'vertical' then
         BottomAxis.LabelsAngle:= 90
      else
         BottomAxis.LabelsAngle:= 0;

         Legend.CheckBoxes:= true;
         Legend.ShapeStyle:= fosRoundRectangle;
         Legend.RoundSize:= 15;
         Legend.ShadowSize:= 0;
         Legend.Alignment:= laBottom;

         Zoom.Pen.SmallDots:= true;
         Zoom.Pen.Color:= clWhite;
         Zoom.Brush.Style:= bsSolid;
         Zoom.UpLeftZooms:= true;
         Zoom.Brush.Color:= 8454016;

         Zoom.MouseButton:= mbLeft;
         ScrollMouseButton:= mbLeft;

         Title.Font.Color:= 0;
         Title.Font.Size:= 10;
         Title.Font.Style:= Title.Font.Style + [fsBold];
         Title.Font.InterCharSize:= 0;

         Color:= cl3DLight;

      for iC := 0 to SeriesCount - 1 do
      begin
         Series[iC].Marks.Visible:= false;
         Series[iC].Marks.Clip:=false;
         Series[iC].Marks.Font.Size:= 8;
         Series[iC].Marks.ArrowLength:= 1;
         Series[iC].Marks.Shadow.Visible:=false;
      end;
   end;

   miClipReadingLabels(Graph,false,bSetClipFlag);

end;
Perhaps you see something in there which may potentially be causing this issue?

Metegrity
Newbie
Newbie
Posts: 13
Joined: Tue Sep 25, 2007 12:00 am
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Metegrity » Tue Aug 24, 2010 3:19 pm

The issue was with not having any Series created on FormCreate.
Adding series later on (on ShowTab) was not formatting the chart properly.

I had to create a dummy series, I actually did it through the Chart Editor, which is assigned to a DataSet and holds X/Y values but is manually hidden from displaying anything.
That corrected the formatting.

Issue solved.

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Undesired effect from code added values to TLineSeries help!

Post by Yeray » Tue Aug 24, 2010 4:28 pm

Hi Marcin,

Once the axes labels are formatted with OnGetAxisLabels event, the margin and the position where the axis title has to be drawn isn't calculated so you have to do manually.
This is a very similar case to the thread mentioned above, where a new LabelStyle would avoid you to do all these manual calculations (TV52015098/TF02015095).
In your case, you also need an axis title and the position where the axis title has to be drawn isn't accessible so I'll suggest you to use an AnnotationTool to draw the axis title where you've calculated.
Here it is an example:

Code: Select all

uses Series, Math, TeeTools;

var maxLabelsWidthBottom: Integer;

procedure TForm1.FormCreate(Sender: TObject);
var point1: TPointSeries;
begin
  Chart1.Align:=alClient;
  Chart1.View3D:=false;

  point1:=Chart1.AddSeries(TPointSeries) as TPointSeries;
  point1.XValues.DateTime:=true;
  point1.FillSampleValues(8);

  Chart1.Axes.Bottom.LabelStyle:=talText;

  Chart1.Axes.Bottom.LabelStyle:=talText;
  Chart1.Axes.Bottom.Title.Caption:='My bottom axis title';
  Chart1.Axes.Bottom.Title.Visible:=false;
  Chart1.Legend.Alignment:=laBottom;
  Chart1.Legend.CustomPosition:=true;

  Chart1.Axes.Bottom.LabelsAngle:=90;

  with Chart1.Tools.Add(TAnnotationTool) as TAnnotationTool do
  begin
    Text:=Chart1.Axes.Bottom.Title.Caption;
    Shape.Visible:=false;
  end;

  Chart1.Draw;
end;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
  AdjustMarginsAndLegend;
end;

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis;
  Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
begin
  if ((Sender = Chart1.Axes.Bottom) and (Sender.LabelStyle = talText)) then
  begin
    if ((Series <> nil) and (ValueIndex > -1)) then
    begin
      if (Sender.IsDateTime) then
        LabelText:=FormatDateTime(Sender.DateTimeFormat, Series.XValues[ValueIndex])
      else
        LabelText:=FloatToStr(Series.XValues[ValueIndex]);

      if ValueIndex = 0 then
        maxLabelsWidthBottom:=Chart1.Canvas.TextWidth(LabelText)
      else
        maxLabelsWidthBottom:=Max(maxLabelsWidthBottom,Chart1.Canvas.TextWidth(LabelText));
    end;
  end;
end;

procedure TForm1.AdjustMarginsAndLegend;
var AnotTitle: TAnnotationTool;
begin
  Chart1.MarginUnits:=muPixels;

  AnotTitle:=Chart1.Tools[0] as TAnnotationTool;
  with Chart1.Axes.Bottom, Chart1.Canvas do
  begin
    Chart1.MarginBottom:=maxLabelsWidthBottom + TickLength + Chart1.Legend.Height + TextHeight(AnotTitle.Text);
    AnotTitle.Top:=Chart1.Height - Chart1.Legend.Height - TextHeight(AnotTitle.Text);
    AnotTitle.Left:=Round((Chart1.Width/2) - (TextWidth(AnotTitle.Text)/2));
  end;

  Chart1.Legend.Left:=Round((Chart1.Width/2) - (Chart1.Legend.Width/2));
  Chart1.Legend.Top:=Chart1.Height - Chart1.Legend.Height;
end;
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply