Thursday, February 21, 2013

Rotatable 3D surface plot

Yesterday a customer asked me how to create a quick and dirty solution for displaying a rotatable three dimensional surface (using ChartPack). Here's the solution to it (for sake of clarity I use predefined data stored in the 12 by 14 array "Data"):
  1. Put the TPlot3D component on a form
  2. In the OnShow event add the following code:
        // suppress any redraw during the
        // construction of the plot
    P3d.SuppressPaint := true; 
        // adjust the data grid of the component 
    P3d.GridMat.Resize(14,12);  
        // fill the data grid
    for i:=1 to 14 do
      for j:=1 to 12 do
        P3d.GridMat[i,j] := Data[i,j];  
        // set the scales of the axes
    P3D.SetRange(1,14,1,12,0,35);  
        // this triggers a repaint
    P3d.SuppressPaint := false;    
    
  3. In the object inspector set the color model ("ColorCodingMode") to "cmThreeColors", the range of colors to a range of 0 to 35 (properties "ColorScaleLow" and "ColorScaleHigh"), and of course, the pivot colors ("ColorLow", "ColorMid", and "ColorHigh") according to your requirements.
As a small refinement I added a scrollbar which allows to adjust the property "ColorScaleHigh". Following is a screen shot of the mini demo:

You can download the sample program written for Delphi XE3 from here. The ZIP file contains the sources and the corresponding executable for Windows. In order to rotate the 3D plot simply click into the chart and drag the mouse holding the left mouse button down.

Monday, January 14, 2013

Reentrancy of events

Not very long ago, I encountered a weird situation which took lots of time to resolve (yes, call me stupid): a measurement device delivered data to my program at irregular intervals by triggering an event which took the new value, added it to a FIFO structure and redrew the corresponding graph.

This worked nice, however, every now and then parts of the drawing disappeared (I used RChart for displaying the graph). The problem was, of course, that the glitch occurred only infrequently, so debugging was in fact almost impossible (how can you the detect the condition of not drawing parts of a graph?).

In such situations, I did what I call "debugging by meditation" (;-): I slept over it, hoping that my brain finds a solution while being asleep.....

And the solution was simple enough: the event to redraw the graph was called a second time before the previous call had been finished (re-entrant call), clearing parts of the graph. So I simply created the following program structure to block re-entrant calls of the drawing routine:


var
  IsProcessing: boolean; // (private variable of the form)

...
...
...

procedure OnDataTrigger (Sender: TObject; newdat: double);

begin
.... // collect the data (not shown here)

if not Processing then
  begin
  IsProcessing := true;

  .... // display the data

  IsProcessing := false;
  end;
end;
... and the glitches were gone!

A final remark: in my case it was a little bit more complicated, because of additional restrictions of the measurement device. So I used the event to collect the data in an array and called the drawing routine only when enough data were available...

Yes, and the very last remark: do not forget to initialize the "IsProcessing" variable to FALSE.

Thursday, January 10, 2013

Lifetime of Older Delphi Versions

Did you ever wonder how long it takes that most of the users of an older Delphi version switch to the newer one?

Well, this question could be answered simply by looking at the sales figures of Embarcadero; however I doubt that Embarcadero will make the sales figures available to the public. An idea to get some insight to this question would be to exploit the search statistics of Google. These numbers are publicly available (at least the relative numbers) and certainly provide an indication of how many people are (still) working with a particular version of Delphi.

Here are the results of this approach (the data points are weekly averages scaled to a maximum of 100%):

So what I did, was to visit Google Trends, enter the following keywords, and download the data provided by Google. Search keywords: "Delphi 2009", "Delphi 2010", "Delphi XE", "Delphi XE2", and "Delphi XE3".

The results clearly show that the decay of a particular search keyword immediately starts after the launch of a new release. The interest in the old release drops within a few months to half of the initial interest. Only Delphi 2010 needed almost a year to drop to 50% - which may be an indication that the move to XE was judged excessively cautious by the users.