/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.hayabusa.io;

import static org.opengion.fukurou.system.HybsConst.CR ;			// 6.1.0.0 (2014/12/26)
import org.opengion.fukurou.util.ColorMap;							// 6.0.2.1 (2014/09/26)
import org.opengion.fukurou.util.HybsDateUtil;						// 6.7.3.0 (2017/01/27)
import org.opengion.hayabusa.common.HybsSystemException;

import java.util.List;
import java.util.Locale;
import java.util.Calendar;									// 6.7.3.0 (2017/01/27)

import java.awt.Color;
import java.text.SimpleDateFormat;

import org.jfree.ui.RectangleEdge;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.CategoryAnchor;
import org.jfree.chart.axis.DateAxis;						// 5.6.1.0 (2013/02/01)
import org.jfree.chart.axis.SegmentedTimeline;				// 6.7.3.0 (2017/01/27)
import org.jfree.chart.plot.DatasetRenderingOrder;
import org.jfree.chart.plot.CategoryMarker;

/**
 * ChartCreate は、JFreeChart オブジェクトを構築するクラスです。
 * 複数の ChartDataset オブジェクトを合成することも、ここで行っています。
 * グラフの種類は、ChartPlot_XXX クラスで設定しています。
 * ここでは、簡易的にオブジェクトを構築できるように、チャートタイプの指定によって、
 * 各種作成するオブジェクトを切り替えています。
 *
 * @version  0.9.0	2007/06/21
 * @author	 Kazuhiko Hasegawa
 * @since	 JDK1.1,
 */
public class ChartCreate {
	private static final long TIME_LINE = 60 * 1000L ;	// // 6.9.8.0 (2018/05/28) FindBugs

	private String	title			;				// タイトル
	private String	chartType		;				// チャートの種類
	private String	domainLabel		;				// チャートの共通横軸のラベル
	private boolean	showLegend		= true;			// 凡例 の表示可否
	private RectangleEdge	rectEdge= RectangleEdge.BOTTOM;		// 凡例の表示箇所
	private PlotOrientation	plotOri	= PlotOrientation.VERTICAL;	// チャートの軸表示方向
	private Color	chartBackColor	;				// 背景色の設定
	private Color	plotBackColor	;				// 描画領域の設定
	private int		rotationLabel	;				// 横軸ラベルの傾き(1:180度 、2:90度 、3:60度 、4:45度 、6:30度 ･･･ )
	// CategoryAxis系は、rotationLabel。ValueAxis系(NumberAxis,DateAxis)は、useVerticalLabels で、ラベルの表示向きを指定します。
	private boolean	useVerticalLabels	;			// 5.6.4.3 (2013/05/24) 横軸ラベルの表示向き(横書き:false/縦書き:true) 
	private	String	domainMarker		;			// 横軸のマーカーライン
	private	boolean	useDomainLabel		= true;		// 横軸ラベルの表示有無
	private	boolean	useMarkerLabel		= true;		// マーカーライン時の文字有無
	private int		seriesPikup			= -1;		// ピックアップするシリーズ番号
	private	HybsURLGenerator urlGen		;			// クリッカブル・マップ
	// 4.0.2.0 (2007/12/20)
	private	String	categoryMargin	;			// カテゴリマージン(0.0～1.0)
	private	String	lowerMargin		;			// 下方マージン(0.0～1.0)
	private	String	upperMargin		;			// 上方マージン(0.0～1.0)
	private	boolean	isDebug			;			// デバッグフラグ
	private	boolean	useDomainLine	;			// 4.0.3.0 (2008/01/07) 横軸のグリッド表示有無(垂直線)
	private	Color	domainLineColor	;			// 4.0.3.0 (2008/01/07) 横軸のグリッド線の色
	private	boolean	useRangeLine	= true;		// 4.0.3.0 (2008/01/07) 縦軸のグリッド表示有無(水平線)
	private	Color	rangeLineColor	;			// 4.0.3.0 (2008/01/07) 縦軸のグリッド線の色
	private int		categorySkip	= 1;		// 4.0.3.0 (2008/01/07) 横軸ラベルをスキップする間隔
	private int		categoryCutNo	= -1;		// 4.1.1.0 (2008/02/04) 横軸ラベルの文字位置指定のキーブレイク
	private int		rangeSkip		= -1;		// 4.1.1.0 (2008/02/04) 縦軸のグリッドをスキップする間隔(初期値:-1)
	private	boolean	useToolTip		;			// 4.3.1.0 (2008/08/09) ツールチップスの利用

	private CategoryAnchor categoryAnchor	;	// 4.1.1.0 (2008/02/14) 横軸のグリッド(垂直線)の書き出し位置(START,MIDDLE,END)

	private List<ChartDataset> chartDataset	;	// チャートのデータ属性管理オブジェクトのリスト

	private String	dateAxisFormat	= "MM/dd";	// 5.6.1.0 (2013/02/01) Time,XYTime Polt関係の時間軸を表す場合のフォーマット
	private SegmentedTimeline	timeLine ;		// 6.7.3.0 (2017/01/27) Time,XYTime Polt関係の時間軸を調整する SegmentedTimeline

