Drawing Graphs

Drawing Graphs

18 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Yep, Scigraph is for QuickWin only; I'm not familiar with ArrayViewer so I'll leave it to others to comment.

On the other hand, my XFTGDI lite contains a sample on how to draw in a dialog. (It uses modified DFLOGM as a base, but you can easily adapt it for a Win32 handled dialog, since XFTGDI is compatible with it -- just insert an owner-drawn static control, and handle WM_DRAWITEM -- see XFLOGM.f90 for the code).

Unfortunately, XFTGDI supports only primitives, i.e. you'll have to draw your own graph from lines & characters. SciGraph port to XFTGDI is supposed to be undergoing, but I'll have to check with its developer about its status; I'll get back with an update if it's anywhere near completion.

Jugoslav

Jugoslav
www.xeffort.com

Have you looked at the AnimWin32 sample? That sample illustrates using the Avis2D control in a dialog.

John

I've looked at that sample and my head starts spinning around. I've only learnt the basics so far and now Im really stuck. I don't quite get which parts are used to get the array viewer to work in the dialog or allocate array values to it. The program Im working on uses a calculation subroutine where the array values are calculated and then displayed(The part Im stuck on). Im presuming that I need the Avis2d.f90 file but don't know how to link the file to my program and what it actually does. What other files do i need to include? Can I copy some of the subroutine codes to get the viewer displayed and working such as the initialize and destroy one? Is there a simpler example of the array viewer in a win32 dialog program without the animated array. Maybe a plain dialog which will display a static array. I've attached my program files to the point where whatever I do messes up. Any help would be greatly apprieciated.

Dave

I don't have time to update your application to use the Avis2D control, but I can give you a quick run-through of the steps you need to hook up the control...

When you create a new Win32 Fortran project, be sure you check the "Use ActiveX" checkbox in the wizard. I think all this does is add the line:
call COMINITIALIZE(ret)
in the startup code. If you have an existing project, make sure that line is there.

In the resource editor right click on the dialog and select "Insert ActiveX Control". Choose the Avis2D control. And insert it into the dialog.

The Avis2D.f90 file provides a fortran interface to the control properties, methods, and events. You can create it using the module wizard, or just copy the one from the AnimWin32 sample into your project.

To get a handle to the avis2d control, use the DlgGet routine, e.g.: lret = DlgGet( gdlg, IDC_AVIS2DCTRL1, hAvis2D1, DLG_IDISPATCH )

You can then use the handle (hAvis2D1) to set properties in the control using AUTOSetProperty. One important property you'll want to set is FileName. In this scenario, the FileName isn't really a file on the disk but a special string that lets the control know where to find the array data.

For the array you want to view, you'll need to call faglStartWatch, e.g.:

faglStartWatch(myArray, status)

Then you'll need to call faglGetShareName to get the string identifier for the array. e.g:

call faglGetShareName(myArray, sharename, status)

Then pass the string to the FileName property:

AUTOSetProperty(hAvis2D1, "FileName", sharename)

That should do it!

If the array is modified and you want to refresh the control view, you'll need to call:

call faglUpdate(myArray, status)

followed by:

call $DAvis2D_Update(hAvis2D1, ret)

to let the control know to redraw itself.

I hope your head is no longer spinning! Write back if you have other questions.

John

Hi John

Thanks for the instructions on adding the array viewer to a program. At the moment Im getting two errors and don't know why. So far I have added the Avis2D.f90 file to the source file folder and added the following lines to the program:
(in WinMain)
use Avis2D
call COMINITIALIZE(ret)

(in the Subroutine called by a button press)
use Avis2D
DIMENSION TP(100)
logical*4 status
character sharename
integer*4 ret
logical*4 lret

lret = DlgGet( gdlg_tab1, IDC_AVIS2DCTRL1, hAvis2D1, DLG_IDISPATCH )

call faglStartWatch(TP(100), status)

call faglGetShareName(TP(100), sharename, status)

ret = AUTOSetProperty(hAvis2D1, "FileName", sharename)

