EspressChartは複数のグラフを系列として一つのチャートプロットに描画します。このため通常はチャートを作成してエクスポートすると一つのチャートプロットのみがキャンバス上に描画されます。

今回はチャート自体やチャートプロットをAPIで複数描画する手法を紹介します。
チャートを並べて描画
複数のチャートを描画したいといったケースで、単純にキャンバスまで含めて、複数のチャートを並べた画像を作成するといった場合であれば、drawメソッドを用いて、Graphics上にチャートを描画することで対応できます。
draw(java.awt.Graphics g, java.awt.Component component, int width, int height)
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import quadbase.ChartAPI.*;
public class LinedUpChart {
public static void main(String[] args){
// EspressManagerを使用しない、エクスポートのみ
QbChart.setEspressManagerUsed(false);
QbChart.setForExportOnly(true);
// 適当なソースデータを作成
String records[][] = {
{ "ABC","2020-05-01","1"},
{ "ABC","2020-06-01","2"},
{ "ABC","2020-07-01","3" },
};
String dataType[] = {"varchar", "date", "int"};
String fieldName[] = {"Series", "month", "Y"};
DbData data = new DbData(dataType, fieldName, records);
ColInfo col = new ColInfo();
col.value=2;
col.series=0;
col.category=1;
Applet parent = null;
// 適当な折れ線チャートを作成
QbChart chart1 = new QbChart(parent,
QbChart.VIEW2D,
QbChart.LINE,
data,
col,
null);
// 適当な縦棒チャートを作成
QbChart chart2 = new QbChart(parent,
QbChart.VIEW2D,
QbChart.COL,
data,
col,
null);
// 適当なエリアチャートを作成
QbChart chart3 = new QbChart(parent,
QbChart.VIEW2D,
QbChart.AREA,
data,
col,
null);
// 適当な横棒チャートを作成
QbChart chart4 = new QbChart(parent,
QbChart.VIEW2D,
QbChart.BAR,
data,
col,
null);
// BufferedImageからGraphicsを取得
BufferedImage img = new BufferedImage(1200,600,BufferedImage.TYPE_INT_BGR);
Graphics g = img.getGraphics();
// Graphicsの原点をずらしながらチャートを描画
chart1.draw(g, chart1, 600, 300);
g.translate(0, 300);
chart2.draw(g, chart2, 600, 300);
g.translate(600, -300);
chart3.draw(g, chart3, 600, 300);
g.translate(0, 300);
chart4.draw(g, chart4, 600, 300);
g.dispose();
//画像出力
try {
ImageIO.write(img, "png", new File("LinedUpChart.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
出力画像:

チャートの前後に描画
そうではなく、キャンバス上にチャートプロットの前後を意識して他のチャートや図形などを描画したいといったケースですと、IChartGraphicsインターフェイスを使用します。
initializeGraphicsメソッドとfinalizeGraphicsメソッドを定義し、そこでキャンバスの描画後に、initializeGraphicsメソッドのGraphicsを、チャートプロットの描画後にfinalizeGraphicsを描画するように構成できます。
チャート描画後:finalizeGraphics
チャートプロット:Chart Plot
チャート描画前:initializeGraphics
キャンバス:Canvas
これにより、以下のようなチャートに対して、
before.png

追加のチャートや図形をチャートプロットのレイヤーを意識して配置することが可能です。
after.png

import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.io.IOException;
import quadbase.ChartAPI.*;
import quadbase.util.*;
public class IChartGraphicsDemo {
public static void main(String[] args){
// EspressManagerを使用しない、エクスポートのみ
QbChart.setEspressManagerUsed(false);
QbChart.setForExportOnly(true);
// 適当な折れ線チャートを作成
String records[][] = {
{ "ABC","2020-05-01","1"},
{ "ABC","2020-06-01","2"},
{ "ABC","2020-07-01","3" },
};
String dataType[] = {"varchar", "date", "int"};
String fieldName[] = {"Series", "month", "Y"};
DbData data = new DbData(dataType, fieldName, records);
ColInfo col = new ColInfo();
col.value=2;
col.series=0;
col.category=1;
Applet parent = null;
QbChart chart = new QbChart(parent,
QbChart.VIEW2D,
QbChart.LINE,
data,
col,
null);
// キャンバスの色、サイズを指定
ICanvas canvas = chart.gethCanvas();
canvas.setBackgroundVisible(true);
canvas.setBackgroundColor(Color.LIGHT_GRAY);
canvas.setSize(new Dimension(1200,900));
// チャートプロットの位置やサイズ、背景色を調整
IPlot plot=chart.gethChartPlot();
plot.setPosition(new Position(0.1f,0.2f));
plot.setRelativeHeight(0.7f);
plot.setRelativeWidth(0.7f);
plot.setBackgroundVisible(true);
// チャートプロットの背景色はレイヤーがわかるよう透過した赤に設定
plot.setBackgroundColor(new Color(255, 0, 0, 128));
// 比較用にGraphicsを描画前にチャートをエクスポート
try {
chart.export(QbChart.PNG,"before.png");
} catch (IOException e) {
e.printStackTrace();
}
// 前後Graphicsの描画を追加
chart.setChartGraphics(new chartGenerationGraphics());
// 前後Graphics描画後のチャートをエクスポート
try {
chart.export(QbChart.PNG,"after.png");
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import quadbase.ChartAPI.*;
import quadbase.util.*
public class chartGenerationGraphics implements IChartGraphics {
// チャート描画前に描画するGraphics
public void initializeGraphics(Graphics g, int w, int h) {
// 適当な縦棒チャートを作成
QbChart.setEspressManagerUsed(false);
QbChart.setForExportOnly(true);
String records[][] = {
{ "ABC","2020-05-01","1"},
{ "ABC","2020-06-01","2"},
{ "ABC","2020-07-01","3" },
};
String dataType[] = {"varchar", "date", "int"};
String fieldName[] = {"Series", "month", "Y"};
DbData data = new DbData(dataType, fieldName, records);
ColInfo col = new ColInfo();
col.value=2;
col.series=0;
col.category=1;
Applet parent = null;
QbChart chart = new QbChart(parent,
QbChart.VIEW2D,
QbChart.COL,
data,
col,
null);
// キャンバスの色を指定
ICanvas canvas = chart.gethCanvas();
canvas.setBackgroundVisible(true);
canvas.setBackgroundColor(Color.green);
// Graphicsの原点を移動
int x = 300;
int y = 50;
g.translate(x, y);
// Graphics上にサイズ指定してチャートを描画
chart.draw(g, chart, 300, 300);
// Graphicsの原点を元に戻す
g.translate(-x, -y);
// 追加で円とテキストを描画
g.setColor(Color.green);
g.fillOval(900, 650, 100, 100);
g.drawString("チャート描画前", 900, 650);
}
// チャート描画後に描画するGraphics
public void finalizeGraphics(Graphics g, int w, int h) {
QbChart.setEspressManagerUsed(false);
QbChart.setForExportOnly(true);
// 適当なエリアチャートを作成
String records[][] = {
{ "ABC","2020-05-01","1"},
{ "ABC","2020-06-01","2"},
{ "ABC","2020-07-01","3" },
};
String dataType[] = {"varchar", "date", "int"};
String fieldName[] = {"Series", "month", "Y"};
DbData data = new DbData(dataType, fieldName, records);
ColInfo col = new ColInfo();
col.value=2;
col.series=0;
col.category=1;
Applet parent = null;
QbChart chart = new QbChart(parent,
QbChart.VIEW2D,
QbChart.AREA,
data,
col,
null);
// キャンバスの色を指定
ICanvas canvas = chart.gethCanvas();
canvas.setBackgroundVisible(true);
canvas.setBackgroundColor(Color.blue);
// Graphicsの原点を移動
int x = 600;
int y = 50;
g.translate(x, y);
// Graphics上にサイズ指定してチャートを描画
chart.draw(g, chart, 300, 300);
// Graphicsの原点を元に戻す
g.translate(-x, -y);
// 追加で円とテキストを描画
g.setColor(Color.blue);
g.fillOval(900, 450, 100, 100);
g.drawString("チャート描画後", 900, 450);
}
}
チャートプロット自体に追加
また、チャートプロット上に別のチャートをsetAddOnChart(QbChart[] qbCharts)で重ねることも可能です。これ自体は各チャートで2nd valueを指定する、オーバレイチャートで始めから複数チャートを重ねるように構成することでも実現できますが、はじめから複数のチャートを重ねる前提で作成する必要があります。
それに対して、setAddOnChartメソッドを使用した方法ですと、すでに作成したチャートに対して、後からチャートプロットのみを追加できますので、プログラム上で動的にチャートプロットを増やすような場合にも便利です。
加えてsetAddOnChartの重ね合わせの場合、以下のような特徴があります。
- 重ねられる対象となるチャートの凡例や軸ラベル、その他追加オブジェクトのみが反映される
- 値の軸スケールは共有
- カテゴリの軸は共有されない
つまり下記のような3つのチャートがあり、chart1に対して、chat2、chart3をsetAddOnChartで重ねると、
chart1.png

chart2.png

chart3.png

以下のようにchart1の軸や凡例、追加作成したオブジェクトのみが残り、chart2,chart3はデータプロットのみが重なることになります。

重なる順番としてはchart1でsetAddOnChartしているので、それが一番下に、あとは配列で指定した順番で重なります。
さらに、カテゴリ軸は共有されていないので、chart2とchart3に関してはデータポイントがカテゴリの位置にきていません。位置を合わせるためにはカテゴリの順番と個数を合わせてものを重ね合わせる必要があることにご注意ください。
import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.io.IOException;
import quadbase.ChartAPI.*;
import quadbase.util.*;
public class setAddOnChartDemo {
public static void main(String[] args){
// EspressManagerを使用しない、エクスポートのみ
QbChart.setEspressManagerUsed(false);
QbChart.setForExportOnly(true);
String dataType[] = {"varchar", "date", "int"};
String fieldName[] = {"Series", "month", "Y"};
ColInfo col = new ColInfo();
col.value=2;
col.series=0;
col.category=1;
Applet parent = null;
// 適当なソースデータを作成
String records1[][] = {
{ "ABC","2020-04-01","7" },
{ "ABC","2020-05-01","9"},
{ "ABC","2020-06-01","6"},
{ "ABC","2020-07-01","15" },
};
DbData data = new DbData(dataType, fieldName, records1);
// 適当な折れ線チャートを作成
QbChart chart1 = new QbChart(parent,
QbChart.VIEW2D,
QbChart.LINE,
data,
col,
null);
// 色を調整、データポイントを表示
IDataPointSet datapoint1 = chart1.gethDataPoints();
datapoint1.setColors(new Color[] {new Color(255, 0, 0, 255)});
datapoint1.setPointsVisible(true);
// 重なるチャートにも対応できるようにY軸を調整
IAxis yaxis1 = chart1.gethYAxis();
yaxis1.setScaleAutomatic(false);
yaxis1.setMaxScale(30);
yaxis1.setScaleStep(5);
// 灰色でコントロールレンジを描画
ControlRange cr = new ControlRange(25,27,Color.gray,"RangeB",false);
cr.setScale2Enabled(true);
cr.setStartScale2(1.2);
cr.setEndScale2(1.5);
IControlRangeSet crset = chart1.gethControlRanges();
crset.addElement(cr);
//chart1の画像出力
try {
chart1.export(QbChart.PNG,"chart1.png",600,300);
} catch (IOException e) {
e.printStackTrace();
}
// ソースデータを変更
String records2[][] = {
{ "DEF","2020-05-01","30"},
{ "DEF","2020-06-01","20"},
{ "DEF","2020-07-01","10" },
};
data = new DbData(dataType, fieldName, records2);
// 適当な縦棒チャートを作成
QbChart chart2 = new QbChart(parent,
QbChart.VIEW2D,
QbChart.COL,
data,
col,
null);
// 色を調整、データポイントを表示
IDataPointSet datapoint2 = chart2.gethDataPoints();
datapoint2.setColors(new Color[] {new Color(0, 255, 0, 255)});
datapoint2.setPointsVisible(true);
// 赤色の水平線を描画
IDataLineSet lineset = chart2.gethDataLines();
IHorzVertLine hline = lineset.newHorzVertLine
(IHorzVertLine.HORIZONTAL_LINE, "水平線");
hline.setLineValue(15.0);
hline.setColor(Color.red);
lineset.add(hline);
//chart2の画像出力
try {
chart2.export(QbChart.PNG,"chart2.png",600,300);
} catch (IOException e) {
e.printStackTrace();
}
// ソースデータを変更
String records3[][] = {
{ "GHI","2020-05-01","10"},
{ "GHI","2020-06-01","1"},
{ "GHI","2020-07-01","3" },
{ "GHI","2020-08-01","15" },
{ "GHI","2020-09-01","5" },
};
data = new DbData(dataType, fieldName, records3);
// 適当なエリアチャートを作成
QbChart chart3 = new QbChart(parent,
QbChart.VIEW2D,
QbChart.AREA,
data,
col,
null);
// 色を調整、データポイントを表示
IDataPointSet datapoint3 = chart3.gethDataPoints();
datapoint3.setColors(new Color[] {new Color(0, 0, 255, 128)});
datapoint3.setPointsVisible(true);
// カテゴリ軸ラベルの調整
IAxis xaxis3 = chart3.gethXAxis();
xaxis3.gethLabel().setAngle(20);
// 赤色の文字列を描画
IFloatingTextSet textset = chart3.gethFloatingText();
TextString text = new TextString(
"test",
new Font("Arial", Font.PLAIN, 12),
Color.RED,
0,
-0.1f,
0.2f );
textset.add(text);
//chart3の画像出力
try {
chart3.export(QbChart.PNG,"chart3.png",600,300);
} catch (IOException e) {
e.printStackTrace();
}
chart1.setAddOnChart(new QbChart[] {chart2,chart3});
//重ねた画像を出力
try {
chart1.export(QbChart.PNG,"setAddOnChartDemo.png",600,300);
} catch (IOException e) {
e.printStackTrace();
}
}
}
関連するトピックス:
- Ver5からのフォントサイズ【Javaチャート・グラフ作成ツールEspressChart】
- 棒グラフの色を各棒ごとに手動で設定を行う方法
- チャート・グラフをWeb上に展開するプログラム【Javaチャート・グラフ作成ツールEspressChart】
- EspressChartのAPIを使用してのチャートの色やプロットの形を指定する方法【Javaチャート・グラフ作成ツールEspressChart】
- EspressChartの自動調整機能により決定した値を利用するには
- API上でロケールやフォーマットを指定する方法[EspressChart]
- EspressChartでDB・テキストファイルから動的グラフ作成(APIからの編集, Servlet利用編)
- 画像(キャンバス)サイズを変えずにグラフのみサイズを変える方法[EspressChart]
- チャート座標と画像座標の変換方法[EspressChart]
- 統計解析向けR言語: EspressChartの連携でデータを簡単に可視化を実現 : JRI (Java R Interface) 事例