	/**
	 * JFreeChart オブジェクトを作成します。
	 *
	 * 内部的には、ChartPlot インターフェースに基づいた Plot を構築するクラスを
	 * 呼び出して、JFreeChart の引数に設定します。
	 * 各種属性の設定も行います。
	 *
	 * @return	JFreeChartオブジェクト
	 */
	public JFreeChart getChart() {

		final ChartPlot chPlot = ChartFactory.newChartPlot( chartType );

		final Plot plot = chPlot.getPlot( this );

		// 描画領域の設定
		if( plotBackColor != null ) {
			plot.setBackgroundPaint( plotBackColor );
		}

		final JFreeChart chart = new JFreeChart( title, JFreeChart.DEFAULT_TITLE_FONT, plot, showLegend );

		if( showLegend ) {
			chart.getLegend().setPosition( rectEdge );
		}

		// 背景色の設定
		if( chartBackColor != null ) {
			chart.setBackgroundPaint( chartBackColor );
		}

		// 以降の処理では、変更イベントが発行される。
		if( categoryAnchor != null && plot instanceof CategoryPlot ) {
			((CategoryPlot)plot).setDomainGridlinePosition( categoryAnchor ) ;
		}

		return chart;
	}

	/**
	 * JFreeChart オブジェクトを変更します。
	 *
	 * すでに作成済みの JFreeChart に対して、
	 * シリーズのピックアップ(seriesPikup) のみ、変更します。
	 * 使用するのは、引数の JFreeChart と seriesPikup 属性値のみです。
	 *
	 * @og.rev 3.8.9.2 (2007/07/28) シリーズ指定時の色、シェープ対応
	 *
	 * @param	chart	JFreeChartオブジェクト
	 * @param	serNo	seriesPikup 属性値
	 *
	 * @return	JFreeChartオブジェクト
	 */
	public static JFreeChart modifying( final JFreeChart chart,final int serNo ) {

		final CategoryPlot plot = chart.getCategoryPlot();

		if( plot instanceof HybsCategoryPlot ) {
			// 以降の処理では、変更イベントは発行されない。
			// 5.1.8.0 (2010/07/01) 実質的に使用されていないので、削除
			((HybsCategoryPlot)plot).setSeriesPikup( serNo ) ;
		}

		final CategoryDataset dtset = plot.getDataset();
		final int rowCnt = dtset.getRowCount();	// Series の個数

		final CategoryItemRenderer rend = plot.getRenderer();

		if( serNo >= 0 && serNo < rowCnt ) {
			rend.setBasePaint( Color.CYAN );
			rend.setSeriesPaint( serNo, Color.RED );
		}

		return chart ;
	}

	/**
	 * CategoryPlotオブジェクトを返します。
	 *
	 * ChartCreate オブジェクト(自分自身)に設定された各種属性を元に、
	 * CategoryPlotオブジェクトを構築します。
	 * 必要な属性設定は、済んでいる状態です。
	 * ここでは、serNo、categoryAxis、plotOrientation、useDomainLine、
	 * domainLineColor、useRangeLine 、RangeLineColor 、rangeSkip 、
	 * domainMarker を設定しておきます。
	 *
	 * @og.rev 4.1.1.0 (2008/02/04) 新規追加
	 *
	 * @return	必要な属性を設定済みのCategoryPlotオブジェクト
	 */
	protected HybsCategoryPlot makeCategoryPlot() {
		final HybsCategoryPlot cPlot = new HybsCategoryPlot( seriesPikup );

		cPlot.setOrientation( plotOri );
		cPlot.setDatasetRenderingOrder( DatasetRenderingOrder.FORWARD );

		// ドメイン(横軸)に対する、グリッドライン(垂直線)の指定
		cPlot.setDomainGridlinesVisible( useDomainLine );
		if( domainLineColor != null ) { cPlot.setDomainGridlinePaint( domainLineColor ); }

		// レンジ(縦軸)に対する、グリッドライン(水平線)の指定
		cPlot.setRangeGridlinesVisible( useRangeLine );
		if( rangeLineColor != null ) { cPlot.setRangeGridlinePaint( rangeLineColor ); }

		// 4.1.1.0 (2008/02/04) 縦軸のグリッド線(水平線)をスキップする間隔の指定
		cPlot.setRangeSkip( rangeSkip );

		// 横軸ドメインマーカーの設定(縦ライン)
		if( domainMarker != null ) {
			final CategoryMarker catMk = new CategoryMarker( domainMarker );
			catMk.setDrawAsLine( true );
			if( useMarkerLabel ) {
				catMk.setLabel( domainMarker );
			}
			cPlot.addDomainMarker( catMk );
		}

		return cPlot ;
	}

