JClass Chart

PreviousNextIndex

8

Data Sources

Overview  Data Views  Pre-Built Chart DataSources  Loading Data from a File

Loading DataSource from a URL  Loading Data from an Applet 

 Loading Data from a Swing TableModel  Loading Data from an XML Source  Data Formats

Data Binding: Specifying Data from Databases

Making Your Own Chart Data Source  Making an Updating Chart Data Source


8.1 Overview

Data is loaded into a chart by attaching one or more chart data sources to it. A chartable data source is an object that takes real-world data and puts it into a form that JClass Chart can use. Once your data source is attached, you can chart the data in a variety of ways.

The design of JClass Chart makes it possible to chart data from virtually any real-world source. There is a toolkit you can use to create custom chartable objects (data sources) for your real-world data.

Creating your own data sources can be time consuming. For that reason, JClass Chart provides pre-built chartable data sources for most common real-world data: files, URLs, applets, Strings, and databases.

This chapter describes how to use the pre-built data sources and how to create your own.


8.2 Data Views

DataSources are added to JClass Chart through Data Views, which are encapsulated by the ChartDataView object. ChartDataView organizes data as a collection of ChartDataViewSeries objects, one ChartDataViewSeries for each series of data points.

In most cases, your charts will require only one Data View. However, JClass Chart allows you to load data from multiple data sources at the same time, assigning each source to a separate Data View. By default, all Data Views are showing, but each may be hidden or revealed depending on the needs of your application. Data Views may be mapped to the same set of X- and Y-axes, or to different axes.

Note: Radar, area radar, and pie charts do not support multiple Data Views.


8.3 Pre-Built Chart DataSources

The pre-built DataSources for JClass Chart are located in the com.klg.jclass.chart.data package. Their names and descriptions follow.

DataSource name

Description

BaseDataSource

A very simple container for chart data.

JCAppletDataSource

Used to load data from an applet parameter tag.

JCChartSwingDataSource

Used to extract data from a Swing TableModel.

JCDefaultDataSource

An extension of BasicDataSource.

JCEditableDataSource

An editable version of JCDefaultDataSource.

JCFileDataSource

Used to load data from a file.

JCInputStreamDataSource

Used to load data from any stream.

JCStringDataSource

Used to load data from a String.

JCURLDataSource

Used to load data from a URL.

JDBCDataSource

Used to load data from a JDBC Result Set.


8.4 Loading Data from a File

An easy way to bring data into a chart is to load it from a formatted file using JCFileDataSource. To load data this way, you create a data file that follows JClass Chart's standard format, as outlined in Section 8.9, Data Formats.

Then, you instantiate a JCFileDataSource object and attach it to a view in your chart application. The following example shows how to instantiate and attach a JCFileDataSource:

chart.getDataView(0).setDataSource(new JCFileDataSource("file.dat"));

8.5 Loading DataSource from a URL

You can chart data from a URL address using JCURLDataSource. To load data this way, you create a data file that follows JClass Chart's standard format, as outlined in Section 8.9, Data Formats.

Then, you instantiate JCURLDataSource and attach it to a view in your chart. The following example uses data from a file named plot1.dat:

chart.getDataView(0).setDataSource(new
  JCURLDataSource(getDocumentBase(), "plot1.dat"));

Parameter options for JCURLDataSource:

The following are valid parameter combinations for JCURLDataSource:

host: The WWW hostname.
file: The fully qualified name of the file on the server.
URL: The URL address of a data file, eg, http://www.quest.com/datafile.dat.
base: A URL object representing the directory where the file is located.

In the example above, the first parameter passed is getDocumentBase(), a method that returns the path where the current applet is located.


8.6 Loading Data from an Applet

You can chart data from an applet using JCAppletDataSource.

To prepare the data, put it into the standard format, (see Data Formats), and insert it into the HTML file that calls your applet. The HTML syntax is as follows:

<Applet>
...
<PARAM NAME=Your_Data_Name VALUE=" ....formatted data... ">
...
</Applet>

"Your_Data_Name" is used by your applet to select the right set of information. Use the same name in the applet and the HTML source. If a name is not provided "data" is assumed.

With your data in the HTML file, instantiate an JCAppletDataSource and attach it to a view in your chart as follows:

chart.getDataView(0).setDataSource(new JCAppletDataSource(applet, "Your_Data_Name"));

You can also chart data from an HTML file. For a listing of the syntax of JClass Chart properties when specified in an HTML file, please see Appendix C.

Example of Data in an HTML file

<APPLET CODEBASE="../../../.." CODE="jclass/chart/demos/labels/labels.class"

<PARAM NAME=data VALUE="

