|
|
JFreeChart を使ったグラフ作成 グラフ作成の手順 |
H.Kamifuji . |
ここではJFreeChartを使ったグラフ作成までの手順を簡単に確認していきます。 当ページでは、Linux CentOS7 の Gnome で動作テストしています。 現在(2021/08)では、JDK-16.0.2 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2023/04)では、JDK-20.0.1 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2024/10)では、JDK-23 に、jfreechart-1.5.5 にアップされています。一部、上位互換について、見直しを行っていきます。 .png 画像データ作成時に実行時エラーが発生する。jfreechart-1.0.19 で、実行してください。 現在(2024/10)では、JDK-23 に、アップされています。JDK-23 + jfreechart-1.0.19 で、上位互換について、見直しを行っていきます。 |
|
グラフ全体を表すオブジェクトはJFreeChartクラスのオブジェクトになります。JFreeChartクラスのオブジェクトに対して、グラフ領域を表すオブジェクト、軸を表すオブジェクト、凡例を表すオブジェクトなどを追加していくことになります。 JFreeChartクラスのクラス図は次のようになっています。 java.lang.Object | +-- org.jfree.chart.JFreeChart public class JFreeChart extends java.lang.Object implements org.jfree.ui.Drawable, TitleChangeListener, PlotChangeListener, java.io.Serializable, java.lang.Cloneable用意されているコンストラクタは次の3つです。
1番目のコンストラクタでは引数にグラフ領域を扱うPlotクラスのオブジェクトを指定します。ここで指定されたPlotクラスのオブジェクトを元にグラフを作成することになります。2番目と3番目ではグラフのタイトルや軸に関する追加の引数を指定します。 それでは1番目のコンストラクタを確認してみます。 JFreeChart public JFreeChart(Plot plot)Creates a new chart based on the supplied plot. The chart will have a legend added automatically, but no title (although you can easily add one later). Note that the ChartFactory class contains a range of static methods that will return ready-made charts, and often this is a more convenient way to create charts than using this constructor. Parameters: plot - the plot (null not permitted). 引数に指定したPlotクラスのオブジェクト元にJFreeChartクラスのオブジェクトを作成します。実際にはコンストラクタからオブジェクトを作成するのではなく、別途グラフ毎に用意されたファクトリメソッドを使ってオブジェクトを作成することになります。ファクトリメソッドについては別のページで確認します。 実際の使い方は次のようになります。 JFreeChart chart = new JFreeChart(new Plot());PlotクラスはAbstractクラスなので、実際にはオブジェクトを直接作成することが出来ませんのでエラーとなります。その為、引数にはPlotクラスを実装したクラスか、用意されているPlotクラスのサブクラスを使用することになります。詳細は次項のページで確認します。 |
グラフ全体を表すJFreeChartクラスのオブジェクトの中にはグラフのタイトルやグラフの凡例の他に実際にグラフが描かれる描画領域が含まれます。グラフの描画領域はPlotクラスを使用します。 Plotクラスのクラス図は次のようになっています。 java.lang.Object | +-- org.jfree.chart.plot.Plot public abstract class Plot extends java.lang.Object implements AxisChangeListener, DatasetChangeListener, MarkerChangeListener, LegendItemSource, org.jfree.util.PublicCloneable, java.lang.Cloneable, java.io.SerializablePlotクラスはAbstractクラスですので、実際にはグラフの種類毎に用意されているサブクラスを使用します。用意されているサブクラスには次のようなものがあります。 CategoryPlot CompassPlot ContourPlot DialPlot FastScatterPlot MeterPlot MultiplePiePlot PiePlot PolarPlot SpiderWebPlot ThermometerPlot WaferMapPlot XYPlotここでは例として円がラフを作成してみます。円グラフの場合は「PiePlot」クラスを使用します。(PiePlotクラスについての詳細は別のページで行います)。 PiePlotクラスのコンストラクタの1つは次のようになっています。 PiePlot public PiePlot(PieDataset dataset)Creates a plot that will draw a pie chart for the specified dataset. Parameters: dataset - the dataset (null permitted). 引数にはグラフの元になるデータを表すPieDatasetインターフェースを実装したクラス(例えばDefaultPieDatasetクラス)のオブジェクトを指定します。(データについては次のページの「グラフのデータ」を参照して下さい)。 実際には次のように記述します。 DefaultPieDataset data = new DefaultPieDataset(); PiePlot plot = new PiePlot(data); JFreeChart chart = new JFreeChart(plot);上記ではグラフのデータを表すDefaultPieDatasetクラスのオブジェクトを作成し、そのオブジェクトを引数に指定してPiePlotクラスのオブジェクトを作成します。そして今度はPiePlotクラスのオブジェクトを引数にしてJFreeChartクラスのオブジェクトを作成します。 では簡単なサンプルを作成して試してみます。 サンプルプログラム下記のサンプルを実行してみよう。/** * グラフの描画領域 */ import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PiePlot; import org.jfree.data.general.DefaultPieDataset; import org.jfree.chart.ChartUtilities; import java.io.File; import java.io.IOException; public class Test2_1{ public static void main(String[] args) { DefaultPieDataset data = new DefaultPieDataset(); JFreeChart chart = new JFreeChart(new PiePlot(data)); File file = new File("./test2_1.png"); try { ChartUtilities.saveChartAsPNG(file, chart, 300, 300); } catch (IOException e) { e.printStackTrace(); } } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Ini]$ javac Test2_1.java [xxxxxxxx@dddddddddd Ini]$ java Test2_1 [xxxxxxxx@dddddddddd Ini]$JDK-23 + jfreechart-1.5.5 では、下記の実行時エラーが発生しました。 [xxxxxxxx@dddddddddd Wrapper_class]$ javac JSample4_1.java Exception in thread "main" java.lang.NoClassDefFoundError: org/jfree/chart/ChartUtilities at Test2_1.main(Test2_1.java:19) Caused by: java.lang.ClassNotFoundException: org.jfree.chart.ChartUtilities at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:528) ... 1 more [xxxxxxxx@dddddddddd Wrapper_class]$「File」から下の行はまだ解説していませんが、作成したJFreeChartクラスのオブジェクトを使って作成したグラフをPNG画像として保存するためのものです。プログラムを実行すると「test2_1.png」と言うファイルが作成されています。 ![]() まだグラフのデータなどを指定していませんので枠が表示されているだけです。 |
グラフの領域には様々な設定が行えますが、まず行うのはグラフのデータの設定です。PiePlotクラスのコンストラクタの引数には円グラフのデータを表すPieDatasetインターフェースを実装したクラスのオブジェクトを指定します。 PieDatasetインターフェースは次のように定義されています。 public interface PieDataset extends KeyedValues, DatasetPieDatasetインターフェースを実装したクラスは次のようなものがあります。 CategoryToPieDataset DefaultKeyedValuesDataset DefaultPieDataset JDBCPieDatasetここでは例として「DefaultPieDataset」クラスを使ってみます。 DefaultPieDatalotクラスDefaultPieDataクラスのクラス図は次のようになっています。java.lang.Object | +-- org.jfree.data.general.AbstractDataset | +-- org.jfree.data.general.DefaultPieDataset public class DefaultPieDataset extends AbstractDataset implements PieDataset, java.lang.Cloneable, org.jfree.util.PublicCloneable, java.io.Serializable用意されているコンストラクタは次の2つです。
2番目は他のデータからデータをコピーして使用する場合のコンストラクタです。では1番目のコンストラクタを確認してみます。 DefaultPieDataset public DefaultPieDataset()Constructs a new dataset, initially empty. 引数にはグラフの元になるデータを表すPieDatasetインターフェースを実装したクラス(例えばDefaultPieDatasetクラス)のオブジェクトを指定します。 実際の使い方は次のようになります。 DefaultPieDataset data = new DefaultPieDataset(); JFreeChart chart = new JFreeChart(new PiePlot(data)); データの登録DefaultPieDatasetクラスのオブジェクトを作成したら、グラフのデータを登録して行きます。DefaultPieDatasetクラスで用意されている「setValue」メソッドを使います。setValue public void setValue(java.lang.Comparable key, java.lang.Number value)Sets the data value for a key and sends a DatasetChangeEvent to all registered listeners. Parameters: key - the key (null not permitted). value - the value. Throws: java.lang.IllegalArgumentException - if key is null. 「setValue」メソッドでは2つの引数を指定します。グラフの項目となる「key」と、その項目の値である「value」です。1番目の引数である「java.lang.Comparable」はインターフェースであり実装したクラスとしては「Integer」クラスや「String」クラスがあります。 例えば次のように記述します。 DefaultPieDataset data = new DefaultPieDataset(); data.setValue("支持する", 56); data.setValue("支持しない", 41); data.setValue("未回答", 3); JFreeChart chart = new JFreeChart(new PiePlot(data));この場合は3つのデータを持つ円グラフを作成しています。 では簡単なサンプルを作成して試してみます。 サンプルプログラム下記のサンプルを実行してみよう。/** * グラフのデータ */ import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PiePlot; import org.jfree.data.general.DefaultPieDataset; import org.jfree.chart.ChartUtilities; import java.io.File; import java.io.IOException; public class Test3_1{ public static void main(String[] args) { DefaultPieDataset data = new DefaultPieDataset(); data.setValue("支持する", 56); data.setValue("支持しない", 41); data.setValue("未回答", 3); JFreeChart chart = new JFreeChart(new PiePlot(data)); File file = new File("./test3_1.png"); try { ChartUtilities.saveChartAsPNG(file, chart, 300, 300); } catch (IOException e) { e.printStackTrace(); } } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Ini]$ javac Test3_1.java [xxxxxxxx@dddddddddd Ini]$ java Test3_1 [xxxxxxxx@dddddddddd Ini]$JDK-23 + jfreechart-1.5.5 では、下記の実行時エラーが発生しました。 [xxxxxxxx@dddddddddd Wrapper_class]$ javac JSample4_1.java Exception in thread "main" java.lang.NoClassDefFoundError: org/jfree/chart/ChartUtilities at Test3_1.main(Test3_1.java:23) Caused by: java.lang.ClassNotFoundException: org.jfree.chart.ChartUtilities at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:528) ... 1 more [xxxxxxxx@dddddddddd Wrapper_class]$今回も作成したJFreeChartクラスのオブジェクトを使って作成したグラフをPNG画像として保存しています。プログラムを実行すると「test3_1.png」と言うファイルが作成されています。 ![]() 追加したデータが円グラフの中に表示されているのと同時に自動的に凡例も作成されて表示されています。 |
ここまでは使用したいグラフの種類に合わせてPlotクラスのサブクラスのオブジェクトを元にJFreeChartクラスのオブジェクトを作成してきました。今度はユーティリティクラスであるChartFactoryクラスを使ったグラフの作成方法を確認してみます。 ChartFactoryクラスではJFreeChartクラスのオブジェクトを作成するためのファクトリメソッドが数多く用意されています。 ChartFactoryクラスのクラス図は次のように定義されています。 java.lang.Object | +-- org.jfree.chart.ChartFactorzy public abstract class ChartFactory extends java.lang.Objectコンストラクタは使用せず、各グラフ毎に用意されたスタティックメソッドを使います。次のようなメソッドが用意されています。 createAreaChart createBarChart createBarChart3D createBoxAndWhiskerChart createBubbleChart createCandlestickChart createGanttChart createHighLowChart createHistogram createLineChart createLineChart3D createMultiplePieChart createMultiplePieChart3D createPieChart createPieChart3D createPolarChart createRingChart createScatterPlot createStackedAreaChart createStackedBarChart createStackedBarChart3D createStackedXYAreaChart createTimeSeriesChart createWaferMapChart createWaterfallChart createWindPlot createXYAreaChart createXYBarChart createXYLineChart createXYStepAreaChart createXYStepChart各メソッドはJFreeChartクラスのオブジェクトを返してくれます。それでは円グラフを作成するための「createPieChart」メソッドを見てみます。 createPieChart public static JFreeChart createPieChart(java.lang.String title, PieDataset dataset, boolean legend, boolean tooltips, boolean urls)Creates a pie chart with default settings. The chart object returned by this method uses a PiePlot instance as the plot. Parameters: title - the chart title (null permitted). dataset - the dataset for the chart (null permitted). legend - a flag specifying whether or not a legend is required. tooltips - configure chart to generate tool tips? urls - configure chart to generate URLs? Returns: A pie chart. 引数にはタイトルやデータなどの必要な情報を指定してメソッドを実行すると結果としてJFreeChartクラスのオブジェクトを取得できます。なお4番目と5番目の引数はグラフを画像として出力する場合は気にしないで結構です。 実際の使い方は次のようになります。 DefaultPieDataset data = new DefaultPieDataset(); data.setValue("支持する", 56); data.setValue("支持しない", 41); data.setValue("未回答", 3); JFreeChart chart = ChartFactory.createPieChart("Title", data, true, false, false);数多くのファクトリメソッドが用意されていますので、ほとんどの場合はChartFactoryクラスの各メソッドを使ってJFreeChartクラスのオブジェクトを作成することになります。 では簡単なサンプルを作成して試してみます。 サンプルプログラム下記のサンプルを実行してみよう。/** * ファクトリメソッドを使ったJFreeChartクラスのオブジェクト作成 */ import org.jfree.chart.JFreeChart; import org.jfree.chart.ChartFactory; import org.jfree.data.general.DefaultPieDataset; import org.jfree.chart.ChartUtilities; import java.io.File; import java.io.IOException; public class Test4_1{ public static void main(String[] args) { DefaultPieDataset data = new DefaultPieDataset(); data.setValue("支持する", 56); data.setValue("支持しない", 41); data.setValue("未回答", 3); JFreeChart chart = ChartFactory.createPieChart("Title", data, false, false, false); File file = new File("./test4_1.png"); try { ChartUtilities.saveChartAsPNG(file, chart, 300, 300); } catch (IOException e) { e.printStackTrace(); } } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Ini]$ javac Test4_1.java [xxxxxxxx@dddddddddd Ini]$ java Test4_1 [xxxxxxxx@dddddddddd Ini]$JDK-23 + jfreechart-1.5.5 では、下記の実行時エラーが発生しました。 [xxxxxxxx@dddddddddd Wrapper_class]$ javac JSample4_1.java Exception in thread "main" java.lang.NoClassDefFoundError: org/jfree/chart/ChartUtilities at Test4_1.main(Test4_1.java:24) Caused by: java.lang.ClassNotFoundException: org.jfree.chart.ChartUtilities at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:528) ... 1 more [xxxxxxxx@dddddddddd Wrapper_class]$今回も作成したJFreeChartクラスのオブジェクトを使って作成したグラフをPNG画像として保存しています。プログラムを実行すると「test4_1.png」と言うファイルが作成されています。 ![]() 今回はタイトルも表示されています。逆に凡例は非表示としました。前項のページのグラフと見比べて見てください。 |
|