	/**
	 * CategoryAxisオブジェクトを返します。
	 *
	 * ChartCreate オブジェクト(自分自身)に設定された各種属性を元に、
	 * CategoryAxisオブジェクトを構築します。
	 * 必要な属性設定は、済んでいる状態です。
	 * ここでは、domainLabel、categoryMargin、lowerMargin、upperMargin、
	 * useDomainLabel、rotationLabel を設定しておきます。
	 *
	 * @og.rev 4.1.1.0 (2008/02/04) 横軸ラベルの文字位置指定のカット文字数追加(categoryCutNo)
	 *
	 * @return	必要な属性を設定済みの CategoryAxisオブジェクト
	 */
	protected CategoryAxis makeCategoryAxis() {
		final CategoryAxis categoryAxis = new HybsCategoryAxis(
											domainLabel,categorySkip,categoryCutNo
									);

		// カテゴリマージン(0.0～1.0)を指定します。
		if( categoryMargin != null ) {
			final double ctMargin = Double.parseDouble( categoryMargin );
			categoryAxis.setCategoryMargin( ctMargin ) ;	// double margin
		}

		// 下方マージン(0.0～1.0)を指定します。
		if( lowerMargin != null ) {
			final double lwMargin = Double.parseDouble( lowerMargin );
			categoryAxis.setLowerMargin( lwMargin ) ;	// double margin
		}

		// 上方マージン(0.0～1.0)を指定します。
		if( upperMargin != null ) {
			final double upMargin = Double.parseDouble( upperMargin );
			categoryAxis.setUpperMargin( upMargin ) ;	// double margin
		}

		// チャートのカテゴリーラベルの方向を指定します。
		if( rotationLabel > 0 ) {
			categoryAxis.setCategoryLabelPositions(
				CategoryLabelPositions.createUpRotationLabelPositions(
					Math.PI / rotationLabel ));
		}
		else if( rotationLabel < 0 ) {
			categoryAxis.setCategoryLabelPositions(
				CategoryLabelPositions.createDownRotationLabelPositions(
					Math.PI / -rotationLabel ));
		}

		// 横軸ラベルの表示有無を返します。
		categoryAxis.setVisible( useDomainLabel );	// ドメインラベルの表示有無

		if( isDebug ) {
			System.out.println( "CategoryMargin="+categoryAxis.getCategoryMargin());
			System.out.println( "LowerMargin="+categoryAxis.getLowerMargin());
			System.out.println( "UpperMargin="+categoryAxis.getUpperMargin());
		}

		return categoryAxis ;
	}

	/**
	 * チャートのデータ属性管理オブジェクトのリストを設定します。
	 *
	 * ChartDataset オブジェクトは、内部チャートの個々の属性を管理しています。
	 * このオブジェクト は、グラフの合成に使用できるように、内部にそれぞれの Plot や
	 * renderer に対応する情報を持っています。
	 * これらを、複数管理するときに、List 管理していますので、そのList をセットします。
	 * JFreeChart には、この複数のChartDataset から、それぞれの Plot と Dataset を
	 * 順次、追加していく必要があります。その処理は、ChartPlot インターフェースを
	 * 継承した、サブクラスで実際に行われます。
	 *
	 * @param	datasetList	チャートのデータ属性管理のリスト
	 */
	public void setDatasetList( final List<ChartDataset> datasetList ) {
		chartDataset = datasetList;

		if( chartDataset != null ) {
			final ChartDataset firstChData = chartDataset.get(0);
			chartType = firstChData.getChartType();
		}
	}

	/**
	 * チャートのデータ属性管理オブジェクトのリストを返します。
	 *
	 * @return	チャートのデータ属性管理オブジェクトのリスト
	 * @see #setDatasetList( List )
	 */
	protected List<ChartDataset> getDatasetList() { return chartDataset; }

	/**
	 * チャートのタイトルを設定します。
	 *
	 * @param	chTitle	チャートのタイトル
	 */
	public void setTitle( final String chTitle ) {
		title = chTitle;
	}

	/**
	 * チャートの共通横軸のラベルを設定します。
	 *
	 * @param	domLabel	チャートの共通横軸のラベル
	 */
	public void setDomainLabel( final String domLabel ) {
		domainLabel = domLabel;
	}

	/**
	 * チャートの共通横軸のラベルを返します。
	 *
	 * @return	チャートの共通横軸のラベル
	 */
	protected String getDomainLabel() { return domainLabel; }

	/**
	 * 凡例 の表示可否を設定します。
	 *
	 * @param	showLeg	凡例 の表示可否
	 */
	public void setShowLegend( final boolean showLeg ) {
		showLegend = showLeg;
	}

	/**
	 * 凡例の表示箇所を設定します(TOP、BOTTOM、RIGHT、LEFT)。
	 *
	 * 表示箇所は、org.jfree.ui.RectangleEdge クラスの設定値を使用します。
	 * 指定できるのは、TOP、BOTTOM、RIGHT、LEFT で、各文字の頭一文字で
	 * 判定してます。つまり、T,B,R,L で、判定を行い、それ以外はエラーになります。
	 *
	 * @param	edge	凡例の表示箇所(TOP、BOTTOM、RIGHT、LEFT)
	 */
	public void setRectangleEdge( final String edge ) {
		if( edge != null && edge.length() > 0 ) {
			final char ope = edge.charAt(0);
			switch( ope ) {
				case 'T' : rectEdge = RectangleEdge.TOP;	break;
				case 'B' : rectEdge = RectangleEdge.BOTTOM;break;
				case 'R' : rectEdge = RectangleEdge.RIGHT;	break;
				case 'L' : rectEdge = RectangleEdge.LEFT;	break;
				default  :
					final String errMsg = "指定のパラメータは適用できません。[" + edge + "]"
							+ CR
							+ "TOP,BOTTOM,RIGHT,LEFT の中から、指定してください。" ;
					throw new HybsSystemException( errMsg );
			}
		}
	}

