/****************************/
/* 指数分布の計算 */
/* coded by Y.Suganuma */
/****************************/
import java.io.*;
import java.util.*;
public class Exponential {
static double p; // α%値を計算するとき時α/100を設定
static double ram; // 母数
/********/
/* main */
/********/
public static void main(String args[]) throws IOException
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
double x, f, up, h;
double pr[] = new double [1];
int sw, sw1[] = new int [1];
System.out.print("母数は? ");
ram = Double.parseDouble(in.readLine());
System.out.println("目的とする結果は? ");
System.out.print(" =0 : 確率の計算( P(X = x) 及び P(X < x) の値)\n");
System.out.print(" =1 : p%値( P(X > u) = 0.01p となるuの値) ");
sw = Integer.parseInt(in.readLine());
if (sw == 0) {
System.out.print("グラフ出力?(=1: yes, =0: no) ");
sw = Integer.parseInt(in.readLine());
// 密度関数と分布関数の値
if (sw == 0) {
System.out.print(" データは? ");
x = Double.parseDouble(in.readLine());
f = App.exponential(x, ram, pr);
System.out.println("P(X = " + x + ") = " + pr[0] + ", P( X < " + x + ") = " + f + " (母数 = " + ram + ")");
}
// グラフ出力
else {
String file1, file2;
System.out.print(" 密度関数のファイル名は? ");
file1 = in.readLine();
System.out.print(" 分布関数のファイル名は? ");
file2 = in.readLine();
PrintStream out1 = new PrintStream(new FileOutputStream(file1));
PrintStream out2 = new PrintStream(new FileOutputStream(file2));
System.out.print(" データの上限は? ");
up = Double.parseDouble(in.readLine());
System.out.print(" 刻み幅は? ");
h = Double.parseDouble(in.readLine());
// データ取得
ArrayList <Double> x1 = new ArrayList <Double> ();
ArrayList <Double> y1 = new ArrayList <Double> ();
ArrayList <Double> y2 = new ArrayList <Double> ();
for (x = 0; x < up+0.5*h; x += h) {
f = App.exponential(x, ram, pr);
out1.println(x + " " + pr[0]);
out2.println(x + " " + f);
x1.add(x);
y1.add(pr[0]);
y2.add(f);
}
// グラフの描画
graph(x1, y1, y2);
}
}
// %値
else {
System.out.print("%の値は? ");
x = Double.parseDouble(in.readLine());
p = 0.01 * x;
if (p < 1.0e-7)
System.out.println(x + "%値 = ∞ (母数 = " + ram + ")");
else {
f = App.p_exponential(sw1);
System.out.println(x + "%値 = " + f + " sw " + sw1[0] + " (母数 = " + ram + ")");
}
}
}
/*************************/
/* グラフの描画 */
/* x1 : x座標データ */
/* y1 : 密度関数 */
/* y2 : 分布関数 */
/*************************/
static void graph(ArrayList <Double> x1, ArrayList <Double> y1, ArrayList <Double> y2)
{
// 密度関数
String title1[]; // グラフ,x軸,及び,y軸のタイトル
String g_title1[]; // 凡例(グラフの内容)
double x_scale[]; // x軸目盛り
double y_scale1[]; // y軸目盛り
double data_x[][], data1_y[][]; // データ
int n = x1.size();
// グラフ,x軸,及び,y軸のタイトル
title1 = new String [3];
title1[0] = "密度関数(指数分布 λ:" + ram + ")";
title1[1] = "x";
title1[2] = "f(x)";
// 凡例
g_title1 = new String [1];
g_title1[0] = "密度関数";
// x軸目盛り
x_scale = new double[3];
double x_max = (x1.get(n-1)).doubleValue();
double x_step = x_max / 5;
int x_p = 0;
boolean ok = true;
int k = 0;
while (ok) {
if (x_step < 1.0) {
x_step *= 10;
k++;
}
else if (x_step >= 10.0) {
x_step /= 10;
k--;
}
else {
ok = false;
if (x_step-(int)x_step > 1.0e-5)
x_step = (int)x_step + 1;
else
x_step = (int)x_step;
if (k != 0) {
x_step = x_step * Math.pow(10, -k);
if (k > 0)
x_p = k;
}
double t = 0.0;
while (t < x_max-0.001*x_step)
t += x_step;
x_max = t;
}
}
x_scale[0] = 0.0; // 最小値
x_scale[1] = x_max; // 最大値
x_scale[2] = x_step; // 刻み幅
// y軸目盛り
y_scale1 = new double[3];
double y_max = ram;
double y_step = y_max / 5;
int y_p1 = 0;
ok = true;
k = 0;
while (ok) {
if (y_step < 1.0) {
y_step *= 10;
k++;
}
else if (y_step >= 10.0) {
y_step /= 10;
k--;
}
else {
ok = false;
if (y_step-(int)y_step > 1.0e-5)
y_step = (int)y_step + 1;
else
y_step = (int)y_step;
if (k != 0) {
y_step = y_step * Math.pow(10, -k);
if (k > 0)
y_p1 = k;
}
double t = 0.0;
while (t < y_max-0.001*y_step)
t += y_step;
y_max = t;
}
}
y_scale1[0] = 0.0; // 最小値
y_scale1[1] = y_max; // 最大値
y_scale1[2] = y_step; // 刻み幅
// データ
data_x = new double [1][n];
data1_y = new double [1][n];
for (int i1 = 0; i1 < n; i1++)
data_x[0][i1] = (x1.get(i1)).doubleValue();
for (int i1 = 0; i1 < n; i1++)
data1_y[0][i1] = (y1.get(i1)).doubleValue();
// 作図
LineGraph gp1 = new LineGraph(title1, g_title1, x_scale, x_p, y_scale1, y_p1, data_x, data1_y, true, false);
// 分布関数
String title2[]; // グラフ,x軸,及び,y軸のタイトル
String g_title2[]; // 凡例(グラフの内容)
double y_scale2[]; // y軸目盛り
double data2_y[][]; // データ
// グラフ,x軸,及び,y軸のタイトル
title2 = new String [3];
title2[0] = "分布関数(指数分布 λ:" + ram + ")";
title2[1] = "x";
title2[2] = "F(x)";
// 凡例
g_title2 = new String [1];
g_title2[0] = "分布関数";
// y軸目盛り
y_scale2 = new double[3];
int y_p2 = 1;
y_scale2[0] = 0.0; // 最小値
y_scale2[1] = 1.0; // 最大値
y_scale2[2] = 0.2; // 刻み幅
// データ
data2_y = new double [1][n];
for (int i1 = 0; i1 < n; i1++)
data2_y[0][i1] = (y2.get(i1)).doubleValue();
// 作図
LineGraph gp2 = new LineGraph(title2, g_title2, x_scale, x_p, y_scale2, y_p2, data_x, data2_y, true, false);
}
}
-------------------------------------------------
/****************/
/* 関数値の計算 */
/****************/
class Kansu {
private int sw;
// コンストラクタ
Kansu (int s) {sw = s;}
// double型関数
double snx(double x)
{
double y = 0.0;
switch (sw) {
// 関数値(f(x))の計算(指数分布)
case 0:
y = Exponential.p - Math.exp(-Exponential.ram * x);
break;
// 関数の微分の計算(指数分布)
case 1:
y = Exponential.ram * Math.exp(-Exponential.ram * x);
break;
}
return y;
}
}
--------------------------------------------------
/************************/
/* 科学技術系算用の手法 */
/************************/
class App {
/****************************************/
/* 指数分布の計算(P(X = x), P(X < x)) */
/* x : データ */
/* ram : 母数 */
/* z : P(X = x) */
/* return : P(X < x) */
/****************************************/
static double exponential(double x, double ram, double pr[])
{
double f = 0.0, y;
if (x < 0)
pr[0] = 0.0;
else {
y = Math.exp(-ram * x);
pr[0] = ram * y;
f = 1.0 - y;
}
return f;
}
/****************************************/
/* 指数分布のp%値(P(X > u) = 0.01p) */
/* ind : >=0 : normal(収束回数) */
/* =-1 : 収束しなかった */
/****************************************/
static double p_exponential(int ind[])
{
// ニュートン法
Kansu kn1 = new Kansu(0);
Kansu kn2 = new Kansu(1);
double xx = newton(0.0, 1.0e-6, 1.0e-10, 100, ind, kn1, kn2);
return xx;
}
/*****************************************************/
/* Newton法による非線形方程式(f(x)=0)の解 */
/* x1 : 初期値 */
/* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */
/* eps2 : 終了条件2(|f(x(k))|<eps2) */
/* max : 最大試行回数 */
/* ind : 実際の試行回数 */
/* (負の時は解を得ることができなかった) */
/* kn1 : 関数を計算するクラスオブジェクト */
/* kn2 : 関数の微分を計算するクラスオブジェクト */
/* return : 解 */
/*****************************************************/
static double newton(double x1, double eps1, double eps2, int max,
int ind[], Kansu kn1, Kansu kn2)
{
double g, dg, x;
int sw;
x = x1;
ind[0] = 0;
sw = 0;
while (sw == 0 && ind[0] >= 0) {
ind[0]++;
sw = 1;
g = kn1.snx(x1);
if (Math.abs(g) > eps2) {
if (ind[0] <= max) {
dg = kn2.snx(x1);
if (Math.abs(dg) > eps2) {
x = x1 - g / dg;
if (Math.abs(x-x1) > eps1 && Math.abs(x-x1) > eps1*Math.abs(x)) {
x1 = x;
sw = 0;
}
}
else
ind[0] = -1;
}
else
ind[0] = -1;
}
}
return x;
}
}
--------------------------------------------------
/****************************/
/* 折れ線グラフの描画 */
/* coded by Y.Suganuma */
/****************************/
import java.io.*;
import java.text.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class LineGraph extends JFrame {
Draw_line pn;
/*****************************************************/
/* コンストラクタ(折れ線グラフ1) */
/* title_i : グラフ,x軸,及び,y軸のタイトル */
/* g_title_i : 凡例 */
/* x_title_i : 横軸の表示項目 */
/* y_scale_i : データの最小値,最大値,目盛幅 */
/* place_y_i : 小数点以下の桁数(y軸) */
/* data_y_i : グラフのデータ */
/* d_t_i : タイトル表示の有無 */
/* d_g_i : 凡例表示の有無 */
/*****************************************************/
LineGraph(String title_i[], String g_title_i[], String x_title_i[],
double y_scale_i[], int place_y_i, double data_y_i[][],
boolean d_t_i, boolean d_g_i)
{
// JFrameクラスのコンストラクタの呼び出し
super("折れ線グラフ(1)");
// Windowサイズと表示位置を設定
int width = 900, height = 600; // Windowの大きさ(初期サイズ)
setSize(width, height);
Toolkit tool = getToolkit();
Dimension d = tool.getScreenSize();
setLocation(d.width / 2 - width / 2, d.height / 2 - height / 2);
// 描画パネル
Container cp = getContentPane();
pn = new Draw_line(title_i, g_title_i, x_title_i, y_scale_i, place_y_i, data_y_i, d_t_i, d_g_i, this);
cp.add(pn);
// ウィンドウを表示
setVisible(true);
// イベントアダプタ
addWindowListener(new WinEnd());
addComponentListener(new ComponentResize());
}
/*********************************************************/
/* コンストラクタ(折れ線グラフ2) */
/* title_i : グラフ,x軸,及び,y軸のタイトル */
/* g_title_i : 凡例 */
/* x_scale_i : データの最小値,最大値,目盛幅(y) */
/* place_x_i : 小数点以下の桁数(x軸) */
/* y_scale_i : データの最小値,最大値,目盛幅(y) */
/* place_y_i : 小数点以下の桁数(y軸) */
/* data_x_i : グラフのデータ(x軸) */
/* data_y_i : グラフのデータ(y軸) */
/* d_t_i : タイトル表示の有無 */
/* d_g_i : 凡例表示の有無 */
/*********************************************************/
LineGraph(String title_i[], String g_title_i[], double x_scale_i[],
int place_x_i, double y_scale_i[], int place_y_i,
double data_x_i[][], double data_y_i[][], boolean d_t_i,
boolean d_g_i)
{
// JFrameクラスのコンストラクタの呼び出し
super("折れ線グラフ(2)");
// Windowサイズと表示位置を設定
int width = 900, height = 600; // Windowの大きさ(初期サイズ)
setSize(width, height);
Toolkit tool = getToolkit();
Dimension d = tool.getScreenSize();
setLocation(d.width / 2 - width / 2, d.height / 2 - height / 2);
// 描画パネル
Container cp = getContentPane();
pn = new Draw_line(title_i, g_title_i, x_scale_i, place_x_i, y_scale_i, place_y_i, data_x_i, data_y_i, d_t_i, d_g_i, this);
cp.add(pn);
// ウィンドウを表示
setVisible(true);
// イベントアダプタ
addWindowListener(new WinEnd());
addComponentListener(new ComponentResize());
}
/**********************/
/* Windowのサイズ変化 */
/**********************/
class ComponentResize extends ComponentAdapter
{
public void componentResized(ComponentEvent e)
{
pn.repaint();
}
}
/************/
/* 終了処理 */
/************/
class WinEnd extends WindowAdapter
{
public void windowClosing(WindowEvent e) {
setVisible(false);
}
}
}
class Draw_line extends JPanel {
String title[]; // グラフのタイトル
String g_title[]; // 凡例(グラフの内容)
String x_title[]; // x軸への表示
double x_scale[]; // y軸目盛り
double y_scale[]; // y軸目盛り
double data_x[][], data_y[][]; // データ
boolean d_t; // タイトル表示の有無
boolean d_g; // 凡例表示の有無
boolean type = true; // 横軸が項目かデータか
boolean ver = true; // 縦か横か
int place_x; // 小数点以下の桁数(x軸)
int place_y; // 小数点以下の桁数(y軸)
int width = 900, height = 600; // Windowの大きさ(初期サイズ)
int bx1, bx2, by1, by2; // 表示切り替えボタンの位置
LineGraph line;
String change = "横 色"; // 表示切り替えボタン
float line_w = 1.0f; // 折れ線グラフ等の線の太さ
boolean line_m = true; // 折れ線グラフ等にマークを付けるか否か
Color cl[] = {Color.black, Color.magenta, Color.blue, Color.orange, Color.cyan,
Color.pink, Color.green, Color.yellow, Color.darkGray, Color.red}; // グラフの色
int n_g; // グラフの数
/*****************************************************/
/* コンストラクタ(折れ線グラフ1) */
/* title_i : グラフ,x軸,及び,y軸のタイトル */
/* g_title_i : 凡例 */
/* x_title_i : 横軸の表示項目 */
/* y_scale_i : データの最小値,最大値,目盛幅 */
/* place_y_i : 小数点以下の桁数(y軸) */
/* data_y_i : グラフのデータ */
/* d_t_i : タイトル表示の有無 */
/* d_g_i : 凡例表示の有無 */
/*****************************************************/
Draw_line(String title_i[], String g_title_i[], String x_title_i[],
double y_scale_i[], int place_y_i, double data_y_i[][],
boolean d_t_i, boolean d_g_i, LineGraph line_i)
{
// 背景色
setBackground(Color.white);
// テーブルデータの保存
title = title_i;
g_title = g_title_i;
x_title = x_title_i;
y_scale = y_scale_i;
place_y = place_y_i;
data_y = data_y_i;
d_t = d_t_i;
d_g = d_g_i;
line = line_i;
// イベントアダプタ
addMouseListener(new ClickMouse(this));
}
/*********************************************************/
/* コンストラクタ(折れ線グラフ2) */
/* title_i : グラフ,x軸,及び,y軸のタイトル */
/* g_title_i : 凡例 */
/* x_scale_i : データの最小値,最大値,目盛幅(y) */
/* place_x_i : 小数点以下の桁数(x軸) */
/* y_scale_i : データの最小値,最大値,目盛幅(y) */
/* place_y_i : 小数点以下の桁数(y軸) */
/* data_x_i : グラフのデータ(x軸) */
/* data_y_i : グラフのデータ(y軸) */
/* d_t_i : タイトル表示の有無 */
/* d_g_i : 凡例表示の有無 */
/*********************************************************/
Draw_line(String title_i[], String g_title_i[], double x_scale_i[],
int place_x_i, double y_scale_i[], int place_y_i,
double data_x_i[][], double data_y_i[][], boolean d_t_i,
boolean d_g_i, LineGraph line_i)
{
// 背景色
setBackground(Color.white);
// テーブルデータの保存
title = title_i;
g_title = g_title_i;
x_scale = x_scale_i;
place_x = place_x_i;
y_scale = y_scale_i;
place_y = place_y_i;
data_x = data_x_i;
data_y = data_y_i;
d_t = d_t_i;
d_g = d_g_i;
type = false;
line = line_i;
// イベントアダプタ
addMouseListener(new ClickMouse(this));
}
/********/
/* 描画 */
/********/
public void paintComponent (Graphics g)
{
super.paintComponent(g); // 親クラスの描画(必ず必要)
double r, x1, y1, sp;
int i1, i2, cr, k, k_x, k_y, k1, k2, kx, kx1, ky, ky1, han, len;
int x_l, x_r, y_u, y_d; // 描画領域
int f_size; // フォントサイズ
int n_p; // データの数
String s1;
Font f;
FontMetrics fm;
Graphics2D g2 = (Graphics2D)g;
//
// Windowサイズの取得
//
Insets insets = line.getInsets();
Dimension d = line.getSize();
width = d.width - (insets.left + insets.right);
height = d.height - (insets.top + insets.bottom);
x_l = insets.left + 10;
x_r = d.width - insets.right - 10;
y_u = 20;
y_d = d.height - insets.bottom - insets.top;
//
// グラフタイトルの表示
//
r = 0.05; // タイトル領域の割合
f_size = ((y_d - y_u) < (x_r - x_l)) ? (int)((y_d - y_u) * r) : (int)((x_r - x_l) * r);
if (f_size < 5)
f_size = 5;
if (d_t) {
f = new Font("TimesRoman", Font.BOLD, f_size);
g.setFont(f);
fm = g.getFontMetrics(f);
len = fm.stringWidth(title[0]);
g.drawString(title[0], (x_l+x_r)/2-len/2, y_d-f_size/2);
y_d -= f_size;
}
//
// 表示切り替えボタンの設置
//
f_size = (int)(0.8 * f_size);
if (f_size < 5)
f_size = 5;
f = new Font("TimesRoman", Font.PLAIN, f_size);
fm = g.getFontMetrics(f);
g.setFont(f);
g.setColor(Color.yellow);
len = fm.stringWidth(change);
bx1 = x_r - len - 7 * f_size / 10;
by1 = y_u - f_size / 2;
bx2 = bx1 + len + f_size / 2;
by2 = by1 + 6 * f_size / 5;
g.fill3DRect(bx1, by1, len+f_size/2, 6*f_size/5, true);
g.setColor(Color.black);
g.drawString(change, x_r-len-f_size/2, y_u+f_size/2);
//
// 凡例の表示
//
n_g = g_title.length;
if (d_g) {
han = 0;
for (i1 = 0; i1 < n_g; i1++) {
len = fm.stringWidth(g_title[i1]);
if (len > han)
han = len;
}
han += 15;
r = 0.2; // 凡例領域の割合
k1 = (int)((x_r - x_l) * r);
if (han > k1)
han = k1;
kx = x_r - han;
ky = y_u + 3 * f_size / 2;
k = 0;
g2.setStroke(new BasicStroke(7.0f));
for (i1 = 0; i1 < n_g; i1++) {
g.setColor(cl[k]);
g.drawLine(kx, ky, kx+10, ky);
g.setColor(Color.black);
g.drawString(g_title[i1], kx+15, ky+2*f_size/5);
k++;
if (k >= cl.length)
k = 0;
ky += f_size;
}
g2.setStroke(new BasicStroke(1.0f));
x_r -= (han + 10);
}
else
x_r -= (int)(0.03 * (x_r - x_l));
//
// x軸及びy軸のタイトルの表示
//
if (ver) { // 縦
if (title[1].length() > 0 && !title[1].equals("-")) {
len = fm.stringWidth(title[1]);
g.drawString(title[1], (x_l+x_r)/2-len/2, y_d-4*f_size/5);
y_d -= 7 * f_size / 4;
}
else
y_d -= f_size / 2;
if (title[2].length() > 0 && !title[2].equals("-")) {
g.drawString(title[2], x_l, y_u+f_size/2);
y_u += f_size;
}
}
else { // 横
if (title[2].length() > 0 && !title[2].equals("-")) {
len = fm.stringWidth(title[2]);
g.drawString(title[2], (x_l+x_r)/2-len/2, y_d-4*f_size/5);
y_d -= 7 * f_size / 4;
}
else
y_d -= f_size / 2;
if (title[1].length() > 0 && !title[1].equals("-")) {
g.drawString(title[1], x_l, y_u+f_size/2);
y_u += f_size;
}
}
//
// x軸,y軸,及び,各軸の目盛り
//
f_size = (int)(0.8 * f_size);
if (f_size < 5)
f_size = 5;
f = new Font("TimesRoman", Font.PLAIN, f_size);
fm = g.getFontMetrics(f);
y_d -= 3 * f_size / 2;
k_y = (int)((y_scale[1] - y_scale[0]) / (0.99 * y_scale[2]));
k_x = 0;
if (!type)
k_x = (int)((x_scale[1] - x_scale[0]) / (0.99 * x_scale[2]));
g.setFont(f);
DecimalFormat df_x, df_y;
df_x = new DecimalFormat("#");
df_y = new DecimalFormat("#");
if (!type) {
if (place_x != 0) {
s1 = "#.";
for (i1 = 0; i1 < place_x; i1++)
s1 += "0";
df_x = new DecimalFormat(s1);
}
}
if (place_y != 0) {
s1 = "#.";
for (i1 = 0; i1 < place_y; i1++)
s1 += "0";
df_y = new DecimalFormat(s1);
}
// 縦表示
if (ver) {
// y軸
y1 = y_scale[0];
len = 0;
for (i1 = 0; i1 < k_y+1; i1++) {
s1 = df_y.format(y1);
k1 = fm.stringWidth(s1);
if (k1 > len)
len = k1;
y1 += y_scale[2];
}
g.drawLine(x_l+len+5, y_u, x_l+len+5, y_d);
g.drawLine(x_r, y_u, x_r, y_d);
y1 = y_scale[0];
x1 = y_d;
sp = (double)(y_d - y_u) / k_y;
for (i1 = 0; i1 < k_y+1; i1++) {
ky = (int)Math.round(x1);
s1 = df_y.format(y1);
k1 = fm.stringWidth(s1);
g.drawString(s1, x_l+len-k1, ky+f_size/2);
g.drawLine(x_l+len+5, ky, x_r, ky);
y1 += y_scale[2];
x1 -= sp;
}
x_l += (len + 5);
// x軸
if (type) {
n_p = x_title.length;
sp = (double)(x_r - x_l) / n_p;
x1 = x_l + sp / 2.0;
for (i1 = 0; i1 < n_p; i1++) {
kx = (int)Math.round(x1);
k1 = fm.stringWidth(x_title[i1]);
g.drawString(x_title[i1], kx-k1/2, y_d+6*f_size/5);
g.drawLine(kx, y_d, kx, y_d-5);
x1 += sp;
}
}
else {
x1 = x_scale[0];
y1 = x_l;
sp = (double)(x_r - x_l) / k_x;
for (i1 = 0; i1 < k_x+1; i1++) {
kx = (int)Math.round(y1);
s1 = df_x.format(x1);
k1 = fm.stringWidth(s1);
g.drawString(s1, kx-k1/2, y_d+6*f_size/5);
g.drawLine(kx, y_d, kx, y_u);
x1 += x_scale[2];
y1 += sp;
}
}
}
// 横表示
else {
// y軸
if (type) {
n_p = x_title.length;
len = 0;
for (i1 = 0; i1 < n_p; i1++) {
k1 = fm.stringWidth(x_title[i1]);
if (k1 > len)
len = k1;
}
g.drawLine(x_l+len+5, y_u, x_l+len+5, y_d);
g.drawLine(x_r, y_u, x_r, y_d);
sp = (double)(y_d - y_u) / n_p;
x1 = y_d - sp / 2.0;
for (i1 = 0; i1 < n_p; i1++) {
ky = (int)Math.round(x1);
k1 = fm.stringWidth(x_title[n_p-1-i1]);
g.drawString(x_title[n_p-1-i1], x_l+len-k1, ky+f_size/2);
g.drawLine(x_l+len+5, ky, x_l+len+10, ky);
x1 -= sp;
}
g.drawLine(x_l+len+5, y_u, x_r, y_u);
g.drawLine(x_l+len+5, y_d, x_r, y_d);
x_l += (len + 5);
}
else {
y1 = x_scale[0];
len = 0;
for (i1 = 0; i1 < k_x+1; i1++) {
s1 = df_x.format(y1);
k1 = fm.stringWidth(s1);
if (k1 > len)
len = k1;
y1 += x_scale[2];
}
g.drawLine(x_l+len+5, y_u, x_l+len+5, y_d);
g.drawLine(x_r, y_u, x_r, y_d);
y1 = x_scale[0];
x1 = y_d;
sp = (double)(y_d - y_u) / k_x;
for (i1 = 0; i1 < k_x+1; i1++) {
ky = (int)Math.round(x1);
s1 = df_x.format(y1);
k1 = fm.stringWidth(s1);
g.drawString(s1, x_l+len-k1, ky+f_size/2);
g.drawLine(x_l+len+5, ky, x_r, ky);
y1 += x_scale[2];
x1 -= sp;
}
x_l += (len + 5);
}
// x軸
x1 = y_scale[0];
y1 = x_l;
sp = (double)(x_r - x_l) / k_y;
for (i1 = 0; i1 < k_y+1; i1++) {
kx = (int)Math.round(y1);
s1 = df_y.format(x1);
k1 = fm.stringWidth(s1);
g.drawString(s1, kx-k1/2, y_d+6*f_size/5);
g.drawLine(kx, y_d, kx, y_u);
x1 += y_scale[2];
y1 += sp;
}
}
//
// グラフの表示
//
g2.setStroke(new BasicStroke(line_w));
cr = (int)line_w + 6;
// 縦表示
if (ver) {
if (type) {
n_p = x_title.length;
sp = (double)(x_r - x_l) / n_p;
k1 = 0;
for (i1 = 0; i1 < n_g; i1++) {
g.setColor(cl[k1]);
x1 = x_l + sp / 2.0;
kx1 = 0;
ky1 = 0;
for (i2 = 0; i2 < n_p; i2++) {
kx = (int)Math.round(x1);
ky = y_d - (int)((y_d - y_u) * (data_y[i1][i2] - y_scale[0]) / (y_scale[1] - y_scale[0]));
if (line_m)
g.fillOval(kx-cr/2, ky-cr/2, cr, cr);
if (i2 > 0)
g.drawLine(kx1, ky1, kx, ky);
kx1 = kx;
ky1 = ky;
x1 += sp;
}
k1++;
if (k1 >= cl.length)
k1 = 0;
}
}
else {
n_p = data_x[0].length;
k1 = 0;
for (i1 = 0; i1 < n_g; i1++) {
g.setColor(cl[k1]);
kx1 = 0;
ky1 = 0;
for (i2 = 0; i2 < n_p; i2++) {
kx = x_l + (int)((x_r - x_l) * (data_x[i1][i2] - x_scale[0]) / (x_scale[1] - x_scale[0]));
ky = y_d - (int)((y_d - y_u) * (data_y[i1][i2] - y_scale[0]) / (y_scale[1] - y_scale[0]));
if (line_m)
g.fillOval(kx-cr/2, ky-cr/2, cr, cr);
if (i2 > 0)
g.drawLine(kx1, ky1, kx, ky);
kx1 = kx;
ky1 = ky;
}
k1++;
if (k1 >= cl.length)
k1 = 0;
}
}
}
// 横表示
else {
if (type) {
n_p = x_title.length;
sp = (double)(y_d - y_u) / n_p;
k1 = 0;
for (i1 = 0; i1 < n_g; i1++) {
g.setColor(cl[k1]);
y1 = y_d - sp / 2.0;
kx1 = 0;
ky1 = 0;
for (i2 = 0; i2 < n_p; i2++) {
ky = (int)Math.round(y1);
kx = x_l + (int)((x_r - x_l) * (data_y[i1][n_p-1-i2] - y_scale[0]) / (y_scale[1] - y_scale[0]));
if (line_m)
g.fillOval(kx-cr/2, ky-cr/2, cr, cr);
if (i2 > 0)
g.drawLine(kx1, ky1, kx, ky);
kx1 = kx;
ky1 = ky;
y1 -= sp;
}
k1++;
if (k1 >= cl.length)
k1 = 0;
}
}
else {
n_p = data_x[0].length;
k1 = 0;
for (i1 = 0; i1 < n_g; i1++) {
g.setColor(cl[k1]);
kx1 = 0;
ky1 = 0;
for (i2 = 0; i2 < n_p; i2++) {
kx = x_l + (int)((x_r - x_l) * (data_y[i1][i2] - y_scale[0]) / (y_scale[1] - y_scale[0]));
ky = y_d - (int)((y_d - y_u) * (data_x[i1][i2] - x_scale[0]) / (x_scale[1] - x_scale[0]));
if (line_m)
g.fillOval(kx-cr/2, ky-cr/2, cr, cr);
if (i2 > 0)
g.drawLine(kx1, ky1, kx, ky);
kx1 = kx;
ky1 = ky;
}
k1++;
if (k1 >= cl.length)
k1 = 0;
}
}
}
g2.setStroke(new BasicStroke(1.0f));
}
/************************************/
/* マウスがクリックされたときの処理 */
/************************************/
class ClickMouse extends MouseAdapter
{
Draw_line dr;
ClickMouse(Draw_line dr1)
{
dr = dr1;
}
public void mouseClicked(MouseEvent e)
{
int xp = e.getX();
int yp = e.getY();
// 縦表示と横表示の変換
if (xp > bx1 && xp < bx1+(bx2-bx1)/2 && yp > by1 && yp < by2) {
if (ver) {
ver = false;
change = "縦 色";
}
else {
ver = true;
change = "横 色";
}
repaint();
}
// グラフの色,線の太さ等
else if (xp > bx1+(bx2-bx1)/2 && xp < bx2 && yp > by1 && yp < by2) {
Modify md = new Modify(dr.line, dr);
md.setVisible(true);
}
}
}
}
--------------------------------------------------
/****************************/
/* 色及び線の太さの変更 */
/* coded by Y.Suganuma */
/****************************/
import java.io.*;
import java.text.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Modify extends JDialog implements ActionListener, TextListener {
Draw_line dr; // 折れ線グラフ
JButton bt_dr;
TextField rgb[];
TextField r[];
TextField g[];
TextField b[];
JTextField tx;
JRadioButton r1, r2;
float line_w = 1.0f; // 折れ線グラフ等の線の太さ
boolean line_m = true; // 折れ線グラフ等にマークを付けるか否か
Color cl[]; // グラフの色
int n_g; // グラフの数
int wd; // 線の太さを変更するか
int mk; // マークを変更するか
int n;
JPanel jp[];
// 折れ線グラフ
Modify(Frame host, Draw_line dr1)
{
super(host, "色と線の変更", true);
// 初期設定
dr = dr1;
wd = 1;
mk = 1;
n_g = dr.n_g;
if (n_g > 10)
n_g = 10;
n = n_g + 3;
line_w = dr.line_w;
line_m = dr.line_m;
cl = new Color[n_g];
for (int i1 = 0; i1 < n_g; i1++)
cl[i1] = dr.cl[i1];
set();
// ボタン
Font f = new Font("TimesRoman", Font.BOLD, 20);
bt_dr = new JButton("OK");
bt_dr.setFont(f);
bt_dr.addActionListener(this);
jp[n-1].add(bt_dr);
}
// 設定
void set()
{
setSize(450, 60*(n));
Container cp = getContentPane();
cp.setBackground(Color.white);
cp.setLayout(new GridLayout(n, 1, 5, 5));
jp = new JPanel[n];
for (int i1 = 0; i1 < n; i1++) {
jp[i1] = new JPanel();
cp.add(jp[i1]);
}
Font f = new Font("TimesRoman", Font.BOLD, 20);
// 色の変更
JLabel lb[][] = new JLabel[n_g][3];
rgb = new TextField[n_g];
r = new TextField[n_g];
g = new TextField[n_g];
b = new TextField[n_g];
for (int i1 = 0; i1 < n_g; i1++) {
rgb[i1] = new TextField(3);
rgb[i1].setFont(f);
rgb[i1].setBackground(new Color(cl[i1].getRed(), cl[i1].getGreen(), cl[i1].getBlue()));
jp[i1].add(rgb[i1]);
lb[i1][0] = new JLabel(" 赤");
lb[i1][0].setFont(f);
jp[i1].add(lb[i1][0]);
r[i1] = new TextField(3);
r[i1].setFont(f);
r[i1].setBackground(Color.white);
r[i1].setText(Integer.toString(cl[i1].getRed()));
r[i1].addTextListener(this);
jp[i1].add(r[i1]);
lb[i1][1] = new JLabel("緑");
lb[i1][1].setFont(f);
jp[i1].add(lb[i1][1]);
g[i1] = new TextField(3);
g[i1].setFont(f);
g[i1].setBackground(Color.white);
g[i1].setText(Integer.toString(cl[i1].getGreen()));
g[i1].addTextListener(this);
jp[i1].add(g[i1]);
lb[i1][2] = new JLabel("青");
lb[i1][2].setFont(f);
jp[i1].add(lb[i1][2]);
b[i1] = new TextField(3);
b[i1].setFont(f);
b[i1].setBackground(Color.white);
b[i1].setText(Integer.toString(cl[i1].getBlue()));
b[i1].addTextListener(this);
jp[i1].add(b[i1]);
}
// 線の変更
if (wd > 0) {
JLabel lb1 = new JLabel("線の太さ:");
lb1.setFont(f);
jp[n_g].add(lb1);
tx = new JTextField(2);
tx.setFont(f);
tx.setBackground(Color.white);
tx.setText(Integer.toString((int)line_w));
jp[n_g].add(tx);
}
if (mk > 0) {
JLabel lb2 = new JLabel("マーク:");
lb2.setFont(f);
jp[n-2].add(lb2);
ButtonGroup gp = new ButtonGroup();
r1 = new JRadioButton("付ける");
r1.setFont(f);
gp.add(r1);
jp[n-2].add(r1);
r2 = new JRadioButton("付けない");
r2.setFont(f);
gp.add(r2);
jp[n-2].add(r2);
if (line_m)
r1.doClick();
else
r2.doClick();
}
}
// TextFieldの内容が変更されたときの処理
public void textValueChanged(TextEvent e)
{
for (int i1 = 0; i1 < n_g; i1++) {
if (e.getSource() == r[i1] || e.getSource() == g[i1] || e.getSource() == b[i1]) {
String str = r[i1].getText();
int rc = str.length()>0 ? Integer.parseInt(str) : 0;
str = g[i1].getText();
int gc = str.length()>0 ? Integer.parseInt(str) : 0;
str = b[i1].getText();
int bc = str.length()>0 ? Integer.parseInt(str) : 0;
rgb[i1].setBackground(new Color(rc, gc, bc));
}
}
}
// 値の設定
public void actionPerformed(ActionEvent e)
{
for (int i1 = 0; i1 < n_g; i1++) {
String str = r[i1].getText();
int rc = str.length()>0 ? Integer.parseInt(str) : 0;
str = g[i1].getText();
int gc = str.length()>0 ? Integer.parseInt(str) : 0;
str = b[i1].getText();
int bc = str.length()>0 ? Integer.parseInt(str) : 0;
dr.cl[i1] = new Color(rc, gc, bc);
}
dr.line_w = Integer.parseInt(tx.getText());
if (r1.isSelected())
dr.line_m = true;
else
dr.line_m = false;
dr.repaint();
setVisible(false);
}
}