I get two errors reported which are:
C:WINDOWSDesktopTorstiffSHOWFONT.f90(1209) : Error: There is no matching specific function for this generic function reference. [DLGGET]
lret = DlgGet( gdlg_tab1, IDC_AVIS2DCTRL1, hAvis2D1,
-------^
DLG_IDISPATCH )
C:WINDOWSDesktopTorstiffSHOWFONT.f90(1215) : Error: There is no matching specific function for this generic function reference. [AUTOSETPROPERTY]
ret = AUTOSetProperty(hAvis2D1, "FileName", sharename)
------^

Does it matter that the activeX control is displayed in a tab ? Should status be altered to integer(4)? Have i missed out alot of information that needs to be included such as the avis2D setup properties that are in the anim32 demo?

Cheers for the help.

Dave

To fix the second error, try changing the declaration for sharename to:

character(AV_SHARENAME_LEN) sharename

Not sure about the first error. What's the declaration for hAvis2D1?

John

Hi John

The previous errors are now ok. I used
Character status
integer hAvis2D1

The program now gets errors on linking due to these lines

call faglStartWatch(TP(100), status)

call faglGetShareName(TP(100), sharename, status)

Here's the error message that comes up.

Linking...
Creating library Debug/showfont.lib and object Debug/showfont.exp
SHOWFONT.obj : error LNK2001: unresolved external symbol _FAGLSTARTWATCH@8
SHOWFONT.obj : error LNK2001: unresolved external symbol _FAGLGETSHARENAME@16
Debug/showfont.exe : fatal error LNK1120: 2 unresolved externals
Error executing link.exe.

showfont.exe - 3 error(s), 0 warning(s)

Is there any declarations or lines Im missing to get the two calls to work? Also, what extra files do I need to incorporate into the program folder? I know that the Array Viewer dll files must be in the systems folder but is there anything else?

Cheers again

Dave

Do you have Array Visualizer installed?

You need to link against ArrayVisualizerLIBAVIEW160.LIB

Steve

Steve - Intel Developer Support

I do have the Array Visualizer installed. How do you link against ArrayVisualizerLIBAVIEW160.LIB ?

Dave

It should happen automatically if you USE AVDEF.

Steve

Steve - Intel Developer Support

Hi,
I was paying close attention to this discussion for a little while as I was in the same predicament as loadpoint at the exact same time (i.e., little experience but needed a graph, couldn't figure it out, etc.). I've learned a lot from the discussion and things are working out for me, so far. However, I've now run into a problem which hopefully someone can help me solve.

My application was a prebuilt simulation that was originally designed to run in a command window. My goal has been to bring that code into Win32 and make it produce a dialog with a dynamic graph that plots some parameters of interest to the users. (It runs long enough that the users get antsy when they don't see something happening immediately). I want to do this without slowing down the original code at all which means not using a timer and the RndrPass event. Thanks in large part to this message thread, the window and graph are up and running essentially as I had intended. The graph constantly updates itself with negligible run-time impact to the original code. The one annoyance is that the axes on the graph don't update until the entire simulation is complete, which defeats the purpose of the graph if users can't read the graph until it is complete.

Is there a way to get the axes to update at the same rate as the graph?

If it helps any, I also have an edit box on the dialog that also refuses to update...grr. :)

Thanks,
Stuart

Well, few disclaimers: I 1) wasn't paying close attention to this discussion 2) I'm not familiar with AV and 3) Not familiar with OpenGL either, but I think I can offer few guidelines:

I think that what you observe is consequence that during the heavy computation, your single-threaded program cannot update its display because it's stuck in computation. What happens if, during the run, you switch to another application and then back to yours? My guess is that you'll see just a grey rectangle, possibly with graph updating.

Now, how it comes that the graph is updated but nothing else is? I don't know (due to disclaimer 2). Either AV uses a separate thread for updating or perhaps uses OpenGL in the background (due to disclaimer 3 I don't know whether OpenGL is independent of Windows' message processing). But, regardless of the graph, I know that the rest is not updated because there's no active message loop to do it.

