Page 1 of 1

color or hide each line segment separately

Posted: Tue Jul 16, 2013 6:44 am
by 16566563
I would like to set the color of the line segement interconnecting to adjacent points added to a TLineSeries different from the points color, or find a way to hide, or disable the this line segment for each point. (i.e. settings to clNone would also hide the segement). When adding new values to the TlineSeries, one can define a color property which sets the points color as well as the color of the line segement from its predecessor to the point currently added. Though its possible to show the line segements in the series color and set each point a different color there might be a way to set each line segement color also - How should I try to approach this ?

Re: color or hide each line segment separately

Posted: Wed Jul 17, 2013 2:11 pm
by yeray
Hi,

This looks similar to the issue discussed here.
However, in your case, since you also want the pointers to follow a different color palette, I'd suggest you to use an extra series, a TPointSeries, with the same values but different colors:

Code: Select all

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D:=false;
  Chart1.Legend.Visible:=false;

  with Chart1.AddSeries(TLineSeries) as TLineSeries do
  begin
    FillSampleValues(10);
    ColorEachPoint:=true;

    for i:=0 to Count-1 do
      ValueColor[i]:=OperaPalette[i];
  end;

  with Chart1.AddSeries(TPointSeries) as TPointSeries do
  begin
    DataSource:=Chart1[0];
    ColorEachPoint:=true;

    for i:=0 to Count-1 do
      ValueColor[i]:=ModernPalette[i];
  end;
end;

Re: color or hide each line segment separately

Posted: Wed Jul 17, 2013 5:17 pm
by 16566563
Dear Yeray,

my requirement is a little bit different. I would like add points to a TLineseries but not show some line segments of the series. I need this in order to show a gap in between the lineseries if for example the time difference between two consecutive points exeeds a certain limit. The solution I'm working with is to create a new series if the time difference is too big, but this solution add to chart a few thousand series sometimes , which I think isn't good solution at all.
If there would be a way to enable / disable each line segment when adding the points like you can set the points color using the "Addxy" method, or any other way like this I would be glad....

Best regards,

Klaus

Re: color or hide each line segment separately

Posted: Thu Jul 18, 2013 11:08 am
by yeray
Hi Klaus,

You could use null points. Just note setting a point as null will make both the predecessor and the successor line segments not to be drawn. So, if you want to hide just a segment, you could add an extra point between the two points for the segment and set it to be null. Ie:

Code: Select all

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D:=false;
  Chart1.Legend.Visible:=false;

  with Chart1.AddSeries(TLineSeries) as TLineSeries do
  begin
    Pointer.Visible:=false;
    for i:=0 to 5 do
    begin
      AddXY(i, random*100);

      if i=2 then //to hide the segment between X=2 and X=3
        AddNullXY(i, 0);
    end;
  end;
end;

Re: color or hide each line segment separately

Posted: Mon Jul 22, 2013 1:14 pm
by 16566563
Dear Yeray,

Using null points is unfortunately not an option to use, because the chart data is also accessed from a table view component (TVirtual string tree), which provides an index to the data in its OnGetText event. inserting 0 points would not allow to access the chart series efficiently due to an index shift between the chart series and the table component because the null points should not be visible in the table.
The optimal solution would to have a method " AddXY(XValue: Double; YVale: Double; Color: TColor, DrawLineSegment: boolean) ", which would allow to enable / disable the line segment for each point when adding the data, without having to add uncolored or null points in between if you don't want to have the points joined with a line segment.
I currently thinking about adding an overloaded method AddXY... which provides the "DrawLinesegement" parameter, but digging into the TChart source code seems to be not the easiest task...

Best regards,

Klaus

Re: color or hide each line segment separately

