Options and Customization

There are a number of options that you can set for SwiftVis, many of them deal with the configurability of the program. To view the options go to File > Edit Options. Before we talk about the general configurability options there is the Miscellaneous tab for other options. Currently there are two types of other options. The first tells SwiftVis how large you want you data sources to be allowed to get for those that do buffering. Not everything does buffering, but those that do will look here to determine how much memory they are allowed to use. By default this is 200MB. If you have a machine with a lot more RAM though you might find your performance improves significantly by increasing this.

Also, there is an option for whether your machine is little-endian or big-endian. This just tells what order the bytes in numbers are given in on your machine. The x86 architecture is little-endian. The PowerPC architecture used by Apple machines is big-endian. If you try to read in a bin.dat file and notice that you are getting numbers that are WAY off (like a values of 2e16) you should probably change this setting. This only matters for binary files in non-XDR format. As of the writing of this, the big-endian code has not been well tested due to lack of a big-endian machine. If you want to donate a high end Apple to Mark Lewis, we can get this fixed. Even if you can't donate one but run into a problem here, contact mlewis@trinity.edu and we can get this working.

The other options in SwiftVis all deal with the ability to add in other components to the system. While we have tried to make SwiftVis as complete as possible, it is inevitable that people will want to add other functionality to the system that can be had by combining different parts or where the combination would be more convoluted than you really want to get into. In this case, you can write your own Java class that will fit into the SwiftVis system. The original design of SwiftVis was intended to make this possible and many of the filters currently in the system were not part of the original plan. Instead, they were added as it was seen that extra functionality was needed. There are four tabs that allow you to edit the features available to you in SwiftVis. These are Sources, Filters, Plot Styles, and Other Sinks. All of these have the same general format. There is a text field at the top with a list under it. At the bottom is a Remove button and there is an OK button for when you are done.

The list is the easiest thing to stat with, it shows you all of the elements of that type that your SwiftVis system knows about. It will include by default all of the ones that are discussed in this documentation. If there is something you don't feel you will ever use, you could click on it and click Remove. This isn't generally recommended, but you can put things back in as long as you know what they are called. The text field at the top is used for adding to the list. The way it works is that you type in the full class name, with packages, of the Java class that you want to add. For example, if you didn't have the Selection Filter, you could type in edu.swri.SwiftVis.filters.SelectFilter. Of course, the Selection Filter is already on the list and you aren't likely to delete it. What these screens matter most for is for adding in new features to SwiftVis written by you or others in the community. If the class that you add doesn't have its own description hard coded in, you will be asked for a description of it at that point.

The classes that you create will not be part of the SwiftVis JAR file so you will need to do something so that Java can find them when you run SwiftVis. If you feel comfortable doing it, the proper method is to edit your CLASSPATH system parameter so that it includes the directory or file where the other classes are included. We have provided an easier alternative that will work equally well and will be easier for most people. The Options dialog has a tab labeled "Class Path" that was added originally for scripting so that you can tell SwiftVis where to look for other scripting languages. You can add directories or JAR files here that contain user created sources, filters, sinks, or plot styles and Java will be able to find them so that you can use them. We hope that users who contribute significantly to SwiftVis might develop their own JAR files that other users can download.

Clicking on OK saves your changes to disk. If you close the window in another way, your changes will be used in this session, but they won't be saved off and the next time you start SwiftVis they won't be there.

SwiftVis was designed to allow the addition of various new components by different users. The system is written in Java which has certain features like dynamic class loading that make this possible. If you intend to add your own sources, filters, plot styles, or other elements, you should know Java and take some time looking that the javadocs for SwiftVis. Unlike most Javadocs, these were generated with private visibility so that you can see everything in the system. You might also want to open the JAR file and look directly at the source code itself. The development for SwiftVis has been done mostly in Eclipse and we highly recommend this IDE. Not only is it free, it is also very feature rich and works wonderfully. It will help you "figure out" what code you need to write if you know what you are inheriting from, and will stub out those methods for you.

Other steps have been taken to help programmers in creating new elements for SwiftVis. To describe this, we should look quickly as the inheritance hierarchy of SwiftVis quickly. The top level is the GraphElement interface. This is anything that can be added into a graph and it has methods that are needed by things that can be drawn in the graph. This class has two subtypes that are also interfaces. There are the DataSource and the DataSink interfaces. The names of these imply what they do. Any element that supplies DataElements should be of type DataSource. Any element that uses DataElements is a DataSink. Both interfaces have the methods required for sinks to ask sources for information and for sources to tell sinks when their data has changed. There is also an interface called Filter that does nothing but inherit from both DataSource and DataSink as the filter elements accept data from sources and give data off to sinks.