	/**
	 * チャートの軸表示方向を設定します(VERTICAL、HORIZONTAL)。
	 *
	 * 軸表示方向は、org.jfree.chart.plot.PlotOrientation クラスの設定値を使用します。
	 * 指定できるのは、VERTICAL、HORIZONTALで、各文字の頭一文字で
	 * 判定してます。つまり、V,H で、判定を行い、それ以外はエラーになります。
	 *
	 * @param	orientation	凡例の表示箇所(VERTICAL、HORIZONTAL)
	 */
	public void setPlotOrientation( final String orientation ) {
		if( orientation != null && orientation.length() > 0 ) {
			final char ope = orientation.charAt(0);
			switch( ope ) {
				case 'V' : plotOri = PlotOrientation.VERTICAL;	break;
				case 'H' : plotOri = PlotOrientation.HORIZONTAL;break;
				default  :
					final String errMsg = "指定のパラメータは適用できません。[" + orientation + "]"
							+ CR
							+ "VERTICAL,HORIZONTAL の中から、指定してください。" ;
					throw new HybsSystemException( errMsg );
			}
		}
	}

	/**
	 * チャートの軸表示方向を返します。
	 *
	 * org.jfree.chart.plot.PlotOrientation クラスの設定値を使用します。
	 *
	 * @return	チャートの軸表示方向(VERTICAL、HORIZONTAL)
	 */
	protected PlotOrientation getPlotOrientation() { return plotOri; }

	/**
	 * チャートの背景色を指定します。
	 *
	 * 指定文字列は、java.awt.Color クラスのstatic フィールド名で指定します。
	 * BLACK , BLUE , CYAN , DARK_GRAY , GRAY , GREEN , LIGHT_GRAY ,
	 * MAGENTA , ORANGE , PINK , RED , WHITE , YELLOW , (PURPLE) が指定できます。
	 * また、#XXXXXX形式の16bitRGB表記 でも指定可能です。
	 *
	 * @og.rev 6.0.2.1 (2014/09/26) StringUtil → ColorMap
	 *
	 * @param   chBackClr チャートの背景色
	 * @see		java.awt.Color#BLACK
	 */
	public void setChartBackColor( final String chBackClr ) {
		if( chBackClr != null && chBackClr.length() > 0 ) {
			chartBackColor = ColorMap.getColorInstance( chBackClr );		// 6.0.2.1 (2014/09/26) StringUtil → ColorMap
		}
	}

	/**
	 * チャートの描画領域の色を指定します。
	 *
	 * 指定文字列は、java.awt.Color クラスのstatic フィールド名で指定します。
	 * BLACK , BLUE , CYAN , DARK_GRAY , GRAY , GREEN , LIGHT_GRAY ,
	 * MAGENTA , ORANGE , PINK , RED , WHITE , YELLOW , (PURPLE) が指定できます。
	 * また、#XXXXXX形式の16bitRGB表記 でも指定可能です。
	 *
	 * @og.rev 6.0.2.1 (2014/09/26) StringUtil → ColorMap
	 *
	 * @param   plBackClr チャートの描画領域色
	 * @see		java.awt.Color#BLACK
	 */
	public void setPlotBackColor( final String plBackClr ) {
		if( plBackClr != null && plBackClr.length() > 0 ) {
			plotBackColor = ColorMap.getColorInstance( plBackClr );		// 6.0.2.1 (2014/09/26) StringUtil → ColorMap
		}
	}

	/**
	 * チャートのカテゴリーラベルの方向を指定します。
	 *
	 * これは、CategoryAxis 系の横軸ラベルに対して、表示方向を指定します。
	 * ValueAxis系(NumberAxis,DateAxis)は、setUseVerticalLabels( boolean ) で
	 * true:縦/false:横 のみ指定可能です。
	 * 
	 * 方向は、上方向に対して、(PI / 指示数) で求まる値に設定します。
	 * この指示数に相当する値を設定します。
	 * 1:180度 、2:90度 、3:60度 、4:45度 、6:30度 ･･･
	 * マイナスは、下方向に回転させます。
	 * 0 を指定した場合は、何も設定しません。(初期設定のまま)
	 *
	 * @param   rotLabel カテゴリーラベルの方向
	 * @see		#setUseVerticalLabels( boolean )
	 */
	public void setRotationLabel( final int rotLabel ) {
		rotationLabel = rotLabel;
	}

