Page 1 of 1

[SOLVED] Contour not drawing correctly

Posted: Thu Mar 24, 2011 12:11 pm
by 16458158
I have a simple project using TeeChart Pro VCL in Embarcadero C++ Builder XE. In this project I populate a Contour chart using values in a StringGrid. Problem is that sometimes the contour draws incorrectly. I have tried dozens of different approaches so far, but nothing seems to help.

I attached an image which shows the incorrectly drawn screen capture (left one) and correctly drawn (right one):
contourtest.png
contourtest.png (42.43 KiB) Viewed 18412 times
Here is the code that draws the contour:

Code: Select all

void TForm1::Draw()
{
   double seriesDefaultValue = 0.0;

   // Remove default/old entries from series
   for (int i = 0; i < Series1->Count(); i++) {
      Series1->Delete(i);
   }

   // Fill Series with StringGrid1 data
   for (int rowIdx = 0; rowIdx < StringGrid1->RowCount; rowIdx++) {
      for (int colIdx = 0; colIdx < StringGrid1->ColCount; colIdx++) {
         Series1->AddXYZ(colIdx, verifyDouble(StringGrid1->Cells[colIdx][rowIdx], &seriesDefaultValue), rowIdx);
      }
   }
}

double TForm1::verifyDouble(UnicodeString input, double* defaultValue) {
   if (input == "") {
      return *defaultValue;
   }

   return input.ToDouble();
}

Re: Contour not drawing correctly

Posted: Mon Mar 28, 2011 10:11 am
by yeray
Hello kville,

I'm trying to reproduce it with the following code but I'm always obtaining something similar to your right image with TeeChart Pro v2010.02.

Code: Select all

uses TeeSurfa;

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

  series:=Chart1.AddSeries(TContourSeries) as TContourSeries;
  series.Brush.Style:=bsSolid;
  series.Pen.Visible:=false;
  series.UseColorRange:=false;
  series.UsePalette:=true;
  series.PaletteStyle:=psRainbow;

  series.AddXYZ(0,5.157,0);
  series.AddXYZ(0,5.155,1);
  series.AddXYZ(0,5.157,2);
  series.AddXYZ(0,5.157,3);

  series.AddXYZ(1,5.157,0);
  series.AddXYZ(1,5.154,1);
  series.AddXYZ(1,5.156,2);
  series.AddXYZ(1,5.154,3);

  series.AddXYZ(2,5.153,0);
  series.AddXYZ(2,5.157,1);
  series.AddXYZ(2,5.153,2);
  series.AddXYZ(2,5.154,3);

  series.AddXYZ(3,5.157,0);
  series.AddXYZ(3,5.157,1);
  series.AddXYZ(3,5.155,2);
  series.AddXYZ(3,5.154,3);
end;
Could you please modify the code above or arrange a simple example we can run as-is to reproduce the problem here?
Thanks in advance.

Re: Contour not drawing correctly

Posted: Tue Mar 29, 2011 4:28 am
by 16458158
I have a sample C++ builder project that I could send to you, but I do not know where or how it should be uploaded.

Re: Contour not drawing correctly

Posted: Tue Mar 29, 2011 6:58 am
by yeray
Hello kville,

You can either post your files at news://www.steema.net/steema.public.attachments newsgroup, at our upload page or directly here in the support forums as a message attachment.

Re: Contour not drawing correctly

Posted: Tue Mar 29, 2011 7:21 am
by 16458158
I attached the sample project + exe for testing. To reproduce the problem you have to populate grid cells (cells are populated by double clicking them) in specified order explained below:

Code: Select all

 
1   2    3    4
8   7    6    5
16  15   14   13
9   10   11   12
The Chart can be corrected (after populating it fully) by clicking the re-draw button three times. The re-draw button executes exactly same draw function that is executed by double clicking a grid cell.

Re: Contour not drawing correctly

Posted: Wed Mar 30, 2011 10:31 am
by yeray
Hello,

It's quite strange. I can reproduce it with your application but not if I load all the values at a time:

Code: Select all

uses Chart, TeeSurfa;

procedure TForm1.FormCreate(Sender: TObject);
var Chart1: TChart;
    Series1: TContourSeries;
    x, z: Integer;
    tmp: double;
const
    values: array[0..3,0..3] of double = ((5.157, 5.157, 5.157, 5.153),
                                          (5.155, 5.154, 5.157, 5.157),
                                          (5.157, 5.156, 5.155, 5.153),
                                          (5.157, 5.154, 5.154, 5.154));
begin
  Chart1:=TChart.Create(self);
  Chart1.Parent:=self;

  Chart1.Align:=alclient;
  Chart1.View3D:=false;
  Chart1.MarginBottom:=0;
  Chart1.Margintop:=0;
  Chart1.MarginLeft:=0;
  Chart1.MarginRight:=0;
  Chart1.Axes.Visible:=false;
  Chart1.Axes.Left.Inverted:=true;
  Chart1.Legend.Visible:=false;

  Series1:=Chart1.AddSeries(TContourSeries) as TContourSeries;
  Series1.UseColorRange:=true;
  Series1.StartColor:=clRed;
  Series1.MidColor:=clYellow;
  Series1.EndColor:=RGB(2, 190, 253);
  Series1.Brush.Style:=bsSolid;
  Series1.Pen.Visible:=false;

  for x:=0 to 3 do
    for z:=0 to 3 do
    begin
      tmp:=values[x,z];
      Series1.AddXYZ(x, tmp, z);
    end;