You could directly inherit from these interfaces if you wanted to, but we have tried to make your life even easier than that. If you want to write a source that pulls from a file or gets data in some other manner (but isn't a filter pulling from a different source), you can inherit from the AbstractSource class. This class implements most of the basic methods of DataSource, especially those that come from GraphElement. It also requires that you implement two other methods that are called by implementations of some methods in AbstractSource. For a simple example of a DataSource that inherits from AbstractSource, we recommend looking at DiscardData. Most of what you will have to program are simple little functions that tell how many parameters and values each of the output data elements will have. More complex methods deserve some comment.

If you don't want people to be asked what your element should be called when it is added to the Options, you should provide a static method public String getTypeDescription(). This is called to provide the name and the user is only asked if it isn't there. This is true of all subclasses of GraphElement, not just sources.

The setupSpecificPropertiesPanel is an abstract method in AbstractSource. It is called by the getPropertiesPanel. The AbstractSource has a protected data member called propPanel that is of type JTabbedPane. In the setupSpecificPropertiesPanel, you should make your own panels for properties and add them into propPanel with appropriate label names. The AbstractSource will add in a tab for looking at the output after you have added your tabs.

The redoAllElements method is another abstract method of AbstractSource. This is called by abstractRedoAllElements which is what you should call when the data should be redone. The redoAllElements method is where you actually put elements into the member dataVect which is a protected member of AbstractSource.

Lastly, there is a copy method. This method is used by the cut and paste functionality and by the template saving functionality. The implementation is fairly simply, return a new object that is a copy of the current one. The one catch is that you only maintain links to GraphElements that are in the list that is passed to you. If you are inheriting from AbstractSource, this last point will likely not matter to you, since it is keeping track of all the sinks that the source connects to. You should write a copy constructor that also takes the list and in that constructor, first call super passing it the object being copied and the list, then copy over all the member data that you have added to your class.

If you are creating a filter, you should inherit either from AbstractSingleSourceFilter or AbstractMultipleSourceFilter. The only difference as far as your concerned is that the latter keeps a vector of input sources while the former keeps track of only one. The canonical example of a filter is the SelectFilter. For a filter you will need to write all the methods that you did for a source. In most cases, the abstract classes handle the other aspects for you.

The third type of feature that you are likely to add is a plot style. These are used in the plotting mechanism to draw out data in different ways. All of them inherit from DataPlotStyle. You could look at ScatterStyle of RectangleGridSurface for examples of these. The methods that you have to add here are all fairly self explanitory and some mirror what you had to do for the sources and filters. The main method of interest is the drawToGraphics method. This method will be passed a Graphics2D object and two doubles. The doubles tell you how large the plotting area is in x and y. The Graphics2D object is what you draw to. See the official Sun API for information on Graphics2D. The significant thing to note here is that you don't need to know the bounds for the drawing or have to do any transformations. Prior to being passed to you, the transformations and clipping at set on the Graphics2D object. So it you want to draw a yellow rectangle that goes from (1,1) to (2,3) in the plot, simply set the color with g.setPaint(Color.yellow), then fill in your rectange with g.fill(new Rectangle2D.Double(1,1,1,2)). Notice that rectangles take x, y, width, height. You don't need to know anything about the size of the window you are drawing to in pixels or anything like that. The two size parameters are passed in so that you can size marker points to be a certain fraction of the plot area. Using markers 1 unit in size doesn't make sense if you plot bounds are 0.1 or 10,000 in size. You might have noticed that the default size in the scatter plot style is 0.01. That means they should cover 1% of the size of the plot linearly.

There is a 4th option that isn't fully integrated as of the writing of this page and that is the "Other Sinks" category. The intension of this is to allow users to write other types of plots other than the 2D style plotting that is provided. Doing this is a significant undertaking though and you should consider contacting us before doing this so that not only can we help lead you through it, but also so that menu options can be put in for you to actually add whatever you create to the graph.

Some other utility classes have been added to help make the coding of different aspects of your extensions to SwiftVis easier. There are some aspects of writing SwiftVis extensions that can get tedious. The GUIs are high on this list. For this reason, a fair bit of help has been provided for when you want to have the user be able to edit values in the GUI. Instead of using the primitive double, int, boolean, or the class String to store data that the user can edit in the GUI, use the corresponding classes in the edu.swri.SwiftVis.util package. For example, if the user should be able to edit the value of a double that is some part of a range, you should use EditableDouble to make the GUI coding simpler. By doing this, when you want to add in the JTextField that allows the user to edit the number, simply call the getTextField method and, if something should happen when it is edited, provide a listener. This will reduce 8-10 lines of very repetitive code down to 1-4 depending on the listener. If you are reading from a binary file, use the BinaryInput class that that is in the util package. This call checks the Options for whether to read numbers in as big-endian or little-endian.

If you are writing a plot style, there is also a utility package under plot: edu.swri.SwiftVis.plot.util. This package includes classes that will help you store and edit fonts, strokes, colors, and gradients. They generally have an edit method that you can call to bring up a dialog box which will allow you to edit the proper information. Using these not only makes your life easier, but it makes things more uniform so that people will automatically know what to do when they see something. Writing an editor for a color gradient is not straightforward and the required complexity of the interface is sufficient that there is no reason for having to document several of them.

If you do create your own class, or you start using classes written by other people that are not part of the normal SwiftVis distribution, you will have to make sure that Java knows where to find the class files when you add them into the options. There are two ways to do this. You can either set the CLASS_PATH environment variable in which case all Java executions will look in the specified directory if they can't find things in other places, or you can use the -cp option when running the JAR file to provide a different directory to look in. Lastly, you might consider rejarring up the distribution with your classes in it and working with that.

If you come up with an addition that you feel other people will benefit from, contact us and we can probably add it into the normal distribution. If you think you have a good idea for something that should be added to SwiftVis but you don't know Java or don't have the time to go through the extension process yourself, you should still let us know your idea so that we can consider adding it.