Visual Engineering provides a set of pre-constructed complete charts that combine these components in a uniform way. These chart classes are uniformly named [chart-type]Chart.class; e.g. BarChart.class AreaChart.class, LineChart.class and so on. They also all extend the Chart abstract superclass, which provides functionality common to all charts, such as adding datasets, installing a background, and so on.
Generally, one of the preconstructed Charts will meet your needs. We have provided source code for each of these specific Chart subclasses so you can see how to create your own combinations.
Every chart includes one or more Dataset classes, a Background and a Plotarea class, and a few other necessary utility classes. Each chart also contains one or more graphical components, such as a Line class (responsible for rendering an array of Dataset classes in a line chart form) or a Pie class (responsible for rendering a Dataset class in pie chart form).
Many component classes are dependent on other components. For example, an Axis class requires an array of Dataset classes and a Plotarea class so that it may scale properly and draw itself in the correct location. The Chart abstract class and the specific chart type classes combine these components in a coherent fashion.
Subclassing is used extensively to share common functionality in KavaChart. For example, Axis is a superclass to LabelAxis, DateAxis, and SpeedoAxis. All these subclasses re-use significant portions of Axis's functionality, and inherit most of their properties from the Axis superclass.
KavaChart also uses Java interfaces in a few strategic places to enhance the package's flexibility and to facilitate KavaChart use within an application's GUI. KavaChart includes interfaces for Axis, Legend, and Chart classes. Should you choose to extend KavaChart classes for your own use, we recommend implementing these interfaces for continuing compatibility.
Generally, programmers will use the access methods available for each class to manipulate a class' properties. These access methods are uniform throughout KavaChart, using signatures recognized by Java 1.1's introspection facility. A sample access method pair from our Axis class is as follows:
public void setLabelAngle(int angle);
myChart.getYAxis().setDatasets(theoreticalDatasets);
myChart.getYAxis().scale();
myChart.getYAxis.setDatasets(savedDatasets);
The KavaChart applet collection uses HTML parameters to set most chart properties. This is a simple way to initialize a wide range of chart properties if your application or applet can use KavaChart's preconstructed applet classes. Since we also provide the applet source code, you can also transfer portions of the applet source code into your own applets to set these properties.
Many of the properties you'll be most interested setting come from KavaChart's Gc class. This is a utility class that stores values for graphical attributes like colors and images. Almost every KavaChart class has at least one Gc associated with it. You will quickly come to appeciate this uniformity in you own code, as you can develop uniform ways to deal with all sorts of graphical attributes. Here are a couple of examples of using the Gc class:
myChart.getPlotArea().getGc().setFillColor(Color.blue);
myChart.getAxis.getGridGc().setLineColor(Color.blue);
myGc.setFillColor(Color.blue);
myGc.setLineColor(Color.blue);
In KavaChart, interfaces are available for Chart,Legend, and Axis. These exist primarily to provide design guidance to individuals who wish to add new classes to KavaChart while re-using existing classes. For example, if an individual wanted to build an axis system with labelling based on Fibonacci sequences, she could still use Line, Bar, or any of the other pre-existing KavaChart classes.
Similarly, all sorts of Legends can be implemented without subclassing KavaChart's Legend class. The only requirement, if those legends are going to be used within pre-existing KavaChart classes, is that the new Legend conform to our LegendInterface class.
Chart is a special case. Visual Engineering provides a set of preconstructed complete Chart classes that all extend the Chart abstract class. Chart is implemented as an abstract class to provide common functionality shared by various chart types. It's a sort of safety net to ensure that obscure classes are all initialized, and to simplify specific Chart classes. You can see by the brevity of source code in BarChart.java that this is an effective approach.
ChartInterface provides a uniform way to deal with complete charts. Its implementation is certainly not mandatory for dealing with internal KavaChart classes because it's not used internally. Rather, ChartInterface provides a uniform way for you to collaborate with other KavaChart users who may have constructed custom charts. You can see an example of how this is used in our own KavaChart applets.
The Axis chapter describes Axis and its subclasses in more detail.
Label Axis uses the same sort of scaling algorithms as Axis, but uses a user-defined list of labels, rather than automatically generated labels. If a particular LabelAxis increment doesn't have a label defined, it will use the Dataset element label or value that corresponds to that location. For example, a BarChart that uses a LabelAxis might not define labels for the axis. If labels are defined for the first Dataset in LabelAxis's dataset array, the Dataset label will be used instead of the (missing) Axis label. As a subclass of Axis, LabelAxis inherits all of Axis's properties and grid and tick drawing capability. You can find most of the Axis functions for LabelAxis in the documentation for Axis.
DateAxis also extends Axis, and uses Axis properties and drawing functions, but alters the way data is interpreted, and changes the kind of labels that are generated. Specifically, DateAxis interprets the data values in its Dataset classes to be Date primitive values (number of milliseconds since the "epoch"). By examining the range of Date values in its Dataset classes, a DateAxis builds an Axis with increments of milliseconds, hours, months, and so on. The labels are constructed accordingly, using North American English conventions. DateAxis exposes its methods for constructing labels so that other conventions can be implemented by subclassing.
Java 1.1 made dramatic changes to the way Dates and calendars are handled. While this promises to provide much better localization of calendar handling, much of the local functionality remains unimplemented. Many of the Date functions used by KavaChart were deprecated, sometimes don't work properly (especially on pre-release Java 1.1 VMs). We're working on creating a Java 1.1 implementation of DateAxis, but this will not, unfortunately, be transparently compatible between Java 1.0.2 and Java 1.1.
SpeedoAxis is a special case of Axis that overrides Axis drawing functions but not scaling and label generating functions. A SpeedoAxis creates a curved scale appropriate for gauges and dials. While it examines all the data in its Dataset array for purposes of creating a scale, the Speedo component usually coupled with a SpeedoAxis draws only a single element: the first Y value of the first Dataset.
All Bar subclasses change Bar's behavior in some way:
StackBar and StackColumn stack multiple observations in a single category, rather than clustering them.
IndBarChart and IndColumnChart use each Datum's Gc class for bar colors, rather than the Dataset Gc.
HorizHiLoBar and HiLoBar examine the Y2 value of each Datum to create Gantt style floating bars.
Two Bar subclasses that are less obviously related to the Bar superclass are Stick and HiLoClose charts. These financial chart styles are able to reuse some of Bar's internal logic for dealing with discrete observations, and avoid redundant code by subclassing Bar. These component types do not draw labels.
KavaChart includes only one Line subclass, Regress. This subclass overrides Line's draw function to draw an ordinary least squares regression line for each Dataset in the Line's Dataset array.
Line is used in slightly different ways in each complete Chart class, however. For example, a LineChart just uses arbitrary X and Y values, while a DateLineChart assumes that the X values represent Date timestamps. LabelLineChart assumes monotonically increasing X values, so that each category can be labelled appropriately.
Legend draws a rectangular icon and a label for each class in its Dataset array. The LineLegend subclass draws lines and markers instead of rectangles, and the PieLegend subclass draws an icon for each Datum in a single Dataset, rather than one icon for each Dataset.
One thing to remember about KavaChart's Chart classes is that the internal components are completely re-usable. You can, for example, create a bar chart, and then simply transfer the datasets to a line chart for a different representation. Because of KavaChart's modular construction, you can easily transfer data, graphical properties, and so on.
Gc is a class for storing graphical properties, such as lineColor and fillColor, as well as methods for drawing. Although Gc doesn't extend the Java Graphics class, you can think of it as KavaChart's conduit to Java Graphics.
DisplayList is KavaChart's internal mechanism for collecting chart geometries and associating these with specific objects. DisplayList's contains() method lets you obtain a list of KavaChart objects at a particular location. Because every chart object that draws something is a candidate for entry into the DisplayList, this class is used almost everywhere.
RotateString is KavaChart's internal utility for rotating labels and other character strings. Since Java doesn't provide any string rotation, the chart package uses raster operations to rotate Java's fonts.
RotateString and DisplayList need to be available to many classes, but creating separate instances of these classes for each chart class would be inefficient and architecturally awkward. To avoid this, we created a special Globals class that stores one instance of these classes and a few properties used by every chart. One instance of a Globals class is available to almost every class in a specific Chart. You probably won't access the members of this class very often, however, because the abstract Chart class provides specific access methods for Globals properties that need to be exposed.
KavaChart's chart package is concerned with managing and rendering data using conventional graphical representations. It provides functions for drawing charts, and for identifying chart objects based on locations, but it does not attempt to create entire bound applications or applets. KavaChart's applets provide some of this functionality in the form of robust applets, and we are working on a set of Java Beans that encapsulates key charting functions into Beans.
By sending a pixel location to any chart's DisplayList class, you can receive a list of chart objects at that location. You can also customize the contents of that list by setting the useDisplayList property for any drawing chart class. By using this functionality, you can acquire property information, data values, or any other information stored within KavaChart's classes.
Since KavaChart doesn't concern itself with managing the flow of events, you're free to implement either 1.0.2 or 1.1 style event management. To make sure you stay up to date on evolving Java technologies in KavaChart, check our additional resources in Appendix B.