end;

Re: Contour not drawing correctly

Posted: Thu Mar 31, 2011 6:29 am
by 16458158
Our application must be populated one by one, so this will not solve the problem.

EDIT:
In fact my application loads all values too, the ones not clicked are filled with default value. So actually the chart will always contain as many values as there are cells in the grid. Only difference between my and your approach seems to be the fact that I use StringGrid as source and you use an array.

It also seems strange that the chart is drawn correctly to the point when the last cell is clicked. And that calling the same Draw method few times again, corrects the chart.

Re: Contour not drawing correctly

Posted: Fri Apr 01, 2011 11:12 am
by narcis
Hi kville,

I see two big differences between your application and Yeray's:

1. Your application has zero values after plotting all cells while Yeray's doesn't.
2. Yeray's application has a grid-like structure while yours has a more irregular structure. Here I explained how such series should be populated.

Both examples have different data so output won't be identical. I attach 3 Excel files with the data in your series, your application after clicking ReDraw several times and Yeray's. You'll clearly see the differences I describe above.

Having seen that, I think your code may not be doing what you expected with your data, it doesn't plot the StringGrid structure which is seen on screen. My suggestion would be to rework your code so that it populates the series in a similar structure as Yeray's it should be able to be plotted in two nested for loops.

Also, something that enhances the output a little bit is changing the default value, for example:

Code: Select all

   double seriesDefaultValue = 5.150;//0.0;

Re: Contour not drawing correctly

Posted: Thu Apr 07, 2011 6:55 am
by 16458158
1. Actually the problem only occurs when I do not have any zero values anymore on the grid. The chart plots just fine until the last zero value is changed to non zero value and the chart is cleared and populated with values from the fully populated stringgrid.

2. Before posting here I had already tried setting the IrregularGrid property to true (among many other properties found here in this forum), but it did not correct the problem.
Having seen that, I think your code may not be doing what you expected with your data, it doesn't plot the StringGrid structure which is seen on screen. My suggestion would be to rework your code so that it populates the series in a similar structure as Yeray's it should be able to be plotted in two nested for loops.
I do not understand your point about me not populating the chart with nested loops as that is exactly what I do as shown also in the code sample in the first post:

Code: Select all

// Fill Series with StringGrid1 data
for (int rowIdx = 0; rowIdx < StringGrid1->RowCount; rowIdx++) {
   for (int colIdx = 0; colIdx < StringGrid1->ColCount; colIdx++) {
      Series1->AddXYZ(colIdx, verifyDouble(StringGrid1->Cells[colIdx][rowIdx], &seriesDefaultValue), rowIdx);
   }
}
What comes to setting the seriesDefaultValue to something closer to the populated values is not an option. My sample application is a simplified version of the real application and intended to only demonstrate the problem for you. In the real application every stringgrid cell gets its value from a measuring device (another piece of hardware/software, also an probe is physically transferred from one place to another between double clicking the stringgrid cells) and that value can be virtually any positive number including zero value. Actually your suggestion for enhancing the output does just the opposite in this case.

Re: Contour not drawing correctly

Posted: Thu Apr 07, 2011 8:54 am
by narcis
Hi kville,
I do not understand your point about me not populating the chart with nested loops as that is exactly what I do as shown also in the code sample in the first post:
Not quite, please check out the spreadsheets I attached in my previous post. You'll see your chart is not populating the series in a grid fashion. It doesn't necessarily need to be with nester for loops but it should have a grid alike structure.

Thanks in advance.

Re: Contour not drawing correctly

Posted: Thu Apr 07, 2011 9:47 am
by 16458158
Thank you for the Excel files, they were really helpful for pointing out why the population was unsuccessful. I actually thought that the chart was populated with 16 (4x4 grid) values all the time and did not suspect that the data corrupted such way.

Further investigation showed that the following code did not empty the series correctly (do you have any idea why?):

Code: Select all

// Remove default/old entries from series
for (int i = 0; i < Series1->Count(); i++) {
   Series1->Delete(i);
}
I replaced it with this:

Code: Select all

Series1->Clear();
The reason that I used the Delete was that earlier I could not get the Clear method to work. I think this was caused by the default C++ Builder options (Paths and Directories) being wrong. I corrected this later in the development to correct another problem and never understood that it could affect the Clear method also.

Re: Contour not drawing correctly

Posted: Thu Apr 07, 2011 10:35 am
by 16458158

Code: Select all

// Remove default/old entries from series
for (int i = 0; i < Series1->Count(); i++) {
   Series1->Delete(i);
}
Answering for myself, the above will not work because if index 0 is deleted index 1 will become new index 0.

Re: Contour not drawing correctly

Posted: Thu Apr 07, 2011 10:42 am
by narcis
Hi kville,
Thank you for the Excel files, they were really helpful for pointing out why the population was unsuccessful. I actually thought that the chart was populated with 16 (4x4 grid) values all the time and did not suspect that the data corrupted such way.
You're welcome. I'm glad to hear that helped.
Further investigation showed that the following code did not empty the series correctly (do you have any idea why?):

Code: Select all
// Remove default/old entries from series
for (int i = 0; i < Series1->Count(); i++) {
Series1->Delete(i);
}
This is a problem with series indices. As you remove a point indices change and so does Series1->Count(). It's easier to control using a while loop:

Code: Select all

	while (Series1->Count()>0){
		Series1->Delete(0);
	}