GroovyChart の ChartBuilder は JFreeChart (JFreeChart のチャートを表す型)オブジェクトを構築するのではなく、そのラッパークラスを構築します。 これは、それほど気にすることでもありませんが、JFrame などに埋め込むために ChartPanel を生成しようとすると、ビルダーの構築結果のオブジェクトに対して「chart プロパティ」にアクセスして JFreeChart オブジェクトを取得する必要があります(以前の記事参照)。
まぁ、「そういうものだ」と思って使い方を覚えてしまってもいいんですが、やはり直感的にはビルダーの構築結果が JFreeChart オブジェクトであった方が自然な感じがします。
今回は、ChartBuilder のサブクラスでちょこっとメソッドをオーバライドすることによって、これを実現する方法を見ていきます。 GroovyChart がどうこうというより、ビルダー実装の演習みたいな回です。
JFreeChart を返す ChartBuilder のサブクラスを作ってみる
ノードを構築した結果返されるオブジェクトを操作したい場合は、postNodeCompletion() メソッドをオーバーライドすると良さそうです(nodeCompletion() メソッドは返り値が void なので、今回の目的には合いません)。
GroovyChart では JFreeChart のラッパークラスは BaseChart クラス*1のようなので、引数 node がこのオブジェクトの時に、chart プロパティを取得して返すようにします。 それ以外の時はスーパークラスの処理そのままにします:
class MyChartBuilder extends ChartBuilder{ @Override protected Object postNodeCompletion(parent, node) { def result = super.postNodeCompletion(parent, node) if(node instanceof BaseChart) return result.chart else return result } }
実装はこれだけ。
使い方
で、実際にこのクラスを使ってみると
def builder = new MyChartBuilder() def chart = builder.xyareachart( title:'BMI Index Graph', XAxisLabel: 'weight (Kg)', YAxisLabel: 'height (m)', orientation:PlotOrientation.VERTICAL) { xyseries { for(int weight = 0; weight < 150; weight += 10) { point('Overweight', x: weight, y: sqrt(weight / 35.0d)) point('Normal', x: weight, y: sqrt(weight / 25.0d)) point('Underweight', x: weight, y: sqrt(weight / 18.0d)) } } xyplot { foregroundAlpha(1.0f) } } assert chart instanceof JFreeChart // chart は JFreeChart インスタンス def chartPanel = new ChartPanel(chart)
という感じで、ビルダーの構築結果が JFreeChart オブジェクトになってます。 めでたし、めでたし。
- 作者: Dierk Konig,Andrew Glover,Paul King,Guillaume Laforge,Jon Skeet,杉浦孝,櫻井正樹,須江信洋,関谷和愛,佐野徹郎,寺沢尚史
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2008/09/27
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 146回
- この商品を含むブログ (121件) を見る
*1:XYAreaChart の継承関係は「BeanBuilder ← BaseChart ← BasicChart ← XYChart ← XYAreaChart」となっているようです。