ARRAY 'Oblivion Inc. 1996 Results' 2 4
'Q1' 'Q2' 'Q3' 'Q4'
'Quarter' 1 2 3 4
'Expenses' 150.2 182.1 152.1 170.6
'Revenue ' 125.5 102.7 225.0 300.9
">
</APPLET>

8.7 Loading Data from a Swing TableModel

The JCChartSwingDataSource class enables you to use any type of Swing TableModel data object for the chart. TableModel is typically used for Swing JTable components, so your application may already have created this type of data object.

JCChartSwingDataSource "wraps" around a TableModel object, so that the data appears to the chart in the format it understands.

This data source is available through the SwingDataModel property in the SimpleChart and MultiChart Beans. To use it, prepare your data in a Swing TableModel object and set the SwingDataModel property to that object.


8.8 Loading Data from an XML Source

8.8.1 XML Primer

XML - eXtensible Markup Language - is a scaled-down version of SGML (Standard Generalized Markup Language), the standard for creating a document structure. XML was designed especially for Web documents, and allows designers to create customized tags ("extensible"), thereby enabling common information formats for sharing both the format and the data on the Internet, intranets, et cetera.

XML is similar to HTML in that both contain markup tags to describe the contents of a page or file. But HTML describes the content of a Web page (mainly text and graphic images) only in terms of how it is to be displayed and interacted with. XML, however, describes the content in terms of what data is being described. This means that an XML file can be used in various ways. For instance, an XML file can be utilized as a convenient way to exchange data across heterogeneous systems. As another example, an XML file can be processed (for example, via XSLT [Extensible Stylesheet Language Transformations]) in order to be visually displayed to the user by transforming it into HTML.

Please note that in XML, certain special characters need to be "escaped" if you want them to be displayed. For example, you cannot simply put and ampersand (&) or a greater than sign (>) into a block of text; these special characters are represented as &amp; and &gt; respectively. For details on this topic, please see http://java.sun.com/xml/jaxp/dist/1.1/docs/tutorial/sax/4_refs.html#chars.

Further Information About XML

Here are links to more information on XML.

http://www.w3.org/XML/ - another W3C site; contains exhaustive information on standards.

http://www.ucc.ie/xml - an extensive FAQ devoted to XML

http://www.java.sun.com/docs/index.html - Sun's XML site

8.8.2 Using XML in JClass

In order to work with XML in your programs or even to compile the JClass XML examples, you will need to have jaxp.jar and crimson.jar in your CLASSPATH; these files are distributed with JClass Chart - you can find them in JCLASS_HOME/lib/.

JClass Chart can accept XML data formatted to the specifications outlined in com.klg.jclass.chart.data.JCXMLDataInterpreter. This public class extends JCDataInterpreter and implements an interpreter for the JClass Chart XML data format. JCXMLDataInterpreter relies on an input stream reader to populate the specified BaseDataSource class.

Data can be specified either by series or by point. This is fully explained below.

Examples of XML in JClass

For XML data source examples, see the XMLArray, XMLArrayTrans, and XMLGeneral examples in JCLASS_HOME/examples/chart/datasource. These use the array.xml, arraytrans.xml, and general.xml data files, respectively.

Interpreter

The interpreter, which converts incoming data to the internal format used by JClass Chart, must be explicitly set by the user when loading XML-formatted data. The interpreter to use for this purpose is com.klg.jclass.chart.data.JCXMLDataInterpreter.

Many constructors in the various data sources in JClass Chart take the abstract class JCDataInterpreter, which is extended by JCXMLDataInterpreter. It is possible for the user to create a custom data format and a custom data interpreter by extending JCDataInterpreter.

Here are a few code examples that load XML data using JClass Chart's XML interpreter, JCXMLDataInterpreter:

ChartDataModel cdm = new JCFileDataSource(fileName, new JCXMLDataInterpreter());
ChartDataModel cdm = new JCURLDataSource(codeBase, fileName, new JCXMLDataInterpreter());
ChartDataModel cdm = new JCStringDataSource(string, new JCXMLDataInterpreter());

8.8.3 Specifying Data by Series

When "specifying by series", there can be any number of <data-series> tags. Within each <data-series> tag, there can be an optional <data-series-label> tag. Within each <data-series> tag, there can be any number of <x-data> tags (these tags represent the X-values for that series). If there are no <x-data> tags in any <data-series> tag, a single X-array is generated, starting at 1 and proceeding in increments of 1.

If only one series has <x-data> tags, then that list of X-data is used for all series. If more than one series has <x-data> tags, those tags are used only for the series in which they are located.

Within each <data-series> tag, there must be at least one <y-data> tag (generally there will be many). <y-data> tags represent the Y-values for that series.

If the number of X-values and Y-values do not match within one series, the one with the fewer number of values is padded out with Hole values.

Here is an example of an XML data file specifying data by series.

