Displaying Dashed Lines with data-dense series

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Errol
Newbie
Newbie
Posts: 35
Joined: Mon Jul 02, 2018 12:00 am

Displaying Dashed Lines with data-dense series

Post by Errol » Sat Sep 01, 2018 2:32 am

Good morning
I use TeeChart to present scientific data measured down a geothermal well. With modern equipment, data can be collected at very closeintervals, as small as 6 inches (15 cm) which would result in over 13,000 data points in a series! If all data points are displayed, a solid dark line is displayed.
AllDataPoints.png
AllDataPoints.png (13.63 KiB) Viewed 5874 times
To overcome this, I have to generate 3 series, a line series, a fastline series and a point series. The line series is not plotted and only used for the legend. I can then limit the number of points that are plotted as shown.
SelectedDataPoints.png
SelectedDataPoints.png (12.61 KiB) Viewed 5874 times
On a typical graph, I might plot up to 20 series. to be able to clearly differentiate, it is necessary to use the full range of presentation features, which includes line type (e.g. solid, dotted, dashed, etc.) However, because of the data density, the dashed line in the example plots as a solid line.
I know this issue has been raised before, and the only solution was to reduce the number of points displayed, using a DownSampling tool. I have not tried this, but I presume it thins the number of points and therefore the fine detail in the curve. I like to display all the data, especially given the very powerful tool in TeeChart where a user can zoom in and examine fine detail very easily.
I think it is time that the FastLine series, at least, was modified to print a uniformly dashed line regardless of the data density. I do not understand why this should be so difficult and it would definitely raise TeeChart credentials as a scientific data charting tool.
I look forward to your comments on this issue.
Best regards
Errol

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

Re: Displaying Dashed Lines with data-dense series

Post by Yeray » Mon Sep 03, 2018 2:12 pm

Hello,

I've done a simple example where I'm using the TDownSamplingFunction with the minimum Tolerance needed to draw line segments of a minimum of 5 pixels wide, so they can be drawn in the Dashed style:

Code: Select all

uses Series, TeeDownSampling, Math;

var oSeries, dSeries: TFastLineSeries;
    dFunc: TDownSamplingFunction;
    minSector: Integer;

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

  Chart1.Axes.Bottom.Grid.Hide;
  Chart1.Axes.Left.Grid.Hide;
  Chart1.Axes.Left.SetMinMax(0,2000);

  oSeries:=Chart1.AddSeries(TFastLineSeries) as TFastLineSeries;
  with oSeries do
  begin
    Pen.Style:=psDash;

    Add(1000);
    for i:=0 to 400-1 do
      Add(YValue[Count-1]+Random*10-5);

    Active:=False;
  end;

  dSeries:=Chart1.AddSeries(TFastLineSeries) as TFastLineSeries;
  dFunc:=TDownSamplingFunction.Create(Self);
  dFunc.DownSampleMethod:=dsAverage;
  dSeries.SetFunction(dFunc);
  dSeries.Pen.Style:=oSeries.Pen.Style;
  dSeries.Color:=oSeries.Color;
  dSeries.DataSource:=oSeries;
  dSeries.CheckDataSource;

  Chart1.OnZoom:=ChartZoom;
  Chart1.OnUndoZoom:=ChartUndoZoom;

  CalcTolerance;
end;


procedure TForm1.ChartZoom(Sender: TObject);
begin
  CalcTolerance;
end;

procedure TForm1.ChartUndoZoom(Sender: TObject);
begin
  CalcTolerance;
end;

procedure TForm1.CalcTolerance;
begin
  dFunc.Tolerance:=1;
  Chart1.Draw;

  if dSeries.Count>0 then
    while (Chart1.ChartRect.Right-Chart1.ChartRect.Left) div (dSeries.LastDisplayedIndex-dSeries.FirstDisplayedIndex) < 5 do
    begin
      dFunc.Tolerance:=dFunc.Tolerance+1;
      dSeries.CalcFirstLastVisibleIndex;
    end;

  Caption:=FormatFloat('#,##0', dFunc.Tolerance);
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

Errol
Newbie
Newbie
Posts: 35
Joined: Mon Jul 02, 2018 12:00 am

Re: Displaying Dashed Lines with data-dense series

Post by Errol » Tue Sep 04, 2018 2:35 am

Good morning
Thanks for your suggestion. I will certainly try this although I cannot get your code to work because of some conflict between VCLTee.TeCanvas and TeCanvas which I do not understand. Here is the error I get when trying to run the test program attached. I appreciate your assistance here.

