Displaying Dashed Lines with data-dense series
Displaying Dashed Lines with data-dense series
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. 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. 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
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. 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. 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
Re: Displaying Dashed Lines with data-dense series
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:
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,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Displaying Dashed Lines with data-dense series
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
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 1068 times
Re: Displaying Dashed Lines with data-dense series
Hello,
Please, confirm if the code I suggested above works as you expected so I can open a detailed ticket in our public tracker
Please make sure the "VCLTee" prefix is present in the "unit scope names" in the project options or the IDE options.
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.Errol wrote: ↑Tue Sep 04, 2018 2:35 amHowever, 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?
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,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Displaying Dashed Lines with data-dense series
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
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 1037 times
Re: Displaying Dashed Lines with data-dense series
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:
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.
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:
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;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Displaying Dashed Lines with data-dense series
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
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 1055 times
Re: Displaying Dashed Lines with data-dense series
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:
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,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Displaying Dashed Lines with data-dense series
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
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 1079 times