	/**
	 * ラベルの表示向きを縦にするかどうか[false/true]を指定します(初期値:false)。
	 *
	 * これは、ValueAxis系(NumberAxis,DateAxis) 系の横軸ラベルに対して、表示方向を
	 * true:縦/false:横で、指定します。
	 * true に指定した場合で、かつ、rotationLabel が未指定(=0)の場合は、2:90度 も設定します。
	 *
	 * ChartCreate の rotationLabel は、角度を指定できましたが、NumberAxis,DateAxis では、
	 * 縦にするかどうかの指定しかできません。
	 * ここでは、true を指定するとラベルは、縦書きになります。
	 * 初期値は、false(横書き)です。
	 *
	 * @og.rev 5.6.4.3 (2013/05/24) 新規追加
	 *
	 * @param	useVLavels	ラベルの表示向き [false:横書き/true:縦書き]
	 * @see		#setRotationLabel( int )
	 */
	public void setUseVerticalLabels( final boolean useVLavels ) {
		useVerticalLabels = useVLavels;

		// useVerticalLabels=true で、rotationLabel を 2:90度 に設定しておきます。
		if( useVerticalLabels && rotationLabel == 0 ) { rotationLabel = 2; }
	}

	/**
	 * チャートのカテゴリーラベルの方向を取得します。
	 *
	 * 方向は、上方向に対して、(PI / 指示数) で求まる値に設定します。
	 * この指示数に相当する値を設定します。
	 * 1:180度 、2:90度 、3:60度 、4:45度 、6:30度 ･･･
	 * マイナスは、した方向に回転させます。
	 * 0 を指定した場合は、何も設定しません。(初期設定のまま)
	 *
	 * @return	カテゴリーラベルの方向
	 * @see     #setRotationLabel( int )
	 */
	protected int getRotationLabel() { return rotationLabel; }

	/**
	 * チャートの横軸の値(ドメイン)に合致する位置にマーカーラインを設定します。
	 *
	 * この属性には、マーカーラインを設定する値を記述します。
	 *
	 * @param   marker ドメインのマーカーライン
	 */
	public void setDomainMarker( final String marker ) {
		if( marker != null && marker.length() > 0 ) {
			domainMarker = marker;
		}
	}

	/**
	 * 横軸ラベルのラベルを表示するかどうか[true/false]を指定します(初期値:true)。
	 *
	 * ドメイン(横軸)が、多数存在する場合、ドメインラベルが見えにくくなります。
	 * そのようなケースで、横軸のラベルそのものを表示しない場合に、false を
	 * 設定します。
	 * 初期値は、表示する(true)です。
	 *
	 * @param   flag 横軸ラベルの表示有無 [true:表示する/false:表示しない]
	 */
	public void setUseDomainLabel( final boolean flag ) {
		useDomainLabel = flag ;
	}

	/**
	 * 横軸ラベルの表示有無を返します。
	 *
	 * @return	boolean横軸ラベルの表示有無(true:表示する/false:表示しない)
	 */
	protected boolean isUseDomainLabel() { return useDomainLabel; }

	/**
	 * マーカーラインに、その設定値を表示するかどうか[true/false]を指定します(初期値:true)。
	 *
	 * ドメイン(横軸)が、多数存在する場合、ドメインラベルが見えない場合があります。
	 * そのようなケースで、見たい値にマーカーラインを設定し、その横に、ドメインラベル
	 * を表示する事で、ピックアップしている軸の値を容易に知ることが可能です。
	 * 初期値は、表示する(true)です。
	 *
	 * @param   flag マーカーラインの設定値表示 [true:表示する/false:表示しない]
	 */
	public void setUseMarkerLabel( final boolean flag ) {
		useMarkerLabel = flag ;
	}

	/**
	 * 複数シリーズのピックアップを行う場合のシリーズ番号を指定します。
	 *
	 * 複数シリーズ(検索時に複数項目を同時に検索する場合)では、チャート上に
	 * 複数のグラフが表示されますが、その中の一つをピックアップする場合に、
	 * シリーズ番号を指定します。
	 * シリーズ番号は、0 から始まる数字です。
	 * ここでは、ピックアップされたシリーズは、赤色で表示されます。
	 * それ以外は、グレー色での表示になります。
	 * (※ 本来は、ChartDataset に持つべき属性です。)
	 *
	 * @param	serPikup	シリーズ番号
	 */
	public void setSeriesPikup( final int serPikup ) {
		seriesPikup = serPikup;
	}

	/**
	 * 横軸ラベルをスキップする間隔を指定します。
	 *
	 * 横軸ラベル(カテゴリラベル表示)する際に、スキップする間隔を指定します。
	 * "1" (初期値)では、１つづつ表示(つまり、すべて表示する)します。
	 * "2" とすると、１つおきに、"3" とすると、２つおきに表示します。
	 * 初期値は、"1" (すべて表示)です。
	 * なお、先頭から表示を開始します。
	 *
	 * 注意：これとは別に、ラベル先頭に "_" を付けた場合は、ラベルを表示しません。
	 * また、categoryCutNo が指定された場合は、categorySkip は使用されません。
	 *
	 * @param	cateSkip	ラベルをスキップする間隔を指定
	 * @see		#setCategoryCutNo( int )
	 */
	public void setCategorySkip( final int cateSkip ) {
		categorySkip = cateSkip;
	}