[dcc32 Error] TeCanvas.pas(5692): E2010 Incompatible types: 'VCLTee.TeCanvas.TTeeCanvas' and 'TeCanvas.TTeeCanvas'
[dcc32 Error] TeCanvas.pas(8496): E2010 Incompatible types: 'TTeeCanvas' and 'TTeeCanvas3D'

However, I still expect that a FastLine series should draw an evenly-spaced dotted, dashed or dot-dashed line regardless of the number of data points, and without having to write extra code. If you wish to retain the behaviour of the current FastLine series, then perhaps a new series (FastLineX or similar) could be introduced to satisfy user expectations. Can this be introduced as a new feature?

Best regards

Errol
Attachments
DownSampling.zip
(52.98 KiB) Downloaded 237 times

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

Re: Displaying Dashed Lines with data-dense series

Post by Yeray » Tue Sep 04, 2018 8:10 am

Hello,
Errol wrote:
Tue Sep 04, 2018 2:35 am
some conflict between VCLTee.TeCanvas and TeCanvas which I do not understand
Please make sure the "VCLTee" prefix is present in the "unit scope names" in the project options or the IDE options.
Errol wrote:
Tue Sep 04, 2018 2:35 am
However, I still expect that a FastLine series should draw an evenly-spaced dotted, dashed or dot-dashed line regardless of the number of data points, and without having to write extra code. If you wish to retain the behaviour of the current FastLine series, then perhaps a new series (FastLineX or similar) could be introduced to satisfy user expectations. Can this be introduced as a new feature?
Yes, it could be controlled by a new property in the TFastLineSeries. Or, as you suggest, if a new series type if the TFastLineSeries performance is affected by this addition.
Please, confirm if the code I suggested above works as you expected so I can open a detailed ticket in our public tracker
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

Errol
Newbie
Newbie
Posts: 35
Joined: Mon Jul 02, 2018 12:00 am

Re: Displaying Dashed Lines with data-dense series

Post by Errol » Wed Oct 03, 2018 5:02 am

Hello
Thank you for your suggestions in the previous post and apologies for the long delay before replying.
I have implemented the down-sampling code in the attached project, but it does not work as well as hoped. Values are omitted, so that the down-sampled line does not match the measured line. Also for a noisy line (the WHP series) the procedure seems to omit all points except for the first and one other. I would be grateful for assistance with this as I do not adequately understand the downsampling procedure.
I still feel the down-sampling procedure is likely to be time-consuming for series with many data points. Already I have to generate a point series and a fastline series to be able to have the required control on point display - I do not wish to generate another series for the downsampling procedure. With up to 20 series each with 20,000 points, there is an impact on graph drawing speed.
I presume the fastline series draws the specified line type from data point to data point. Ii is not clear to me why it has to re-start the line type at each data point. I hope Steema can modify the fastline series so that the dash intervals are dependent only on the path length, and ignore the occurrence of a point in the path.
I look forward to your comments
Best regards
Errol
Attachments
DownSampling2.zip
DownSampling project
(110.13 KiB) Downloaded 219 times

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

Re: Displaying Dashed Lines with data-dense series

Post by Yeray » Thu Oct 04, 2018 10:21 am

Hello,

There is also the option to draw the line/fastline series as a polyline. This can be done setting the DrawStyle property to flAll (flSegments is the default). However, as you can see in this simple example doesn't solve the problem:
Project3_2018-10-04_11-57-19.png
Project3_2018-10-04_11-57-19.png (65.16 KiB) Viewed 5812 times

Code: Select all

uses Series, TeeDownSampling;

var dFunc: TDownSamplingFunction;
    dSeries: TFastLineSeries;

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

  Chart1.Axes.Left.EndPosition:=33;
  Chart1.Axes.Left.Title.Caption:='Original';

  with Chart1.CustomAxes.Add do
  begin
    StartPosition:=33;
    EndPosition:=66;
    LabelsFont.Assign(Chart1.Axes.Left.LabelsFont);
    Title.Font.Assign(Chart1.Axes.Left.Title.Font);
    Title.Caption:='DrawStyle=flAll';
  end;
  with Chart1.CustomAxes.Add do
  begin
    StartPosition:=66;
    LabelsFont.Assign(Chart1.Axes.Left.LabelsFont);
    Title.Font.Assign(Chart1.Axes.Left.Title.Font);
    Title.Caption:='DownSampling';
  end;

  for i:=0 to 2 do
  begin
    with Chart1.AddSeries(TFastLineSeries) as TFastLineSeries do
    begin
      if i=0 then
        FillSampleValues(10000)
      else
      begin
        DataSource:=Chart1[0];
        CustomVertAxis:=Chart1.CustomAxes[i-1];
        Color:=Chart1[0].Color;

        if i=1 then
          DrawStyle:=flAll
        else if i=2 then
        begin
          dSeries:=Chart1[i] as TFastLineSeries;
          dFunc:=TDownSamplingFunction.Create(Self);
          dFunc.DownSampleMethod:=dsAverage;
          dSeries.SetFunction(dFunc);
        end;
      end;

      Pen.Style:=psDash;
    end;
  end;

  CalcTolerance;