<?xml version="1.0"?>
<!DOCTYPE chart-data SYSTEM "JCChartData.dtd">
<chart-data Name="My Chart" Hole="MAX">
  <data-point-label>Point Label 1</data-point-label>
  <data-point-label>Point Label 2</data-point-label>
  <data-point-label>Point Label 3</data-point-label>
  <data-point-label>Point Label 4</data-point-label>
  <data-series>
    <data-series-label>Y Axis #1 Data</data-series-label>
    <x-data>1</x-data>
    <x-data>2</x-data>
    <x-data>3</x-data>
    <x-data>4</x-data>
    <y-data>1</y-data>
    <y-data>2</y-data>
    <y-data>3</y-data>
    <y-data>4</y-data>
  </data-series>
  <data-series>
    <data-series-label>Y Axis #2 Data</data-series-label>
    <y-data>1</y-data>
    <y-data>4</y-data>
    <y-data>9</y-data>
    <y-data>16</y-data>
  </data-series>
</chart-data>

This format is similar to both the array and the general formats of the default chart data source.

8.8.4 Specifying Data by Point

In the "specifying by point" format, there can be any number of <data-point> tags. Within each <data-point> tag, there can be one optional <data-point-label> tag. Within each <data-point> tag, there can be one optional <x-data> tag (these tags represent the X-value of that point). If there are no <x-data> tags in any of the <data-point> tags, X-values are generated, starting at 1 and then increasing in increments of 1.

If some <data-point> tags have <x-data> tags but others do not, the missing ones will be replaced with Hole values.

Within each <data-point> tag, there must be at least one <y-data> tag (in general, there will be many). <y-data> tags represent the Y-values of each series at this point.

There should always be the same number of <y-data> tags within each <data-point> tag. If there are not, then the largest number of <y-data> tags in any one <data-point> tag is used as the number of series, and the other lists of Y-values will be padded with Hole values.

Here is an example of an XML data file specifying data by point.

<?xml version="1.0"?>
<!DOCTYPE chart-data SYSTEM "JCChartData.dtd">
<chart-data Name="MyChart">
<data-series-label>Y Data</data-series-label>
<data-series-label>Y 2 Data</data-series-label>
<data-point>
  <data-point-label>Point Label 1</data-point-label>
  <x-data>1</x-data>
  <y-data>1</y-data>
  <y-data>1</y-data>
</data-point>
<data-point>
  <data-point-label>Point Label 2</data-point-label>
  <x-data>2</x-data>
  <y-data>2</y-data>
  <y-data>4</y-data>
</data-point>
<data-point>
  <data-point-label>Point Label 3</data-point-label>
  <x-data>3</x-data>
  <y-data>3</y-data>
  <y-data>9</y-data>
</data-point>
<data-point>
  <data-point-label>Point Label 4</data-point-label>
  <x-data>4</x-data>
  <y-data>4</y-data>
  <y-data>16</y-data>
</data-point>
</chart-data>

This format is similar to the transposed array format of the default chart data source.

8.8.5 Labels and Other Parameters

<data-point-label> and <data-series-label> tags

<data-point-label> and <data-series-label> tags are optional with both the specifying by series or specifying by point methods. If there are more point labels than data points, or more series labels than data series, the extra labels are ignored. If there are more data points than point labels, or more data series than series labels, then the list is padded with blank labels. If there are no point labels or no series labels at all, the chart default is used - no point labels and series labels containing "Series 1", "Series 2", et cetera.

Name and Hole parameters

The Name and Hole parameters of the JCChartData tag are also optional. Name can be any String. Hole can be a value, the String MIN (meaning Double.MIN_VALUE) or the String MAX (meaning Double.MAX_VALUE). To represent virtual hole values in an X-data or y-data tag, use the word Hole. Any X-data or y-data tag can contain a value, the String MIN, the String MAX, or the String Hole.

See the "Specifying Data by Series" and "Specifying Data by Point" sections to view these elements in code samples.


8.9 Data Formats

JCFileDataSource, JCURLDataSource, JCInputStreamDataSource, JCStringDataSource, and JCAppletDataSource all require that data be pre-formatted. The following table illustrates the formatting requirements of data for pre-built data sources. There are two main ways to format data: Array and General.

Array-formatted data shares a single series of X-data among one or more series of Y-data. General-formatted data specifies a series of X-data for every series of Y-data.

Array format is the recommended standard, because it works well with all of the chart types. General Format may not display data properly in Stacking Bar, Stacking Area, Pie Charts, and Bar Charts.

Note that for data arrays in Polar charts, (x, y) coordinates in each data set will be interpreted as (theta, r). For array data, the X-array will represent a fixed theta value for each point.

In Radar and Area Radar charts, only array data can be used. (x, y) points will be interpreted in the same way as for Polar charts (above), except that the theta (that is, x) values will be ignored. The circle will be split into nPoints segments with nSeries points drawn on each radar line.