	/**
	 * 横軸ラベルの文字位置指定のカット文字数を指定します。
	 *
	 * @og.rev 4.1.1.0 (2008/02/04) 新規追加
	 *
	 * 横軸ラベル(カテゴリラベル表示)する際に、ラベルの先頭から、この指定文字数だけ
	 * カットして、表示します。
	 * その際、前回作成したカットラベルと、同一ラベルの場合は、表示しません。
	 * 例えば、データは、年月日で、年と月のみ(先頭６文字)を指定すると、
	 * 日のデータは、ラベルが表示されません。
	 * 指定される数字は、１以上の整数としてください。
	 * 初期値は、すべて表示です。
	 *
	 * 注意：これとは別に、ラベル先頭に "_" を付けた場合は、ラベルを表示しません。
	 * また、categoryCutNo が指定された場合は、categorySkip は使用されません。
	 *
	 * @param	cateCutNo	カット文字数
	 * @see		#setCategorySkip( int )
	 */
	public void setCategoryCutNo( final int cateCutNo ) {
		if( cateCutNo > 0 ) {
			categoryCutNo = cateCutNo;
		}
	}

	/**
	 * 複数シリーズのピックアップを行う場合のシリーズ番号を取得します。
	 *
	 * 方向は、上方向に対して、(PI / 指示数) で求まる値に設定します。
	 * この指示数に相当する値を設定します。
	 * 0 を指定した場合は、何も設定しません。(初期設定のまま)
	 * (※ 本来は、ChartDataset に持つべき属性です。)
	 *
	 * @return	シリーズ番号
	 * @see     #setSeriesPikup( int )
	 */
	protected int getSeriesPikup() { return seriesPikup; }

	/**
	 * 縦軸のグリッド線(水平線)をスキップする間隔を指定します(初期値:-1)。
	 *
	 * 縦軸のグリッド線を表示する際に、スキップする間隔を指定します。
	 * 通常は、ラベルと同じだけのグリッド線が掛かれますが、ラベルよりも
	 * 少ない数のグリッド線(例えば、２つおき)を出す場合に、値を設定します。
	 * "1" (初期値)では、１つづつ表示(つまり、すべて表示する)します。
	 * "2" とすると、１つおきに、"3" とすると、２つおきに表示します。
	 * なお、先頭から表示を開始します。
	 *
	 * 6.0.2.0 (2014/09/19) 前回の JFreeChart のVerUpで、グリッド線の表示が
	 * ５個おきに変わったようです。設定する値を マイナスにすると、初期設定の値を
	 * 使用するように変更します。微調整は、個々にお願いします。
	 *
	 * 初期値は、"-1" (設定しない)です。
	 *
	 * @og.rev 4.1.1.0 (2008/02/04) 新規追加
	 * @og.rev 6.0.2.0 (2014/09/19) rangeSkip 属性 の初期値を、-1(設定なし)に変更
	 *
	 * @param	rngSkip	縦軸のグリッド線(水平線)をスキップする間隔
	 */
	public void setRangeSkip( final int rngSkip ) {
		rangeSkip = rngSkip;
	}

	/**
	 * クリッカブル・マップ用URLを指定します。
	 *
	 * 画像に、クリッカブル・マップを作成する場合の、URL を指定します。
	 * これは、画像上にエリア指定でリンク引数を作成することが可能です。
	 * URL 自身は、? 付きで固定値の引数を連結することが可能です。
	 * クリックしたエリアのカテゴリやインデックスの値(引数)は、自動的に
	 * 設定されます。(指定しない場合はチャートによって異なります)
	 * <pre>
	 * ・Pie      ：category、pieIndex
	 * ・XY       ：series、item
	 * ・Category ：series、category
	 * </pre>
	 * この引数の URL の名称を変更したい場合は、URL に続けて、カンマ(,) で、
	 * 名称を記述してください。
	 * 例：link.jsp,BLOCK
	 *
	 * @param	imageMapUrl	クリッカブル・マップ用URL
	 */
	public void setImageMapUrl( final String imageMapUrl ) {
		if( imageMapUrl != null ) {
			urlGen = new HybsURLGenerator( imageMapUrl );
		}
	}

	/**
	 * クリッカブル・マップ用URLを取得します。
	 *
	 * @return	クリッカブル・マップ用URL
	 * @see     #setImageMapUrl( String )
	 */
	protected HybsURLGenerator getURLGenerator() { return urlGen; }

	/**
	 * ツールチップス利用(true)利用しない(false)のフラグを取得します。
	 *
	 * @og.rev 4.3.1.0 (2008/08/09) 新規追加
	 * @og.rev 4.9.9.9 (2009/08/07) メソッド名変更
	 *
	 * @return	ツールチップス利用(true)利用しない(false)のフラグ
	 * @see     #setUseToolTip( boolean )
	 */
	protected boolean isUseToolTip() { return useToolTip; }

	/**
	 * カテゴリマージン(0.0～1.0)を指定します。
	 *
	 * カテゴリ(グラフの横軸に相当)の表示間隔(マージン)の比率を指定します。
	 * この比率は、％ ではなく、数字(double)での設定になります。
	 * 何も指定しない場合は、デフォルトで自動調整されます。
	 *
	 * @og.rev 4.0.2.0 (2007/12/20) 新規追加
	 *
	 * @param	margin	カテゴリマージン(0.0～1.0)
	 */
	public void setCategoryMargin( final String margin ) {
		categoryMargin = margin;
	}

