Michael Malak Posted May 12, 2009 Report Share Posted May 12, 2009 I am new to LabVIEW. I am trying to read in a file that has N channels, where N is somewhere between 1 and 64. I need to display each channel in its own graph (overlapping is not acceptable to the users). Thus, I would like to dynamically instantiate at run-time N instances of WaveGraph. How do I do this? I see that there is a VI called "Open VI Reference", but it requires as input what seems to me to be a physical path to the VI source. How can I use "Open VI Reference" to a built-in VI such as WaveGraph? And is there anything else I need to do to get it to be displayed on my VI's front panel? Quote Link to comment
mross Posted May 12, 2009 Report Share Posted May 12, 2009 QUOTE (Michael Malak @ May 11 2009, 05:08 PM) I am new to LabVIEW.I am trying to read in a file that has N channels, where N is somewhere between 1 and 64. I need to display each channel in its own graph (overlapping is not acceptable to the users). Thus, I would like to dynamically instantiate at run-time N instances of WaveGraph. How do I do this? I see that there is a VI called "Open VI Reference", but it requires as input what seems to me to be a physical path to the VI source. How can I use "Open VI Reference" to a built-in VI such as WaveGraph? And is there anything else I need to do to get it to be displayed on my VI's front panel? Michael, It sounds as if you want to display 64 graphs simultaneously. From a usability POV that is not a great idea. You could instead choose what you think is a reasonable number of graphs to show at one time, like four for instance. Then you can change which of the data channels you want to show in each one. It would also be possible to have multiple channels overlaying in the same graph, four graphs of eight channels (this is surpassing what I would call usable also). One graph with eight channels overlaid would be useful and very doable. Also you talk about reading a "file with 1 to 64 channels of data. I interpret that to be a 64 x n array. You can do whatever you like with a static array of pre-existing data. Choose what data channel appears in what graph at any time. Choose how many graphs to put up and where - but you need to plan it out in detail. You do not want to be reconfiguring the front panel on the fly for a newbie VI. You can get lot's of good use from the Tab Control. You can put different numbers and size of graphs on as many tabs as you care to set up, and the user can choose the front panel look that suits their mood that way. Regarding "runtime, dynamic, instantiation." Imagine a front panel with four graphs (that way they are large enough for the user to resolve what they are seeing easily). Each graph has a control that turns on and off up to 8 channels (overlaying each other) and a corresponding channel selector. Each time you change a value the graph automatically updates withe the desired data channels. I suggest you learn to use the user event structure. Have it respond to Value Changes of the controls to turn on and off the traces and the channel selectors. It is not much more difficult that that in theory. You can also get lot's of extra functionality in the graphs with the use of the cursors. They will allow you to view up close sections of the data in the graph. If you post a data set, you can proabaly get some direct help from people that like to do this sort of thing. Mike Quote Link to comment
ShaunR Posted May 12, 2009 Report Share Posted May 12, 2009 QUOTE (Michael Malak @ May 11 2009, 10:08 PM) I am new to LabVIEW.I am trying to read in a file that has N channels, where N is somewhere between 1 and 64. I need to display each channel in its own graph (overlapping is not acceptable to the users). Thus, I would like to dynamically instantiate at run-time N instances of WaveGraph. How do I do this? I see that there is a VI called "Open VI Reference", but it requires as input what seems to me to be a physical path to the VI source. How can I use "Open VI Reference" to a built-in VI such as WaveGraph? And is there anything else I need to do to get it to be displayed on my VI's front panel? You used to be able to put graphs directly into arrays.I don't think you can anymore. But you can do this...... http://lavag.org/old_files/monthly_05_2009/post-15232-1242078686.png' target="_blank"> Put your graph into a cluster. Then put the cluster into an array. Quote Link to comment
Mark Yedinak Posted May 13, 2009 Report Share Posted May 13, 2009 QUOTE (ShaunR @ May 11 2009, 04:53 PM) You used to be able to put graphs directly into arrays.I don't think you can anymore. But you can do this...... http://lavag.org/old_files/monthly_05_2009/post-15232-1242078686.png' target="_blank"> Put your graph into a cluster. Then put the cluster into an array. You could but I would agree with mross. You need to think of what the user truly wants and design a user interface that meets those needs. Your suggestion while functional is actually looks rather unprofessional. Depending on the target audience this solution simply wouldn't do. Quote Link to comment
Michael Malak Posted May 13, 2009 Author Report Share Posted May 13, 2009 QUOTE (Mark Yedinak @ May 11 2009, 04:46 PM) You could but I would agree with mross. You need to think of what the user truly wants and design a user interface that meets those needs. Your suggestion while functional is actually looks rather unprofessional. Depending on the target audience this solution simply wouldn't do. I probably should have also included up front that I have 2-3 decades of non-LabVIEW experience and that the requirements for this project are well-defined and set in stone due to the existence of a previous application lineage with the same use interface in continuous use for the past 15 years. The suggested solution of an array of clusters of WaveGraphs is probably going to work for me, and actually answers directly the previous question I asked on the User Interface subforum here, which is why could I create an array of toggles, a cluster of WaveGraphs, but not an array of WaveGraphs. Quote Link to comment
Mark Yedinak Posted May 13, 2009 Report Share Posted May 13, 2009 QUOTE (Michael Malak @ May 11 2009, 06:21 PM) I probably should have also included up front that I have 2-3 decades of non-LabVIEW experience and that the requirements for this project are well-defined and set in stone due to the existence of a previous application lineage with the same use interface in continuous use for the past 15 years.The suggested solution of an array of clusters of WaveGraphs is probably going to work for me, and actually answers directly the previous question I asked on the User Interface subforum here, which is why could I create an array of toggles, a cluster of WaveGraphs, but not an array of WaveGraphs. Given that you are essentially rewriting this application you can use this as an opportunity to make improvements. Just because something has been done for 15 years doesn't mean that it can't be improved. I am not trying to be argumentative but simply suggesting that this is an opportunity to make improvements to your application. There is quite a bit to be gained from user interface improvements. Good design can help to clarify things, improve productivity, help eliminate errors and so forth. Whenever I have to go back and touch old code I look for ways it can be improved. That is all that I am saying. And for the record I also have several decades of software engineering experience. Quote Link to comment
mross Posted May 13, 2009 Report Share Posted May 13, 2009 QUOTE (Michael Malak @ May 11 2009, 07:21 PM) I probably should have also included up front that I have 2-3 decades of non-LabVIEW experience and that the requirements for this project are well-defined and set in stone due to the existence of a previous application lineage with the same use interface in continuous use for the past 15 years.The suggested solution of an array of clusters of WaveGraphs is probably going to work for me, and actually answers directly the previous question I asked on the User Interface subforum here, which is why could I create an array of toggles, a cluster of WaveGraphs, but not an array of WaveGraphs. Michael, You didn't ask for this, but I will give it anyway. I think it contains the ingredients of a better solution than 64 little graphs. There are other ways to do this, but this one is basic and shows how arrays are manipulated. The attached VI shows a way for you to overlay any of the 64 channels in one large graph. I made fake data in 24 rows of 40 data each. The rows are like your channels. All you need to do is wire your data array into the same input tunnel as my fake data. The UI lets you enter the channels and turn them on and off "on the fly." You could show all the channels at once, but that is clearly not useful. I show the data itself on the front panel so you can get some confidence that the senseless random data I generated is actually doing what I say it is. Array 2 is the same as the graphed data. On the block diagram the operation is quite simple. Starting from the inside out, the array is parsed using the delete from array function. An index of the desired channel is used to pull out the channel of interest (it is the I16 (16 bit integer) wired to the Index (row) input of the Delete from Array VI). The User Event Structure is triggered every time you enter a new channel or turn a channel on or off (for either it is a Value Change). You press the little LED to turn the channel on off, you enter a channel number from 0 to n in the numeric controls next to the LED (Boolean). When the event is triggered the for loop works its way through the channel array and the LED array element by element. Using the default values - Plot 0 is ON and the channel is #9 (the last one shown), Plot 1 is OFF, Plot 2 is ON and gets channel 1 (the channels start from channel 0). Notice the little square brackets inside the input tunnels of the channels and On/Off Boolean array's wires to the For Loop Structure. This is called auto-indexing. The loop automatically works its way through the array when this is set. (Input terminals with no brackets pass their arrays all at once.) On the first loop iteration channel 9 is indexed from the main array (auto indexing disabled for this one), placed into the build array function and passed to a shift register ( the little box with orange up/down arrow) of the For Loop. On the second iteration the Boolean is false (OFF) so the Case Structure runs the False Case which passes the shift register unchanged to the right side of the For Loop. On the third iteration the Boolean is True so the True case extracts channel 1 from the main array and "builds" it into the array with the results from the first iteration. And so on. The For loop stops because the arrays have been run to completion as set by the array size wired to the Count terminal of the For Loop. When the loop finishes all it work the Shift Register, built from the parsed channels, passes its data to the graph and the results are displayed. Shift Registers are way cool because you can build them with any contents you need - doubles, integers, strings, time stamps, Booleans, clusters of arrays of strings, you name it. Each time you change a channel entry or an ON/OFF LED the whole array is parsed and a new graph written (not terribly efficient if you have a huge array, but OK for medium sized arrays. If you pick the Stop Button the Stop event is run and a True is passed out to the conditional of the outer While Loop Structure. the While Loop stops, the loop conditional True Boolean is inverted and used to reset the Stop switch with a Value Property Node. Nothing more is wired so the VI stops. This is a good example worth studying. You will do this sort of thing over and over if you keep using LabVIEW. If you haven't learned it yet the little Light Bulb Icon turns on highlighting and lets you watch the progress of the VI. LabVIEW is a data flow language not sequential. Nodes only begin when all their inputs are filled, and stop only when all their outputs are filled. If you have never encountered this before you will have to think on it a bit to see all the implications. Good luck and enjoy, Mike Quote Link to comment
Michael Malak Posted May 13, 2009 Author Report Share Posted May 13, 2009 QUOTE (ShaunR @ May 11 2009, 03:53 PM) You used to be able to put graphs directly into arrays.I don't think you can anymore. But you can do this...... http://lavag.org/old_files/monthly_05_2009/post-15232-1242078686.png' target="_blank"> Put your graph into a cluster. Then put the cluster into an array. OK. How can I change the size of the control array at run-time? The Array Property Node "NumCols" seems to be read-only. UPDATE: Never mind -- I discovered "Make write-only" on the Property Node. Quote Link to comment
ShaunR Posted May 14, 2009 Report Share Posted May 14, 2009 QUOTE OK. How can I change the size of the control array at run-time? The Array Property Node "NumCols" seems to be read-only. Right click on the property node and choose "Change To Write" from the menu. QUOTE Also, how do I unpack this on the Block Diagram? If I attach an "Index Array" VI with no index (to indicate I want the first element of the array), the output data type is an array of one element, which is not what I would expect. I would expect a cluster of one WaveGraph. It should be a cluster containing a 1D array. If you put a Waveform graph on your front panel then right click and "create" constant on the diagram. You will see it creates a 1D array of Double Precision constant.This is the default format. You can see more on the input options in the help for Waveform Graph (a 2D Array is a multi-plot for example). Quote Link to comment
Francois Normandin Posted May 14, 2009 Report Share Posted May 14, 2009 QUOTE (Michael Malak @ May 12 2009, 06:24 PM) OK. How can I change the size of the control array at run-time? The Array Property Node "NumCols" seems to be read-only. Also, how do I unpack this on the Block Diagram? If I attach an "Index Array" VI with no index (to indicate I want the first element of the array), the output data type is an array of one element, which is not what I would expect. I would expect a cluster of one WaveGraph. 1- It's a writable property and it's the right one to adjust programmatically the number of array columns. I tried and it works. 2- You don't get an array of one element, you get a cluster of one element. Remember that you had to put the XY Graph in a cluster to display as array of graphs. As a side note, you have to realize that this implementation does not allow you to change the color or point style of graphs independantly. If you change it on one graph, it gets changed for all elements in the array... That's because the array element reference doesn't return value of all elements but rather is a reference to the datatype of the model element. Thus, any property you change on one graph, whether it is manually (on front panel) or programmatically, you'll see changes in all graphs. That could be great for plot color, but it won't be cool for axis scaling, zooming, etc. http://lavag.org/old_files/monthly_05_2009/post-10515-1242169403.png' target="_blank"> Quote Link to comment
Michael Malak Posted May 14, 2009 Author Report Share Posted May 14, 2009 QUOTE (normandinf @ May 12 2009, 05:13 PM) 1- It's a writable property and it's the right one to adjust programmatically the number of array columns. I tried and it works.2- You don't get an array of one element, you get a cluster of one element. Remember that you had to put the XY Graph in a cluster to display as array of graphs. As a side note, you have to realize that this implementation does not allow you to change the color or point style of graphs independantly. If you change it on one graph, it gets changed for all elements in the array... That's because the array element reference doesn't return value of all elements but rather is a reference to the datatype of the model element. Thus, any property you change on one graph, whether it is manually (on front panel) or programmatically, you'll see changes in all graphs. That could be great for plot color, but it won't be cool for axis scaling, zooming, etc. The inability to independently specify zoom would indeed be a bummer, which leads me to my original question this thread (which still hasn't been answered): how to dynamically instantiate a WaveGraph? Quote Link to comment
mross Posted May 14, 2009 Report Share Posted May 14, 2009 QUOTE (Michael Malak @ May 13 2009, 04:14 PM) The inability to independently specify zoom would indeed be a bummer, which leads me to my original question this thread (which still hasn't been answered): how to dynamically instantiate a WaveGraph? You can't "dynamically instantiate" anything without scripting, and that is not where you want to go. We are trying to offer you solutions not pipe dreams. Did you try a tab control? You can put graphs on different tabs and programmatically cause different tab pages to be visible. Or with much more trouble you can move the locations of the various graphs so they are visible on screen, or they are off screen. If you try to manage that with 64 individual graphs you are in for a long, boring, job that will be of limited use to the user. I gave you a way to show absolutely any combination of the 64 plots overlaid in the same graph. Use that and you work is almost done. You could decide that realistically only 4 or 6 graphs provide useful visual information on screen at the same time, and give the user the ability to show any of the plots in any of those graphs. Mike Quote Link to comment
Michael Malak Posted May 15, 2009 Author Report Share Posted May 15, 2009 QUOTE (mross @ May 13 2009, 03:34 PM) You can't "dynamically instantiate" anything without scripting, and that is not where you want to go. We are trying to offer you solutions not pipe dreams.Did you try a tab control? You can put graphs on different tabs and programmatically cause different tab pages to be visible. Or with much more trouble you can move the locations of the various graphs so they are visible on screen, or they are off screen. If you try to manage that with 64 individual graphs you are in for a long, boring job that will be of limited use to the user. I gave you a way to show absolutely any combination of the 64 plots overlaid in the same graph. Use that and your work is almost done. You could decide that realistically only 4 or 6 graphs provide useful visual information on screen at the same time, and give the user the ability to show any of the plots in any of those graphs. Mike Thanks for the info on instantiation. I had guessed that perhaps it might be possible with the "Open VI Reference" VI, but I guess now that that's not the case. Manually placing N WaveGraphs (12 is all I need immediately for the next month) and then placing references to them in an array is the approach I'm going to take to achieve simultaneously the programming convenience of arrays and independent properties (such as zoom) in the WaveGraphs. I'll simulate instantiation via the "Visible" property of each WaveGraph. Quote Link to comment
Francois Normandin Posted May 15, 2009 Report Share Posted May 15, 2009 QUOTE (Michael Malak @ May 13 2009, 07:29 PM) Thanks for the info on instantiation. I had guessed that perhaps it might be possible with the "Open VI Reference" VI, but I guess now that that's not the case.Manually placing N WaveGraphs (12 is all I need immediately for the next month) and then placing references to them in an array is the approach I'm going to take to achieve simultaneously the programming convenience of arrays and independent properties (such as zoom) in the WaveGraphs. I'll simulate instantiation via the "Visible" property of each WaveGraph. As Mike says, you need scripting (not available in exe) to create graphs "spontaneously", BUT if you're looking for a solution with "Open VI reference", then it's an other ballgame! Try out those VIs (attached). You can spawn multiple graph windows and communicate your data to each of them, either from the main VI that spawned them using some means that you can certainly find in other threads, or by having each spawned VI acquire it's own data. Now this is what Mike and others advised: it's a good time to refactor your design while still satisfying your customer! Each instance of "XY Graph Instance.vi" will be independant. (Launch XY Graph Main.vi, don't open XY Graph Instance.vi) Hoping it's in the right direction for you... Download File:post-10515-1242264287.vi Download File:post-10515-1242264294.vi This has been programmed in LV 8.6 EDIT: BTW, you profile says you use LabVIEW 2009, which is still in Beta testing. Perhaps you should change your profile to tell us which version you use (and can read our code snippets). It will prevent us from uploading code that you can't read. Quote Link to comment
mross Posted May 15, 2009 Report Share Posted May 15, 2009 QUOTE (Michael Malak @ May 13 2009, 07:29 PM) Thanks for the info on instantiation. I had guessed that perhaps it might be possible with the "Open VI Reference" VI, but I guess now that that's not the case.Manually placing N WaveGraphs (12 is all I need immediately for the next month) and then placing references to them in an array is the approach I'm going to take to achieve simultaneously the programming convenience of arrays and independent properties (such as zoom) in the WaveGraphs. I'll simulate instantiation via the "Visible" property of each WaveGraph. You should look at the capabilities of VI Server. You can start up many new VIs that way. However, you cannot cause new graphs on the front panel of a VI which is how I interpreted your query. You can only hide and show them by various means, or put them on Tabs and change the visible tab - programmatically. Here is a little demo of how to use the Open VI Reference you mentioned. This example was written for a someone else, but it is useful as an general example. It shows how to call and open a VI and its Front Panel independent of the calling VI. It also shows the use of the Producer Consumer architecture which demonstrates parallel loops, queues, and the user event structure. You will need to put all 4 of these files in your C: directory, or you will have to change the paths to the VIs and data file. (the Data Logging VI also has a path to change). Run the top level VI called ProdCons_experiment.vi. Press the INITIATE DATALOGGING button to invoke the data generation and logging VI. Press the PRESENT GRAPH OF DATA FILE button to to invoke the display a graph of the data file VI. This method allows the Top level VI to continue operation independent of the invoked VIs. It is possible to have sub-VIs to show their front panel when called from within the top level VI, but the top level VI then waits for the sub-VI to finish before proceeding. The original purpose of this was to have a datalogger VI write to a file periodically, and to show the contents of that data file on demand. I use this example to remind myself how this is done. Mike Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.