General format is intended for use in cases where you want to display multiple X-axis values on the same chart.

The following table shows four formatted data examples. An explanation of each element follows.

8.9.1 Formatted Data Examples

Array Data Format (Recommended)

ARRAY 2 3 # 2 series of 3 points
HOLE 10000 # Use only if custom hole value needed
'Point 0' 'Point 1' 'Point 2' # Optional Point-labels
# X-values common to all points
1.0 2.0 3.0
# Y-values
'Series 0' 50.0 75.0 60.0 # Series-label is optional
'Series 1' 25.0 10.0 50.0

Transposed Array Data Format (same data as previous)

ARRAY 2 3 T # 2 series of 3 points, Transposed
HOLE 10000
'' 'Series 0' 'Series 1' # Optional Series-labels
# X-values Y0-values Y1-values
'Point 0' 1.0 50.0 25.0 # Point-labels are optional
'Point 1' 2.0 75.0 10.0
'Point 2' 3.0 60.0 50.0

General Data Format (Use if X-data is different for each series)

GENERAL 2 4 # 2 series, max 4 points in each
HOLE -10000 # Use only if custom hole value needed
'Series 0' 2 # 2 points, optional series label
1.0 3.0 # X-values
50.0 60.0 # Y-values
'Series 1' 4 # 4 points
2.0 2.5 3.5 5.0 # X-values
45.0 60.0 HOLE 70.0 # Y-values, including data hole
Transposed General Data Format (same data as previous)
GENERAL 2 4 T # 2 series, max 4 points in each, Transposed
HOLE -10000
'Series 0' 2 # 2 points, optional series label
# X Y
1.0 50.0
3.0 60.0
'Series 1' 4 # 4 points
# X Y
2.0 45.0
2.5 60.0
3.5 HOLE
5.0 70.0

8.9.2 Explanation of Format Elements

Initialization - Data Layout, Data Size, Hole Value

The first (non-comment) line must begin with either "ARRAY" or "GENERAL" followed by two integers specifying the number of series and the number of points in each series. For example:

# This is an Array data file containing 2 series of 4 points
ARRAY 2 4

The only difference with General data is that the second integer specifies the maximum number of points possible for each series:

# A General data file, 5 series, maximum 10 points
GENERAL 5 10

The second line can optionally specify a data hole value. A hole value is the number that is interpreted by the chart as missing data. There should be only one hole value per ChartDataView class. Use a hole value if you know that a particular value in the data should be ignored in the chart:

HOLE 10000

You can also indicate that any particular point is a hole by specifying the word "HOLE" for that X- or Y-value. For example:

50.0 75.0 HOLE 70.0

Note: If the hole value is later changed in the data view, values in the X- and Y-data previously set with hole values will not change their values and will now draw.

Adding Comments

You can use comments throughout the data file to make it easier for people to understand. Any text on a line following a "#" symbol are treated as comments and are ignored.

Point Labels

The third line can optionally specify text labels for each data point, which can be used to annotate the X-axis. Point-labels are generally only useful with Array data; if specified for General data they apply to the first series. The following shows how to specify Point-labels:

'Point 1' 'Point 2' 'Point 3' # Optional Point-labels

The Data - Array layout

The rest of the file contains the data to be charted. Array layout uses the first line of data as X-values that are common to all points. Subsequent lines specify the Y-values for each data series:

1.0 2.0 3.0 4.0 # X-values
150.0 175.0 160.0 170.0 # Y-values, series 0
125.0 100.0 225.0 300.0 # Y-values, series 1
# Y-values continue, until end of data

The Data - General layout

General layout provides more flexibility. For each series, the first line of data specifies the number of points in the series (this cannot be greater than the maximum number of points defined earlier). The second line specifies the X-values for that series; the third line specifies the Y-values:

4 # Series 0, 4 points
50.0 75.0 60.0 70.0 # X-values
25.0 10.0 25.0 30.0 # Y-values
# Next series follows, until end of data

Series Labels

You can optionally specify text labels for each series, which can be displayed in the legend. Series labels are enclosed in single-quotes. In Array data, the label appears at the start of each line of Y-values, for example:

'Series label' 150.0 175.0 160.0 170.0 # Y-values, series 0

In General data, the label appears at the start of the line defining the number of points in that series, for example:

'Series label' 4 # Series 0, 4 points
50.0 75.0 60.0 70.0 # X-values
25.0 10.0 25.0 30.0 # Y-values

Transposed Data

JClass Chart can also interpret transposed data, where the meaning of the data series and points is switched. Note that transposing data also transposes series and point labels. To indicate that the data is transposed, add a "T" to the first line specifying the data layout and size. The following illustrates how data is interpreted when transposed:

ARRAY 2 3 T
# X-values Y0-values Y1-values
1.0 150.0 125.0
2.0 175.0 100.0
3.0 160.0 225.0

8.10 Data Binding: Specifying Data from Databases

In order to chart data from a database, your application must be able to establish a connection, perform necessary queries on the data, and then put the data into a chartable format.

This type of database connectivity is often called `data binding' and components that can be connected to a database are considered `data bound'. JClass Chart is a data bound component.

Perhaps the easiest way to bind a chart to a database is to use one of the data binding Beans (DSdbChart or JBdbChart) in an IDE or the BeanBox. There are Beans for connecting to a database using Borland JBuilder and the JClass DataSource. See the Bean Reference for complete details on using these Beans in an IDE.

More complex chart features, however, can only be accessed programmatically. To do data binding programmatically, you can use one of the solutions listed in the table below:

Class

Use with:

JCChart

  • JDBCDataSource
  • An application that provides connection to database and passes an SQL result set to JCDBCDataSource
  • DSdbChart

  • JClass DataSource component
  • JBdbChart

  • Borland JBuilder 3.0+ components
  • The following sections provide a brief outline of these different data binding methods.

    8.10.1 Data Binding using JDBCDataSource

    JDBCDataSource is not a full data binding solution. It is a data source that you can use to chart data from an SQL Result Set. It does not perform any binding operations such as connecting to or querying the database. You will have to provide that functionality.

    To use it, you just attach an instance of JDBCDataSource to your chart and pass it a Result Set from your application, as follows:

    chart.getDataView(0).setDataSource(new JDBCDataSource(resultSet));

    8.10.2 Data Binding with JBuilder

    JBdbChart allows you to bind to JBuilder's DataSet, for a full data binding solution. The following example illustrates how to connect to the necessary JBuilder components:

    package examples.chart.db.jbuilder;

    import java.awt.*;
    import javax.swing.JFrame;
    import com.borland.dx.sql.dataset.*;

    import com.klg.jclass.chart.db.jbuilder.*;
    import com.klg.jclass.chart.db.DataBindingConfigWrapper;

    /**
    * This file was generated using JBuilder data binding. It is intended
     * to demonstrate the code generated when using JBuilder's
     * QueryDataSet and JBdbChart.
    *
    * (Code has been reindented to conform to Quest Software coding standard.)
    */
    public class JBuilderDBChart extends JFrame {

    Database database1= new Database();
    QueryDataSet queryDataSet1= new QueryDataSet();
    JBdbChart jBdbChart1= new JBdbChart();

    public JBuilderDBChart()
    {
      try {
        jbInit();
      }
      catch(Exception e) {
        e.printStackTrace();
      }
    }

    private void jbInit() throws Exception
    {
      QueryDescriptor qd =
        new  QueryDescriptor(database1,
          "SELECT OrderDetails.OrderDetailID,OrderDetails.OrderID," +
          "OrderDetails.ProductID,OrderDetails.DateSold," +
          "OrderDetails.Quantity,OrderDetails.UnitPrice," +
          "OrderDetails.SalesTax,OrderDetails.LineTotal " +
          "FROM OrderDetails",
          null, true, Load.ALL);
      queryDataSet1.setQuery(qd);
      ConnectionDescriptor cd=
        new ConnectionDescriptor("jdbc:odbc:JClassDemo", "dba", "sql", false, sun.jdbc.odbc.JdbcOdbcDriver");
      database1.setConnection(cd);
      jBdbChart1.setDataSet(queryDataSet1);
      DataBindingConfigWrapper cw=
        new DataBindingConfigWrapper(false, 0, 100, "OrderDetailID", new String[]{"UnitPrice", "SalesTax"});
      jBdbChart1.setDataBindingConfig(cw);
      this.getContentPane().add(jBdbChart1, BorderLayout.NORTH);
    }
    public static void main(String args[])
    {
      JBuilderDBChart f = new JBuilderDBChart();
      f.pack();
      f.show();
    }
    }

    8.10.3 Data Binding with JClass DataSource

    JClass DataSource is a full data binding solution. It is a robust hierarchical, multiple-platform data source that you can use to bind and query any JDBC compatible database. It can also bind to platform-specific data solutions in JBuilder.

    JClass DataSource is available only in JClass DesktopViews (which also contains JClass Chart, JClass Chart 3D, JClass Elements, JClass Field, JClass HiGrid, JClass JarMaster, JClass DataSource, and JClass PageLayout). Visit http://www.quest.com for information and downloads.

    To bind a chart to a database through JClass DataSource, use DSdbChart.

    The following example illustrates the main parts of binding with DSdbChart:

    package examples.chart.db.datasource;
    //JDK specific
    import java.awt.BorderLayout;
    import java.awt.Event;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;

    import javax.swing.JPanel;
    import javax.swing.JFrame;

    //JClass datasource specific
    import com.klg.jclass.datasource.TreeData;
    import com.klg.jclass.datasource.swing.DSdbJNavigator;
    import examples.datasource.jdbc.DemoData;

    //JClass Chart specific
    import com.klg.jclass.chart.JCAxis;
    import com.klg.jclass.chart.EventTrigger;
    import com.klg.jclass.chart.db.datasource.DSdbChart;

    import com.klg.jclass.util.swing.JCExitFrame;

    public class DataBoundChart extends JPanel {

    protected DSdbChart chart = null;
    protected DSdbJNavigator navigator = null;
    protected TreeData treeData = null;
    protected int currentRow = 0;

    public DataBoundChart() {
      setLayout(new BorderLayout());

      // Create DataSource data-bound Chart instance
      chart = new DSdbChart();
      // Chart formatting
      makeAFancyChart();

      // Create DataSource instance
    treeData = new DemoData();

      // Connect Chart instance to DataSource instance
      chart.setDataSource(treeData, "Orders|OrderDetails");
      // Select point label column from DataSource meta data
      chart.setPointLabelsColumn("OrderDetailID");
      chart.setName("Order Details");

      navigator = new DSdbJNavigator();
      navigator.setDataBinding(treeData, "Orders");

      add(navigator, BorderLayout.SOUTH);
      add(chart, BorderLayout.CENTER);
    }

    /**
    * Setting some of the chart parameters to make it look fancy
    */
    protected void makeAFancyChart()
    {
      JCAxis xAxis = chart.getChartArea().getXAxis(0);
      xAxis.setAnnotationMethod(JCAxis.POINT_LABELS);
      chart.getLegend().setVisible(true);
      chart.setForeground(java.awt.Color.yellow);
      chart.setBackground(java.awt.Color.gray);
      chart.getDataView(0).setChartType(DSdbChart.STACKING_AREA);
      chart.getHeader().setVisible(true);
      chart.getFooter().setVisible(true);

      String name = "com.klg.jclass.chart.customizer.ChartCustomizer";
      chart.setCustomizerName(name);
      chart.setAllowUserChanges(true);
      chart.setTrigger(0, new EventTrigger(Event.META_MASK, EventTrigger.CUSTOMIZE));
    }

    /**
    * main function
    */
    public static void main(String[] args)
    {
      DataBoundChart dbChart = new DataBoundChart();
      JCExitFrame frame = new JCExitFrame("This is a data bound chart");

      frame.getContentPane().add(dbChart);
      frame.pack();
      frame.setSize(500, 400);
      frame.show();
    }

    }

    8.11 Making Your Own Chart Data Source

    8.11.1 The Simplest Chart Data Source Possible

    In order for a data source object to work with JClass Chart, it must implement the ChartDataModel interface. The EditableChartDataModel interface is an extension of ChartDataModel and can be used when you want to allow the data source to be editable. The LabelledChartDataModel and the HoleValueChartDataModel interfaces can be used in conjunction with ChartDataModel to extend the functionality of ChartDataModel to allow for label values (via the LabelledChartDataModel interface) and hole values (via the HoleValueChartDataModel interface).

    The ChartDataModel interface is intended for use with existing data objects. It allows Chart to ask the data source for the number of data series, and the X-values and y-values for each data series. The interface looks like this:

    public double[] getXSeries(int index);
    public double[] getYSeries(int index);
    public int getNumSeries();

    Basically, JClass Chart organizes data based on data series. Each series has X-values and y values, returned by getXSeries() and getYSeries(), respectively. It is expected that, for a given series index, the X-series and Y-series will be the same length.

    If the X-data is the same for all Y-data, then the same X-series can be returned for each value. JClass Chart will automatically re-use the array.

    As an example, consider SimplestDataSource in the examples.chart.datasource example:

    /**
    * This example shows the simplest possible chart data source.
    * The data source contains two data series, held in "xvalues"
    * and "yvalues" below.
    */
    public class SimplestDataSource extends JPanel implements ChartDataModel {

    // X values for chart.
    protected double xvalues[] = { 1, 2, 3, 4 };
    // Y values.
    protected double yvalues[][] = { {20, 10, 30, 25}, {30, 22, 10, 40}};


    /**
    * Retrieves the specified x-value series
    * In this example, the same x values are used regardless of
    * the index.
    * @param index data series index
    * @return array of double values representing x-value data
    */
    public double[] getXSeries(int index) {
      return xvalues;
    }
    /**
    * Retrieves the specified y-value series
    * In this example, yvalues contains the y data.
    * @param index data series index
    * @return array of double values representing x-value data
    */
    public double[] getYSeries(int index) {
      return yvalues[index];
    }

    /**
    * Retrieves the number of data series.
    * In this example, there are only two data
    * series.
    */
    public int getNumSeries() {
      return yvalues.length;
    }

    There are two series in this example. The X-data is repeated for both series, and is stored in an array of doubles (xvalues). The Y-data is stored in an array of arrays of doubles (yvalues). Each sub-array is the same length as xvalues.

    Note: You can run this example from JCLASS_HOME/Examples/Chart/DataSource/SimplestDataSource.

    8.11.2 LabelledChartDataModel - Labelling Your Chart

    Sometimes it is important to label each data series and each point in a graph. This information can be added to a data source using the LabelledChartDataModel interface.

    The LabelledChartDataModel interface allows specification of series and point labels for your data. It is an optional part of the chart data model, but is very commonly used:

    public int getNumSeries();
    public String[] getPointLabels();
    public String[] getSeriesLabels();
    public String getDataSourceName();

    The getPointLabels() call returns the point labels for all points in the chart. The size of the String array should correspond with the number of items in the XSeries and YSeries arrays.

    The getSeriesLabels() call returns the series labels for the chart. The size of the String array should correspond to the value returned by getNumSeries(). Series labels appear in the legend.

    The getDataSourceName() returns the name of the data source. This appears in the chart as the title of the legend.

    As an example, consider LabelledDataSource in JCLASS_HOME/examples/chart/ datasource/.

    /**
    * This example shows how to add point and series labelling
    * to a data source. It extends SimplestDataSource and
    * implements the LabelledChartDataModel interface to add
    * this information. The result can be seen on the X-axis
    * (point labels representing quarters) and in the legend
    * (title, series names).
    */
    public class LabelledDataSource extends SimplestDataSource implements
    LabelledChartDataModel {

    // Point labels
    protected String pointLabels[] = { "Q1", "Q2", "Q3", "Q4" };

    // Series labels
    protected String seriesLabels[] = { "West", "East" };

    /*
    * Retrieves the labels to be used for each point in a
    * particular data series.
    * @return array of point labels
    */
    public String[] getPointLabels() {
      return pointLabels;
    }
    /**
    * Retrieves the labels to be used for each data series
    */
    public String[] getSeriesLabels() {
      return seriesLabels;
    }

    /**
    * Retrieves the name for the data source
    */
    public String getDataSourceName() {
      return "Sales By Region";
    }

    As noted, this data source extends SimplestDataSource, adding in the required methods for returning point labels - getPointLabels() - and series labels -getSeriesLabels().

    Note that the number of items in the array returned by getSeriesLabels() should equal the number returned by getNumSeries().

    Note that the number of items in the array returned by getPointLabels() should equal the number of items in the array returned by getXSeries() and getYSeries(). (In cases where the X-data is unique for each series and each series has a possibly different number of points, the point labels are applied to the first series.)

    Note: You can run this example from JCLASS_HOME/Examples/Chart/DataSource/LabelledDataSource.

    8.11.3 EditableChartDataModel - Modifying Your Data

    If you want to allow users to modify data using the edit trigger in JClass Chart, your data source must implement EditableChartDataModel. The EditableChartDataModel interface extends ChartDataModel, adding a single method that allows Chart to modify data in the data source:

    public boolean setDataItem(int seriesIndex, int pointIndex,
      double newValue);

    The seriesIndex and pointIndex values are used to save the data sent in newValue. Note that EditableChartDataModel only allows for Y-values to be changed. In other words, newValue is a Y-value!

    As an example, consider EditableDataSource in JCLASS_HOME/examples/chart/ datasource/.

    /**
    * This example shows how to make a data source editable
    * by adding the EditableChartDataModel interface to
    * the object.
    */
    public class EditableDataSource extends LabelledDataSource implements
    EditableChartDataModel {

    /**
    * Change the specified y data value.
    * In this example, the series and point indices index
    * into the yvalues array originally defined in SimplestDataSource.
    *
    * @param seriesIndex series index for the point to be changed.
    * @param pointIndex point index for the point to be changed.
    * @param newValue new y value for the specified point
    * @return boolean value indicating whether the new value was
    * accepted. "true" means value was accepted.
    */
    public boolean setDataItem(int seriesIndex, int pointIndex, double
                  newValue) {

      if (newValue < 0) return false;
      yvalues[seriesIndex][pointIndex] = newValue;
      return true;
    }

    In this example, the value is saved back into the yvalues array from SimplestDataSource, using the seriesIndex and pointIndex values to index to the appropriate array member.

    This example extends LabelledDataSource, adding the setDataItem() method to allow chart to modify the data in the data source.

    Note: You can run this example from JCLASS_HOME/Examples/Chart/DataSource/SimplestDataSource.

    8.11.4 HoleValueChartDataModel - Specifying Hole Values

    If you want to supply a specific hole value along with your data, your data source must implement the HoleValueChartDataModel interface.

    As noted in Section 8.9.2, Explanation of Format Elements, a hole value is a particular value in the data that should be ignored by the chart. There should be only one hole value per data source.

    The HoleValueChartDataModel interface has one method, getHoleValue(). This method retrieves the hole value for the data source.

    Note: The default hole value is Double.MAX_VALUE.


    8.12 Making an Updating Chart Data Source

    Quite often, the data shown in JClass Chart is dynamic. This kind of data requires creation of an updating data source. An updating data source is capable of informing chart that a portion of the data has been changed. Chart can then act on the change.

    JClass Chart uses the standard AWT/Swing event/listener mechanism for passing changes between the chart data source and JClass Chart. At a very high level, JClass Chart is a listener to data source events that are fired by the data source.

    8.12.1 Chart Data Source Support Classes

    There are a number of data source related support classes included with JClass Chart. These classes make it easier to build updating data sources.

    ChartDataEvent and ChartDataListener

    The ChartDataListener interface is implemented by objects interested in receiving ChartDataEvents. Most often, the only ChartDataListener is JClass Chart itself. ChartDataEvent and ChartDataListener give data sources away to send update messages to Chart.

    The ChartDataListener interface has only one method:

    public void chartDataChange(ChartDataEvent e);

    This method is used by the data source to inform the listener of a change. In most systems, only JClass Chart need implement this interface.

    The ChartDataEvent object has three immutable properties: Type, SeriesIndex, and PointIndex. SeriesIndex and PointIndex are used to specify the data affected by the posted change. If all data is affected, the enum values ALL_SERIES and ALL_POINTS can be used.

    Type is used to specify the kind of update:

    Message

    Meaning

    ADD_SERIES

    A new data series has been added to the end of the existing series in the data source.

    APPEND_DATA

    Used in conjunction with the FastUpdate feature, this tells the listener that data has been added to the existing series. Please see FastUpdate, in Chapter 10, for full details.

    CHANGE_CHART_TYPE

    A request from the data source to change the chart type. The chart type is held inside seriesIndex.

    INSERT_SERIES

    A new data series has been added; seriesIndex indicates where the series should be added.

    RELOAD

    The data has completely changed; the difference here is that the dimensions of the data source (that is, number of data series and number of points) has not changed.

    RELOAD_ALL_POINT_LABELS

    Tells the listener to reload all point labels.

    RELOAD_ALL_SERIES_LABLES

    Tells the listener to reload all series labels.

    RELOAD_DATA_SOURCE_NAME

    Tells the listener the data source name has changed.

    RELOAD_POINT

    Single data value has changed, as specified by seriesIndex and pointIndex.

    RELOAD_POINT_LABEL

    Tells the listener to reload the point label specified by pointIndex.

    RELOAD_SERIES

    An entire data series has changed, as specified by seriesIndex (pointIndex ignored).

    RELOAD_SERIES_LABEL

    Tells the listener to reload the series label specified by seriesIndex.

    REMOVE_SERIES

    Removes the series at seriesIndex.

    RESET

    The data source has completely changed.

    ChartDataManageable and ChartDataManager

    This interface is used by a data source to tell Chart that it will be sending ChartDataEvents to Chart. Without this interface, there is no way for Chart to know that it has to attach itself as a ChartDataListener to the data source.

    The only method in ChartDataManageable returns a ChartDataManager:

    public abstract ChartDataManager getChartDataManager();

    A ChartDataManager is an object that knows how to register and deregister ChartDataListeners. Chart uses this object to register itself as a listener to events from the data source.

    The quickest way to get a data source set up is to extend or use ChartDataSupport.

    ChartDataSupport

    ChartDataSupport provides a default implementation of ChartDataManager. It will manage a list of ChartDataListeners. It also provides two convenience methods for firing events to the listeners:

    public void fireChartDataEvent(int type, int seriesIndex, int
      pointIndex)

    public void fireChartDataEvent(ChartDataEvent evt)

    The first method listed above is the most convenient. Given a ChartDataEvent Type, SeriesIndex, and PointIndex, it constructs and fires a ChartDataEvent to all listeners. The second method requires that you construct the ChartDataEvent yourself.

    Creating an Updating Data Source

    If your datasource either extends or contains ChartDataSupport, sending updates from the data source to the chart is easy. Simple call fireChartDataEvent() with the event you wish to send.

    fireChartDataEvent(ChartDataEvent.RESET, 0, 0);

    To have JClass Chart automatically added as a listener, your data source needs to implement the ChartDataManageable interface and to return the ChartDataSupport instance in the getChartDataManager() method.

    Chart Data Source Hierarchy


    PreviousNextIndex