	/**
	 * 下方マージン(0.0～1.0)を指定します。
	 *
	 * カテゴリ(グラフの横軸に相当)の下方側(左側)のマージンの比率を指定します。
	 * この比率は、％ ではなく、数字(double)での設定になります。
	 * 何も指定しない場合は、デフォルトで自動調整されます。
	 *
	 * @og.rev 4.0.2.0 (2007/12/20) 新規追加
	 *
	 * @param	margin	下方マージン(0.0～1.0)
	 */
	public void setLowerMargin( final String margin ) {
		lowerMargin = margin;
	}

	/**
	 * 上方マージン(0.0～1.0)を指定します。
	 *
	 * カテゴリ(グラフの横軸に相当)の上方側(右側)のマージンの比率を指定します。
	 * この比率は、％ ではなく、数字(double)での設定になります。
	 * 何も指定しない場合は、デフォルトで自動調整されます。
	 *
	 * @og.rev 4.0.2.0 (2007/12/20) 新規追加
	 *
	 * @param	margin	上方マージン(0.0～1.0)
	 */
	public void setUpperMargin( final String margin ) {
		upperMargin = margin;
	}

	/**
	 * 横軸のグリッド表示有無(垂直線)を指定します(初期値:false)。
	 *
	 * ドメイン(横軸)に対する、グリッドラインを表示するかどうか指定します。
	 *
	 * 何も指定しない場合は、表示しません。(false)
	 *
	 * @og.rev 4.0.3.0 (2008/01/07) 新規追加
	 *
	 * @param	useLine	横軸のグリッド表示有無(垂直線)
	 */
	public void setUseDomainLine( final boolean useLine ) {
		useDomainLine = useLine;
	}

	/**
	 * 横軸のグリッド線の色を指定します。
	 *
	 * ドメイン(横軸)に対する、グリッドラインの表示色を指定します。
	 * 何も指定しない場合は、デフォルトで自動設定されます。
	 *
	 * @og.rev 4.0.3.0 (2008/01/07) 新規追加
	 * @og.rev 6.0.2.1 (2014/09/26) StringUtil → ColorMap
	 *
	 * @param	color	横軸のグリッド線の色
	 */
	public void setDomainLineColor( final String color ) {
		if( color != null ) {
			domainLineColor = ColorMap.getColorInstance( color );		// 6.0.2.1 (2014/09/26) StringUtil → ColorMap
		}
	}

	/**
	 * 縦軸のグリッド表示有無(水平線)を指定します(初期値:true)。
	 *
	 * レンジ(縦軸)に対する、グリッドラインを表示するかどうか指定します。
	 *
	 * 何も指定しない場合は、表示しません。(false)
	 *
	 * @og.rev 4.0.3.0 (2008/01/07) 新規追加
	 *
	 * @param	useLine	横軸のグリッド表示有無(垂直線)
	 */
	public void setUseRangeLine( final boolean useLine ) {
		useRangeLine = useLine;
	}

	/**
	 * ツールチップスを利用(true)/利用しない(false)を指定します(初期値:false)。
	 *
	 * @og.rev 4.3.1.0 (2008/08/09) 新規追加
	 *
	 * @param	toolTip	ツールチップスを利用(true)/利用しない(false)
	 */
	public void setUseToolTip( final boolean toolTip ) {
		useToolTip = toolTip;
	}

	/**
	 * 縦軸のグリッド線の色を指定します。
	 *
	 * レンジ(縦軸)に対する、グリッドラインの表示色を指定します。
	 * 何も指定しない場合は、デフォルトで自動設定されます。
	 *
	 * @og.rev 4.0.3.0 (2008/01/07) 新規追加
	 * @og.rev 6.0.2.1 (2014/09/26) StringUtil → ColorMap
	 *
	 * @param	color	縦軸のグリッド線の色
	 */
	public void setRangeLineColor( final String color ) {
		if( color != null ) {
			rangeLineColor = ColorMap.getColorInstance( color );		// 6.0.2.1 (2014/09/26) StringUtil → ColorMap
		}
	}

	/**
	 * 横軸のグリッド(垂直線)の書き出し位置(START,MIDDLE,END)を指定します。
	 *
	 * 横軸のグリッド(垂直線)を、グラフのどの位置に記述するかを指定します。
	 * 具体的な値は、CategoryAnchor オブジェクトの値になります。
	 * ここでは、文字列で(START,MIDDLE,END)を指定します。(先頭一文字で判定)
	 * 何も指定しない場合は、デフォルト(MIDDLE)です。
	 *
	 * @og.rev 4.1.1.0 (2008/02/14) 新規追加
	 *
	 * @param	anchor	横軸のグリッド(垂直線)の書き出し位置(START,MIDDLE,END)
	 */
	public void setCategoryAnchor( final String anchor ) {
		if( anchor != null && anchor.length() > 0 ) {
			final char anc = anchor.charAt(0);
			switch( anc ) {
				case 'S' : categoryAnchor = CategoryAnchor.START;	break;
				case 'M' : categoryAnchor = CategoryAnchor.MIDDLE;	break;
				case 'E' : categoryAnchor = CategoryAnchor.END;		break;
				default  :
					final String errMsg = "指定のAnchorは適用できません。[" + anchor + "]"
							+ CR
							+ "START,MIDDLE,END の中から、指定してください。" ;
					throw new HybsSystemException( errMsg );
			}
		}
	}