As an illustration, see my ThreadDlg sample. Download the workspace and try it; then, replace the CreateThread line with a plain function call -- see?. I believe that the behaviour will match yours.

So, a solution appears to be one of:
1) Create a separate thread for calculation. Since your code is probably more complicated than ThreadDlg, there may be synchronization issues.

2) Call a message loop every while from the calculation, like:

SUBROUTINE ProcessMessages(Dlg)
USE DFWIN
USE DFLOGM
TYPE(T_MSG):: Msg
TYPE(DIALOG):: Dlg
DO WHILE (PeekMessage(Msg, 0, 0, 0, PM_REMOVE)
   IF (.NOT.IsDialogMessage(Dlg%hWnd, Msg)) THEN
      i = TranslateMessage(Msg)
      i = DispatchMessage(Msg)
   END IF
END DO

HTH
Jugoslav

Jugoslav
www.xeffort.com

Thanks for the reply jugoslavdujic! You are correct in your assumption that AV updates the graph in a separate thread. This is why the graph updates properly during the computation process. I just assumed that the graph axes would also update in that same thread, but it doesn't seem to work that way. Strange but true!

I appreciate your suggestion to launch a separate thread for the computational process, and I did consider that at one point, but thought it might be going a bit far for this situation. Perhaps I'll revisit it now that you have suggested it. Since my post, I have started using DlgFlush() which forces the dialog to update, so long as I put in a while loop like the one you included in your reply. The problem, of course, is that this while loop slows down the computational process, which is why the separate thread is starting to sound like a good idea again!

Thanks,
Stuart

Loadpoint started his question with "Is there any good tutorials for complete beginners out there ?"
Problem is that you'll find a lot of examples and packages doing the job partly, after which you'll get stuck in additional requirements. If you need complex graphical output more often, forget Array Viewer and QuickWin and opt for Win32 right away. Some examples may be found in ...DF98SamplesAdvancedWin32 but see also Norman Lawrence: Compaq Visual Fortran and his complete download projectsources. Even then still a lot to find out ! Want to exchange experiences and demosources ? Mail me. Applies for others looking for a graphics/Win32 solution too. After debugging we put them back on the Intel/CVF Community. DaVinci

Stuart is correct in that the control does the graphics rendering in a separate thread. This allows the user's application to be responsive even when the control is busy rendering a very complex plot. Now that Hyperthreading processors are becoming more widely available this should result in a performance boost as well.

Creating a separate thread for applications that are doing long-running computations is a good idea in general. Your primary thread can deal with user interaction while a worker thread does the heavy lifting. Of course writing multi-threaded applications is more work and can lead to hard to find bugs, so there are some drawbacks too.

Regarding the axis updating, the control is written to finish the current render before "noticing" that the axis parameters has changed. It should then go back and re-render the graph with the new settings. If you are not seeing this, try throwing in a call to the Update() method and see if that helps.

Davinci has a good point in that using Win32 GDI gives you the most flexability in creating the graphical output for your program. Tools like Array Visualizer can't anticipate every user requirement. We are just trying to provide a way for developers to display typical graphs without a lot of work on their part.

John

Thanks for all your input and clarifications! I've got something working that will do for now. The effort was basically a "proof of technology," so it doesn't have to be polished just yet.

Stuart

I don't think that the message loop will significantly affect the performance (but i do think that the thread is a better idea).

Attached is a small test .exe derived from ThreadDlg; it runs a heavy calculation (really) in four ways: plain function call, CreateThread without update, with update and with increased thread priority. All yield similar times on my Win2k computer (but I didn't test ProcessMessages approach). The reason I made it is that I was reported by a Win98 user that spawning a thread (in his own code) approach is twice as long as plain function call; unfortunately, I didn't receive feedback whether it was his error or just Win98. So, if your target system is Win9x, I recommend you test it before coding.

Luckily, Win9x is going to disappear from the Earth's face some time in the future ;-)

Jugoslav

Jugoslav
www.xeffort.com

Leave a Comment

Please sign in to add a comment. Not a member? Join today