倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

GroovyChart と戯れて (8) : データをビルダーで構築する

さて前回、データとビューの構築を分離する方法を見ましたが、折角 ChartBuilder を使うなら、ビューだけでなくデータ (dataset) もこれを使って構築したいというのは人情(ならぬ「Groovier 情」?)。

ってことで、今回はチャートのビューとは別に ChartBuilder でデータを構築する方法を見ていきます。

ChartBuilder でデータを構築する


まぁ、ビルダーの性質上、chart ノード(今までのサンプルでは xyareachart ノード)下でなくても、普通に ChartBuilder を使ってデータを構築できちゃうんですけど:

def builder = new ChartBuilder()
def dataset = builder.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))
        }
    }

それなら、「前回やっとけよ」と言われそうですが、そうは豚屋がおろさない。 というのは、「GroovyChart は JFreeChart のラッパーだ」ってことからくるんですが、上記の dataset オブジェクトは「JFreeChart オブジェクトではなく、そのラッパークラスのオブジェクトだ」ということです。

まぁ、チャートを構築したときも同じようなことになってたので、解決の方法も予想ができて、ChartBuilder が返すオブジェクトに対して「dataset プロパティ」を取得すれば、JFreeChart の Dataset オブジェクトが得られます。

def builder = new ChartBuilder()
def dataset = builder.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))
        }
    }

assert dataset.dataset instanceof Dataset

ビルダー実装の演習 その2


以前に「JFreeChart オブジェクトを返す ChartBuilder のサブクラス」を簡単に実装しましたが、それと同じように JFreeChart の Dataset を返す ChartBuilder のサブクラスも実装してみましょう。

まぁ、基本的には前にやったことと同じように postNodeCompletion() メソッドをオーバーライドするだけです。 GroovyChart での dataset のラッパークラス(のスーパークラス)は BaseDatasetBuilder 型のようなので、構築したノードがこの型のときに「dataset プロパティ」を返すようにします。

ただ1つ問題なのは、普通に chart ノード下でデータセットを構築する際には、データセットのラッパーを返さなければならないことです。 これは、構築しているノードがルートノードかどうか(親ノードがあるかないか)で判断します。

実装はこんな感じ:

class MyChartBuilder extends ChartBuilder{

    @Override
    protected Object postNodeCompletion(parent, node) {
        def result = super.postNodeCompletion(parent, node)

        if(parent == null){
            if(node instanceof BaseChart)
                return result.chart
            else if(node instanceof BaseDatasetBuilder)
                return result.dataset
            else
                return result
        }else{
            return result
        }
    }
}

ここではルートノードが BaseChart (JFreeChart のラッパークラス)なら JFreeChart を返すようにもしています。 まぁ、上記の説明ほど複雑ではないかと。

Groovyイン・アクション

Groovyイン・アクション