	/**
	 * Time,XYTime Polt関係の時間軸を表す場合のフォーマットを指定します。
	 *
	 * TimeSeries 関連のデータを扱う場合の横軸の日付フォーマットを指定します。
	 * 日付フォーマットは、java.text.SimpleDateFormat で使われる yyyy/MM/dd HH:mm:ss 表記です。
	 * 
	 * 初期値は、"MM/dd" です。
	 *
	 * @og.rev 5.6.1.0 (2013/02/01) 新規追加
	 *
	 * @param	dtFormat	Time,XYTime Polt関係の時間軸を表す場合のフォーマット
	 */
	public void setDateAxisFormat( final String dtFormat ) {
		if( dtFormat != null && dtFormat.length() > 0 ) {
			dateAxisFormat	= dtFormat;
		}
	}

	/**
	 * Time,XYTime Polt関係の時間軸で、SegmentedTimeline 関係の情報をセットします。
	 *
	 * segSizeは、分単位の数値です。日単位を指定する場合は、24*60 = 1440 を指定します。
	 * 0 または、何も指定しない場合は、その他の情報を使用しません。 (SegmentedTimeline を使用しません。)
	 * 
	 * <pre>
	 *   start time
	 *     |
	 *     v
	 *     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 ...
	 *   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
	 *   |  |  |  |  |  |EE|EE|  |  |  |  |  |EE|EE|  |  |  |  |  |EE|EE|
	 *   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
	 *   [_____________] [___]            [_]
	 *          |          |               |
	 *       included   excluded        segment
	 *       segments   segments         size
	 *   [___________________]
	 *              |
	 *         segment group
	 * </pre>
	 *
	 * @og.rev 6.7.3.0 (2017/01/27) 新規追加
	 *
	 * @param	segSize		SegmentedTimelineのsegment size を、分単位で指定
	 * @param	segIncluded	SegmentedTimelineのincluded segments(ｽﾍﾟｰｽ)を数値で指定
	 * @param	segExcluded	SegmentedTimelineのexcluded segments(EE)を数値で指定
	 * @param	startTime	SegmentedTimelineのStartTime(segment groupの開始位置)
	 */
	public void setSegmentedTimelineInfo( final int segSize , final int segIncluded , final int segExcluded , final String startTime ) {
		if( segSize > 0 ) {
			// 6.9.8.0 (2018/05/28) FindBugs:整数乗算の結果を long にキャストしている
//			timeLine = new SegmentedTimeline( segSize * 60 * 1000 , segIncluded , segExcluded );
			timeLine = new SegmentedTimeline( segSize * TIME_LINE , segIncluded , segExcluded );
			if( startTime != null && startTime.length() >= 8 ) {
				final Calendar cal = HybsDateUtil.getCalendar( startTime );
				timeLine.setStartTime( cal.getTimeInMillis() );
			}
		}
	}

	/**
	 * Time,XYTime Polt関係の時間軸を表す DateAxis オブジェクトを返します。
	 *
	 * このオブジェクトは、domainLabel で名前付けされた DateAxis で、日付フォーマットは、
	 * dateAxisFormat で DateFormat を Override しています。
	 * 初期フォーマットは、"MM/dd" です。
	 *
	 * @og.rev 5.6.1.0 (2013/02/01) 新規追加
	 * @og.rev 5.6.4.3 (2013/05/24) 横軸ラベルを９０度傾ける処理を追加
	 * @og.rev 6.7.3.0 (2017/01/27) 日付軸(dateAxis)の指定で、dateSegSize,dateSegIncluded,dateSegExcluded,dateStartTime を追加します。
	 *
	 * @return	DateAxisオブジェクト(Time,XYTime Polt関係の時間軸表現)
	 */
	protected DateAxis getDateAxis() {
		final DateAxis daxis = new DateAxis( domainLabel );
		daxis.setDateFormatOverride( new SimpleDateFormat( dateAxisFormat,Locale.JAPAN ) );

		// 5.6.4.3 (2013/05/24) 時間関係の横軸は、rotationLabel ではなく、useVerticalLabels を使います。
		if( useVerticalLabels ) {
			daxis.setVerticalTickLabels( useVerticalLabels );
		}

		if( timeLine != null ) { daxis.setTimeline( timeLine );  }		// 6.7.3.0 (2017/01/27)

		return daxis;
	}

	/**
	 * デバッグフラグを指定します。
	 *
	 * true に設定すると、チャートの状態を System.out.println します。
	 *
	 * @og.rev 4.0.2.0 (2007/12/20) 新規追加
	 *
	 * @param   flag デバッグフラグ [true:デバッグ/false:通常]
	 */
	public void setDebug( final boolean flag ) {
		isDebug = flag;
	}
}