end;

procedure TForm1.CalcTolerance;
begin
  dFunc.Tolerance:=1;
  Chart1.Draw;

  if dSeries.Count>0 then
    while (Chart1.ChartRect.Right-Chart1.ChartRect.Left) div (dSeries.LastDisplayedIndex-dSeries.FirstDisplayedIndex) < 5 do
    begin
      dFunc.Tolerance:=dFunc.Tolerance+1;
      dSeries.CalcFirstLastVisibleIndex;
    end;

  Caption:='DownSampling Tolerance: ' + FormatFloat('#,##0', dFunc.Tolerance);
end;
The problem is when you have points so close that there isn't space between them to draw a line and a leave a white space (to have a dash). The only way around I can think on is by reducing the number of points... and thus loosing some precision.
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

Errol
Newbie
Newbie
Posts: 35
Joined: Mon Jul 02, 2018 12:00 am

Re: Displaying Dashed Lines with data-dense series

Post by Errol » Mon Oct 15, 2018 2:54 am

Good afternoon
I seem to have solved the problem of displaying dashed line with data-dense series, and that is to use a Line Series rather than a Fast Line Series, and to set DrawStyles to dsAll and Pointer.Visible to False. See attached DashedLines example program. I then use a Point series to draw points at a user-defined density.
I am surprised that a line series has the capability of displaying dashed lines independent of the data density, whereas a Fast Line Series cannot do this. Intuitively, I would have expected the opposite to be true, but I appreciate there is a solution.
My (hopefully final) question is this. Will the chart drawing be significantly slower using Line Series rather than Fast line Series, assuming say 10 series on a graph each with 10,000 data points (but perhaps only 10 points/symbols drawn per series)?
I look forward to your comments.
Best regards
Errol
Attachments
DashedLines.zip
(102.01 KiB) Downloaded 228 times

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

Re: Displaying Dashed Lines with data-dense series

Post by Yeray » Wed Oct 17, 2018 12:08 pm

Hello,

I believe you missed to include the .pas.

I've done some tests with this simple example and the application needs about 122ms to repaint using TLineSeries vs about 78ms using TFastLineSeries:

Code: Select all

uses Series, Diagnostics;

const nValues=10000;
      nPoints=10;

var Stopwatch: TStopwatch;
    tmp1, tmp2: Double;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
  tmp1:=Stopwatch.Elapsed.TotalMilliseconds;
  tmp2:=Stopwatch.Elapsed.TotalSeconds;

  if Stopwatch.Elapsed.TotalSeconds>1 then
     Caption:=FormatFloat('#,##0.##', Stopwatch.Elapsed.TotalSeconds)+'s'
  else
     Caption:=FormatFloat('#,##0.##', Stopwatch.Elapsed.TotalMilliseconds)+'ms';
end;

procedure TForm1.Chart1BeforeDrawChart(Sender: TObject);
begin
  Stopwatch := TStopwatch.StartNew;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i, j: Integer;
    diff: Double;
begin
  Chart1.View3D:=False;
  Chart1.Legend.Hide;
  Chart1.Title.Hide;
  Chart1.Hover.Visible:=False;

  (Chart1.AddSeries(TPointSeries) as TPointSeries).Pointer.Size:=2;

  diff:=nValues/nPoints;

  for i:=0 to 9 do
  begin
    Chart1.AddSeries(TLineSeries).FillSampleValues(nValues);
    //Chart1.AddSeries(TFastLineSeries).FillSampleValues(nValues);

    j:=0;
    repeat
      Chart1[0].AddXY(j*diff, Chart1[Chart1.SeriesCount-1].YValue[round(j*diff)], '', Chart1[Chart1.SeriesCount-1].Color);
      Inc(j);
    until (j*diff>=nValues);

  end;

  Chart1.ExchangeSeries(0, Chart1.SeriesCount-1);
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

Errol
Newbie
Newbie
Posts: 35
Joined: Mon Jul 02, 2018 12:00 am

Re: Displaying Dashed Lines with data-dense series

Post by Errol » Wed Oct 31, 2018 3:36 am

Hi Yeray

Thanks for the tests. I think I can live with the slower paint time. Such big data sets are reasonably rare. I have attached the Dashed Lines project, this time with the missing .pas file, just in case anyone wants to review it.
Best regards
Errol
Attachments
DashedLines.zip
(204.28 KiB) Downloaded 219 times

Post Reply