Posted: Mon Jul 22, 2013 3:32 pm
by yeray
Hi Klaus,
niotronic wrote:The optimal solution would to have a method " AddXY(XValue: Double; YVale: Double; Color: TColor, DrawLineSegment: boolean) ", which would allow to enable / disable the line segment for each point when adding the data, without having to add uncolored or null points in between if you don't want to have the points joined with a line segment.
I currently thinking about adding an overloaded method AddXY... which provides the "DrawLinesegement" parameter, but digging into the TChart source code seems to be not the easiest task...
You could create a custom series inheriting from TLineSeries. Your new series could have an extra array of booleans to store this and the AddXY override you mentioned.
Then you'll have to decide what segment does this property hide: the predecessor or the successor. And then, you should probably override the DrawValue setting the color to clTransparent when the segment has to be hidden.

Find attached a testing project. As you'll see, you just need to add the following condition to skip adding the extra/null points to the table:

Code: Select all

if not Chart1[0].IsNull(i) then
I understand you can't use null points, but the example may be still valid to test your AddXY override.
test.zip
(1.79 KiB) Downloaded 1229 times

Re: color or hide each line segment separately

Posted: Tue Jul 23, 2013 2:46 pm
by 16566563
Dear Yeray,

good idea - I have already started implementing this derivated class of TLineSeries. What I am bothering around is how to change the color of the line segment in the overriden DrawValue function. Would you like to tell me what properties to change in order to show or hide the previous line segment (the one from the previous point to the current one)
I tried to set the ValueColor[Valueindex] in the DrawValue function, but this changed the color of both line segments (pervious and the next one). I would appreciate if you could provide me with a short code snippet for the DrawValue function.


Best regards,


Klaus

Re: color or hide each line segment separately

Posted: Fri Jul 26, 2013 1:45 pm
by yeray
Hi Klaus,

I'm afraid it won't be as easy as I initially thought. The problem is that the DrawValue(ValueIndex: Integer) function is a quite big one, that draws both the pointer and the line segment between the ValueIndex-1 and ValueIndex. Since both the pointer and the segments are drawn in the same function, I don't see any property you can set to make the current pointer to be drawn but skip drawing the segment, still calling the TLineSeries.DrawValue function through the inherited call:

Code: Select all

  TMyLineSeries = class(TLineSeries)
  protected
    procedure DrawValue(ValueIndex:Integer); override;
  end;

procedure TMyLineSeries.DrawValue(ValueIndex:Integer);
begin
  //set up the series to draw all the pointers but only some segments
  inherited;
end;
So the easier way to achieve it will probably be to directly modify the TLineSeries.DrawValue function in the sources. In the DrawPoint procedure, nested into DrawLine, you'll find the DrawLine2D procedure is called under the condition:

Code: Select all

if (not View3D) and FDrawLine then
Here you can add another condition, checking if the predecessor segment has to be drawn. If your array of booleans to store this information is called DrawSegment, it could be:

Code: Select all

if (not View3D) and FDrawLine and DrawSegment[ValueIndex] then
If checked it directly with (ValueIndex<>3) to check it without implementing the array of booleans, and it seems to work fine for me

Re: color or hide each line segment separately

Posted: Wed Sep 04, 2013 11:02 pm
by 15666411
Hi Klaus,

Did you ever get this working? I've got a similar (if not identical) problem: I need to hide some line segments, but I'm also exporting tabular data so spurious extra points are not acceptable.

Matt

Re: color or hide each line segment separately

Posted: Fri Sep 06, 2013 7:02 am
by yeray
Hi Matt,

I don't see why the custom series with the extra array of boolean shouldn't work. Have you tried it?
The only problem I see is that the source code is needed so you can change the DrawValue function.

Re: color or hide each line segment separately

Posted: Thu Oct 10, 2013 9:33 pm
by 15666411
Thanks Yeray. I just saw your response now. (Problem with my email.) I'll give your suggestion a try and let you know how it goes.

Thanks,
Matt

Re: color or hide each line segment separately

Posted: Mon Oct 21, 2013 10:22 am
by David
Another solution that might work without modifying TlineSeries source code is:

Code: Select all

procedure TMyLineSeries.DrawValue(ValueIndex:Integer);
begin
  FDrawLine:=DrawSegment[ValueIndex];
  inherited;
  FDrawLine:=True;
end;
regards
david