package org.opengion.hayabusa.taglib;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;											// 6.4.3.4 (2016/03/11)
import java.util.Iterator;										// 6.7.7.0 (2017/03/31)
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.opengion.hayabusa.db.DBTableModelSorter;
import org.opengion.hayabusa.db.DBTableModel;
import org.opengion.hayabusa.common.HybsSystem;
import org.opengion.hayabusa.common.HybsSystemException;
import org.opengion.hayabusa.db.DBColumn;						// 6.8.3.1 (2017/12/01)

import org.opengion.hayabusa.io.JsChartData;
import org.opengion.fukurou.util.ArraySet;						// 6.4.3.4 (2016/03/11)
import org.opengion.fukurou.util.ToString;
import org.opengion.fukurou.util.StringUtil;					// 6.8.3.1 (2017/12/01)
import static org.opengion.fukurou.util.StringUtil.nval ;

/**
 * JsChart は、JavascriptのjsChart用のｽｸﾘﾌﾟﾄを出力するクラスです。
 * 複数の JsChartData オブジェクトを合成することも、ここで行っています。
 * ChartJSを利用しているため、標準属性以外の項目をセットする場合はoptionAttributesで行ってください。
 * 例えばアニメーションをOFFにする場合はanimation:falseをセットします。
 * 
 * 出力されるスクリプトでは、idを指定しない場合はhybscanvas[tableId]が利用されます。
 * 複数のグラフを同一画面で出力する場合はidかtableIdを変えてください。
 * チャートオブジェクトはchart_[id]という名前で作成されるため、ajax等でコントロールが必要な場合は利用してください。
 * 
 * @og.formSample
 * ●形式：&lt;og:column chartType="…" ... /&gt;
 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{$#064;XXXX} を解析します)
 * 
 * ●Tag定義：
 *  &lt;og:jsChart
 *      chartType       ○【TAG】ﾁｬｰﾄの種類を指定します[line/bar/horizontalBar/radar/polarArea/pie/doughnut](必須)。
 *      labelColumn     ○【TAG】ﾗﾍﾞﾙのｶﾗﾑ名を指定します(表示名称）(必須)。
 *      id                【TAG】canvasﾀｸﾞのidを指定します(初期値:hybscanvas)。
 *      height            【TAG】ﾁｬｰﾄの高さを指定します(初期値:400)。
 *      width             【TAG】ﾁｬｰﾄの幅を指定します(初期値:400)。
 *      title             【TAG】ﾀｲﾄﾙを指定します。
 *      titlePosition     【TAG】ﾀｲﾄﾙの表示位置[top/right/bottom/left]を指定します(初期値:top)。
 *      legendDisplay     【TAG】凡例を表示するか[true/false]を指定します。
 *      legendPosition    【TAG】凡例の表示位置[top/right/bottom/left]を指定します(初期値:top)。
 *      barWidthPer       【TAG】棒線の横幅を指定します(初期値:0.8, typeがbar,horizontalBarの場合に有効)。
 *      onClick           【TAG】ﾁｬｰﾄｸﾘｯｸ時のｲﾍﾞﾝﾄを指定します。
 *      usePointStyle     【TAG】点のスタイル属性を使用するかどうか[true/false]を指定します(初期値:null)。	// 6.8.5.0 (2018/01/09)
 *  ===================
 *      xscaleType        【TAG】x軸のｽｹｰﾙﾀｲﾌﾟ[category/time/linear]を指定します(初期値:category)。
 *      xlabel            【TAG】x軸のラベルを指定します。
 *      xscaleCallback    【TAG】x軸ｺｰﾙﾊﾞｯｸを指定します。
 *      xbeginAtZero      【TAG】x軸を０から書き始まるかどうか(初期値:true)		// 6.8.5.0 (2018/01/09)
 *      xmax              【TAG】x軸の最大値を指定します(xscaleTypeがlinearの場合に有効)。
 *      xmin              【TAG】x軸の最小値を指定します(xscaleTypeがlinearの場合に有効)。
 *      xstepSize         【TAG】x軸のメモリ幅を指定します(xscaleTypeがlinearの場合に有効)。
 *  ===================
 *      timeUnit          【TAG】x軸のﾀｲﾑの単位[year/quarter/month/week/day/hour/minute/second/millsecond]を指定します(xscaleTypeがtimeの場合に有効。指定しない場合は自動)。
 *      timeUnitStepSize  【TAG】x軸のﾀｲﾑの単位幅を指定します。(xscaleTypeがtimeの場合に有効)
 *      timeSetFormat     【TAG】x軸の設定するﾀｲﾑのﾌｫｰﾏｯﾄを指定します(xscaleTypeがtimeの場合に有効)。
 *      timeLblFormat     【TAG】x軸の表示するﾀｲﾑのﾌｫｰﾏｯﾄを指定します(xscaleTypeがtimeの場合に有効)。
 *      timeMax           【TAG】x軸のﾀｲﾑの最大値を指定します(xscaleTypeがtimeの場合に有効)。
 *      timeMin           【TAG】x軸のﾀｲﾑの最小値を指定します(xscaleTypeがtimeの場合に有効)。
 *  ===================
 *      yscaleType        【TAG】y軸のｽｹｰﾙﾀｲﾌﾟ[linear/category]を指定します(初期値:linear)。
 *      ylabel            【TAG】y軸のラベルを指定します。
 *      yscaleCallback    【TAG】y軸ｺｰﾙﾊﾞｯｸを指定します。
 *      ybeginAtZero      【TAG】y軸を０から書き始まるかどうか(初期値:true)(円形の場合もこの値)		// 6.8.5.0 (2018/01/09)
 *      max               【TAG】y軸の最大値を指定します(yscaleTypeがlinearの場合に有効)。
 *      min               【TAG】y軸の最小値を指定します(yscaleTypeがlinearの場合に有効)。
 *      stepSize          【TAG】y軸のメモリ幅を指定します(yscaleTypeがlinearの場合に有効)。
 *      ycategoryList     【TAG】y軸のﾒﾓﾘﾘｽﾄをカンマ区切りで指定します(yscaleTypeがcategoryの場合に有効)
 *  ===================
 *      markValues        【TAG】マーカーラインの設定値をCSV形式で複数指定します	// 6.8.5.0 (2018/01/09)
 *      markColors        【TAG】マーカーラインの色をCSV形式で複数指定します		// 6.8.5.0 (2018/01/09)
 *      markLbls          【TAG】マーカーラインのラベルをCSV形式で複数指定します(未指定時はラベルを表示しません)	// 6.8.5.0 (2018/01/09)
 *      markAdjust        【TAG】マーカーラインのラベル表示位置の上下方向を調整します(＋でラインの下側、－で上側に位置を移動します。初期値:-6)。	// 6.8.5.0 (2018/01/09)
 *  ===================
 *      useZoom           【TAG】ズーム処理を使用するかどうか[true/false]を指定します。	// 6.8.5.0 (2018/01/09)
 *  ===================
 *      widthEventColumn  【TAG】横幅を動機に設定するｶﾗﾑのIDを指定します。
 *      heightEventColumn 【TAG】縦幅を動的に設定するｶﾗﾑのIDを指定します。
 *      minEventColumn    【TAG】minを動的に設定するｶﾗﾑのIDを指定します。 
 *      maxEventColumn    【TAG】maxを動的に設定するｶﾗﾑのIDを指定します。 
 *  ===================
 *      useZeroDataOmit   【TAG】ﾃﾞｰﾀが０の場合、使用しない（除外する）かどうかを指定します[true:０ﾃﾞｰﾀを除外する](初期値:false)
 *      useRenderer       【TAG】データ出力でレンデラを利用するかどうか(初期値:false)
 *      sortColumn        【TAG】検索結果をこのカラムでソートしなおします(初期値:null)。
 *      optionAttributes  【TAG】その他ｵﾌﾟｼｮﾝを指定します。
 *      tableid           【TAG】(通常は使いません)sessionから所得する DBTableModelオブジェクトの ID
 *      scope             【TAG】キャッシュする場合のスコープ[request/page/session/application]を指定します(初期値:session)
 *      caseKey           【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
 *      caseVal           【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
 *      caseNN            【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
 *      caseNull          【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
 *      caseIf            【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
 *      debug             【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
 *  &gt;   ... Body ...
 *  &lt;/og:jsChart&gt;
 *
 * ●使用例
 *      &lt;og:jsChart
 *          chartType      = "[line/bar/horizontalBar/radar/polarArea/pie/doughnut]"
 *          labelColumn    = "LDATA"
 *          id             = "hybscanvas"
 *          height         = "400"
 *          width          = "400"
 *          title          = "タイトル"
 *          titlePosition  = "top"				[top/right/bottom/left]
 *          ylabel         = "給料"
 *          xlabel         = "名称"
 *          legendPosition = "right"			[top/right/bottom/left]
 *          legendDisplay  = "true"				[true/false]
 *          xsclaeCallback = "function(value){return value + ' 様';}"
 *          ysclaeCallback = "function(value){return value.toLocaleString();}"
 *          xscaleType     = "time"
 *          max            = "1000000"
 *          min            = "100000"
 *          stepSize       = "10000"
 *          barWidthPer    = "0.4"
 *      &gt;
 *          &lt;og:jsChartData ... /&gt;
 *      &lt;/og:jsChart&gt;
 *      
 * @og.group 画面表示
 * 
 * @version	5.9.17.2		2017/02/08
 * @author	T.OTA
 * @since	JDK7.0
 *
 */
public class JsChartTag extends CommonTagSupport {
	//* このプログラムのVERSION文字列を設定します。{@value} */
	private static final String VERSION = "6.9.7.0 (2018/05/14)" ;
	private static final long serialVersionUID = 697020180514L ;

	/** chartType 引数に渡す事の出来る タイプ 折れ線 {@value} **/
	public static final String		CTYPE_LINE			= "line";
	/** chartType 引数に渡す事の出来る タイプ 棒線 {@value} **/
	public static final String		CTYPE_BAR			= "bar";
	/** chartType 引数に渡す事の出来る タイプ 横棒線 {@value} **/
	public static final String		CTYPE_HBAR			= "horizontalBar";
	/** chartType 引数に渡す事の出来る タイプ レイダー {@value} **/
	public static final String		CTYPE_RADAR			= "radar";
	/** chartType 引数に渡す事の出来る タイプ ポーラエリア {@value} **/
	public static final String		CTYPE_PA			= "polarArea";
	/** chartType 引数に渡す事の出来る タイプ 円 {@value} **/
	public static final String		CTYPE_PIE			= "pie";
	/** chartType 引数に渡す事の出来る タイプ ドーナツ {@value} **/
	public static final String		CTYPE_DOUGHNUT		= "doughnut";
	/** chartType 引数に渡す事の出来る タイプ リスト {@value} */

	private static final Set<String> CTYPE_SET = new ArraySet<>( CTYPE_LINE, CTYPE_BAR, CTYPE_HBAR, CTYPE_RADAR, CTYPE_PA, CTYPE_PIE, CTYPE_DOUGHNUT );

	/** chartType が円形のリスト */
	private static final String[]	CTYPE_CI		= new String[] { CTYPE_RADAR, CTYPE_PA, CTYPE_PIE, CTYPE_DOUGHNUT };

	private static final String TYPE_CATEGORY		= "category";
	private static final String TYPE_TIME			= "time";
	private static final String TYPE_LINEAR			= "linear";

	private static final Set<String> SET_POSITION	= new ArraySet<>( "top", "right", "bottom", "left" );
	private static final Set<String> SET_TIMEUNIT	= new ArraySet<>( "year", "quarter", "month", "week", "day", "hour", "minute", "second", "millsecond" );
	private static final Set<String> SET_XSCALE		= new ArraySet<>( TYPE_CATEGORY, TYPE_TIME, TYPE_LINEAR );
	private static final Set<String> SET_YSCALE		= new ArraySet<>( TYPE_LINEAR, TYPE_CATEGORY );
	private static final Set<String> SET_BOOLEAN	= new ArraySet<>( "true", "false" );

	private static final String 	CANVAS_NAME		= "hybscanvas";

	private static final String		MARK_DEF_COLOR	= "BLUE";		// 6.8.5.0 (2018/01/09) マーカーラインの色の初期値
	private static final String		MARK_DEF_ADJUST	= "-6";			// 6.8.5.0 (2018/01/09) マーカーラインの位置調整の初期値

	// 変数宣言
	private final List<JsChartData>	jsChartData = new ArrayList<JsChartData>() ;		// 6.7.5.0 (2017/03/10) jsChartDataのﾘｽﾄ
	private String	chartType			;							// ﾁｬｰﾄﾀｲﾌﾟ(必須)
	private String	labelColumn			;							// ﾗﾍﾞﾙｶﾗﾑ(必須)
	private String	id					;							// canvasﾀｸﾞのid
	private String	height				= "400";					// canvasﾀｸﾞのheight
	private String	width				= "400";					// canvasﾀｸﾞのwidth
	private String	title				;							// ﾀｲﾄﾙ
	private String	titlePosition		;							// ﾀｲﾄﾙ位置
	private String	legendPosition		;							// 凡例位置
	private String	legendDisplay		;							// 凡例表示ﾌﾗｸﾞ
	private String	barWidthPer			= "0.8";					// 棒線の横幅(ﾊﾟｰｾﾝﾄ)
	private String	onClick				;							// ｸﾘｯｸｲﾍﾞﾝﾄ
	private String	usePointStyle		;							//  6.8.5.0 (2018/01/09) 点のスタイル属性を使用するかどうか(初期値:false)
	private String	xlabel				;							// x軸ﾗﾍﾞﾙ
	private String	xscaleCallback		;							// x軸のﾒﾓﾘ編集用ｺｰﾙﾊﾞｯｸ
	private String	xscaleType			= TYPE_CATEGORY ;			// x軸のｽｹｰﾙﾀｲﾌﾟ
	private boolean	xbeginAtZero		= true;						//  6.8.5.0 (2018/01/09) x軸を０から書き始まるかどうか(初期値:true)
	private String	xmax				;							// x軸の最大値(ﾘﾆｱｽｹｰﾙ用)
	private String	xmin				;							// x軸の最小値(ﾘﾆｱｽｹｰﾙ用)
	private String	xstepSize			;							// x軸のﾒﾓﾘ幅(ﾘﾆｱｽｹｰﾙ用)
	private String	timeUnit			;							// 時間の単位(ﾀｲﾑｽｹｰﾙ用)
	private String	timeUnitStepSize	;							// 時間のﾒﾓﾘ幅(ﾀｲﾑｽｹｰﾙ用)
	private String	timeSetFormat		;							// 時間の入力ﾌｫｰﾏｯﾄ(ﾀｲﾑｽｹｰﾙ用)
	private String	timeLblFormat		;							// 時間の表示ﾌｫｰﾏｯﾄ(ﾀｲﾑｽｹｰﾙ用)
	private String	timeMax				;							// 最大の時間(ﾀｲﾑｽｹｰﾙ用)
	private String	timeMin				;							// 最小の時間(ﾀｲﾑｽｹｰﾙ用)
	private String	ylabel				;							// y軸ﾗﾍﾞﾙ
	private String	yscaleCallback		;							// y軸のﾒﾓﾘ編集用ｺｰﾙﾊﾞｯｸ
	private String	yscaleType			= TYPE_LINEAR;				// y軸のｽｹｰﾙﾀｲﾌﾟ
	private String	stepSize			;							// y軸のﾒﾓﾘ幅(ﾘﾆｱｽｹｰﾙ用)
	private String	ycategoryList		;							// y軸のｶﾃｺﾞﾘｰﾘｽﾄ(ｶﾃｺﾞﾘｰｽｹｰﾙ用)
	private boolean	ybeginAtZero		= true;						//  6.8.5.0 (2018/01/09) y軸を０から書き始まるかどうか(初期値:true)(円形の場合もこの値)
	private String	max					;							// y軸の最大値(ﾘﾆｱｽｹｰﾙ用)
	private String	min					;							// y軸の最小値(ﾘﾆｱｽｹｰﾙ用)
	private String	tableId				= HybsSystem.TBL_MDL_KEY;	// ﾃｰﾌﾞﾙid
	private String	markValues			;							// 6.8.5.0 (2018/01/09) マーカーラインの設定値をCSV形式で複数指定します	
	private String	markColors			;							// 6.8.5.0 (2018/01/09) マーカーラインの色をCSV形式で複数指定します
	private String	markLbls			;							// 6.8.5.0 (2018/01/09) マーカーラインのラベルをCSV形式で複数指定します(未指定時はラベルを表示しません)
	private String	markAdjust			;							// 6.8.5.0 (2018/01/09) マーカーラインのラベル表示位置の上下方向を調整します(初期値:-6)。
	private boolean	useZoom				;							// 6.8.5.0 (2018/01/09) ズーム処理を使用するかどうか(初期値:false)
	private String	widthEventColumn	;							// 横幅の動的参照ｶﾗﾑ	2017/03/28 ADD
	private String	heightEventColumn	;							// 縦幅の動的参照ｶﾗﾑ	2017/03/28 ADD
	private String	minEventColumn		;							// 最小値の動的参照ｶﾗﾑ	2017/03/28 ADD
	private String	maxEventColumn		;							// 最大値の動的参照ｶﾗﾑ	2017/03/28 ADD
	private boolean useZeroDataOmit		;							// 6.7.7.0 (2017/03/31) ﾃﾞｰﾀが０の場合、使用しない（除外する）かどうか
	private boolean useRenderer			;							// 6.7.9.0 (2017/04/28) useRenderer 追加
	private String	sortColumn			;							// 6.8.0.0 (2017/06/02) 検索結果をこのカラムでソートしなおします(初期値:null)。
	private String	optionAttributes	;							// ｵﾌﾟｼｮﾝ

	/**
	 * デフォルトコンストラクター
	 *
	 * @og.rev 6.9.7.0 (2018/05/14) PMD Each class should declare at least one constructor
	 */
	public JsChartTag() { super(); }		// これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。

	/**
	 * タグリブオブジェクトをリリースします。
	 * キャッシュされて再利用されるので、フィールドの初期設定を行います。
	 * 
	 * @og.rev 6.7.5.0 (2017/03/10) jsChartData属性の初期化もれ
	 * @og.rev 5.9.19.0 (2017/04/07)	T.OTA 61200-170316-02	ﾁｬｰﾄｻｲｽﾞ・max・minの動的変更対応
	 * @og.rev 6.7.7.0 (2017/03/31) useZeroDataOmit属性の追加
	 * @og.rev 6.7.9.0 (2017/04/28) useRenderer 追加
	 * @og.rev 6.8.0.0 (2017/06/02) sortColumn 追加
	 * @og.rev 6.8.3.0 (2017/11/27) useEqValOmit属性の追加
	 * @og.rev 6.8.5.0 (2018/01/09) xbeginAtZero,ybeginAtZero,markValues,markColors,markLbls,markAdjust,rangeMin,rangeMax,usePointStyle属性の追加
	 */
	@Override
	protected void release2() {
		super.release2();
		jsChartData.clear();				// 6.7.5.0 (2017/03/10)
		chartType			= null;
		id					= null;
		height				= "400";
		width				= "400";
		labelColumn			= null;
		title				= null;
		titlePosition		= null;
		legendPosition		= null;
		legendDisplay		= null;
		barWidthPer			= "0.8";
		onClick				= null;
		usePointStyle		= null;		// 6.8.5.0 (2018/01/09) 点のスタイル属性を使用するかどうか
		xlabel				= null;
		xscaleCallback		= null;
		xscaleType			= TYPE_CATEGORY;
		xbeginAtZero		= true;		//  6.8.5.0 (2018/01/09) x軸を０から書き始まるかどうか(初期値:true)
		xmax				= null;
		xmin				= null;
		xstepSize			= null;
		timeUnit			= null;
		timeUnitStepSize	= null;
		timeSetFormat		= null;
		timeLblFormat		= null;
		timeMax				= null;
		timeMin				= null;
		ylabel				= null;
		yscaleCallback		= null;
		yscaleType			= TYPE_LINEAR;
		ycategoryList		= null;
		ybeginAtZero		= true;		//  6.8.5.0 (2018/01/09) y軸を０から書き始まるかどうか(初期値:true)(円形の場合もこの値)
		max					= null;
		min					= null;
		stepSize			= null;
		tableId				= HybsSystem.TBL_MDL_KEY;
		markValues			= null;		// 6.8.5.0 (2018/01/09) マーカーラインの設定値をCSV形式で複数指定します	
		markColors			= null;		// 6.8.5.0 (2018/01/09) マーカーラインの色をCSV形式で複数指定します
		markLbls			= null;		// 6.8.5.0 (2018/01/09) マーカーラインのラベルをCSV形式で複数指定します(未指定時はラベルを表示しません)
		markAdjust			= null;		// 6.8.5.0 (2018/01/09) マーカーラインのラベル表示位置の上下方向を調整します(初期値:-6)。
		useZoom				= false;	// 6.8.5.0 (2018/01/09) ズーム処理を使用するかどうか(初期値:false)
		widthEventColumn	= null;		// 5.9.19.0	
		heightEventColumn	= null;		// 5.9.19.0	
		maxEventColumn		= null;		// 5.9.19.0	
		minEventColumn		= null;		// 5.9.19.0	
		useZeroDataOmit		= false;	// 6.7.7.0 (2017/03/31) ﾃﾞｰﾀが０の場合、使用しない（除外する）かどうか
		useRenderer			= false;	// 6.7.9.0 (2017/04/28) useRenderer 追加
		sortColumn			= null;		// 6.8.0.0 (2017/06/02) 検索結果をこのカラムでソートしなおします(初期値:null)。
		optionAttributes	= null;
	}

	/**
	 * Taglibの開始タグが見つかった時に処理する doStartTag() を オーバーライドします。
	 * 
	 * @og.rev 6.7.5.0 (2017/03/10) タグの使用を決める共通属性の追加
	 * 
	 * @return 後続処理の指示
	 */
	@Override
	public int doStartTag() {
		if( !useTag() ) { return SKIP_BODY ; }		// 6.7.5.0 (2017/03/10)

		// ﾁｪｯｸ処理の実行
		checkData();

		return EVAL_BODY_BUFFERED; // Bodyを評価する
	}

	/**
	 * ﾁｪｯｸ処理。
	 */
	private void checkData() {
		// xscaleTypeに「linear」、yscaleTypeに「category」を指定した場合は、エラー
		if( TYPE_LINEAR.equals( xscaleType ) && TYPE_CATEGORY.equals( yscaleType ) ) {
			final StringBuilder errMsg = new StringBuilder( BUFFER_MIDDLE )
				.append( "指定のｽｹｰﾙﾀｲﾌﾟの組み合わせは実行できません。" )
				.append( CR )
				.append( "xscaleType:" ).append( xscaleType ).append( " yscaleType:" ).append( yscaleType );

			throw new HybsSystemException( errMsg.toString() );
		}
	}

	/**
	 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
	 * 
	 * @og.rev 6.7.5.0 (2017/03/10) タグの使用を決める共通属性の追加
	 * 
	 * @return 後続処理の指示
	 */
	@Override
	public int doEndTag() {
		debugPrint();
		if( !useTag() ) { return EVAL_PAGE ; }			// 6.7.5.0 (2017/03/10)

		id = (id==null ? CANVAS_NAME + tableId : id );	// id指定なしの場合はCANVAS_NAME+tableId

		// jsChart出力
		jspPrint( jsChartOutput() );

		return EVAL_PAGE;
	}

	/**
	 * jsChart出力用
	 * jsChartTag と jsChartData を使用して、jsChart情報を出力します。
	 * 
	 * @og.rev 5.9.19.0 (2017/04/07) T.OTA 61200-170316-02	ﾁｬｰﾄｻｲｽﾞ・max・minの動的変更対応
	 * @og.rev 6.7.7.0 (2017/03/31) ﾁｬｰﾄﾃﾞｰﾀで、ｾﾞﾛ、null カラムを非表示にします。
	 * @og.rev 6.7.9.0 (2017/04/28) useRenderer 追加
	 * @og.rev 6.8.0.0 (2017/06/02) sortColumn 追加
	 * @og.rev 6.8.3.0 (2017/11/27) useZeroDataOmit属性で、nullOmit属性もセットします。
	 * @og.rev 6.8.3.0 (2017/11/27) useEqValOmit属性の追加
	 * @og.rev 6.8.3.1 (2017/12/01) 不要なデータを出力しないようにします。
	 * @og.rev 5.9.27.0 2017/12/01	T.OTA 61200-170831-04	max,minの小数点対応 
	 * @og.rev 6.8.5.0 (2018/01/09) xbeginAtZero,ybeginAtZero,markValues,markColors,markLbls,markAdjust,rangeMin,rangeMax,usePointStyle属性の追加
	 * 
	 * @return jsChert用文字列
	 */
	private String jsChartOutput() {
		final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );

		// 各JavaScriptの変数名
		final String qd			= "qd_" + id;		//queryData
		final String cd			= "cd_" + id;		//chartData
		final String myChart	= "chart_"+id;
		final String lblClm		= labelColumn + id;

		// JSON形式でﾃｰﾌﾞﾙ情報を取得
		// ﾃｰﾌﾞﾙ情報の取得
		// 6.8.0.0 (2017/06/02) sortColumn 追加
		DBTableModel table = (DBTableModel)getObject( tableId ) ;
		if( !StringUtil.isNull( sortColumn ) ) {						// 6.8.5.0 (2018/01/09)
			final int clmNo = table.getColumnNo( sortColumn,false );	// エラーを出さない。

			final DBTableModelSorter temp = new DBTableModelSorter();
			temp.setModel( (DBTableModel)getObject( tableId ) );
			temp.sortByColumn( clmNo,true );							// 順方向のソート
			table = temp;
		}

//		final int rowCount = table.getRowCount();						// 6.9.2.0 (2018/03/05)

		// ｾﾞﾛﾃﾞｰﾀを使用しない設定
		if( useZeroDataOmit ) {
			final Iterator<JsChartData> itr = jsChartData.iterator();	// 個々のグラフ
			while( itr.hasNext() ) {
				final JsChartData jcData = itr.next();
				final String chtClm = jcData.getChartColumn();
				final int    clmNo  = table.getColumnNo( chtClm, false );	// エラーを出さない。

				// 6.8.3.1 (2017/12/01) ループ処理の判定は、ChartColumn のみでよい。
				boolean isRemove = true;
				if( clmNo >= 0 ) {
					for( int row=0; row<table.getRowCount(); row++ ) {
						final String val = table.getValue( row,clmNo );
						if( !StringUtil.isNull( val ) && !"0".equals( val ) && !"0.0".equals( val ) && !"0.00".equals( val )  ) {	// 6.8.5.0 (2018/01/09)
							isRemove = false;
							break;	// 判定処理打ち切り
						}
					}
				}
				if( isRemove ) {
					itr.remove();										// すべてが、ｾﾞﾛ、null カラムを、削除します。
				}
			}
		}

		// 6.8.3.1 (2017/12/01) 不要なデータを出力しないようにします。
		final int clmSize = jsChartData.size();				// JsChartTag の 値部分のみの配列

		final int[]    clmNos = new int[clmSize];
		final int      lblNos = table.getColumnNo( labelColumn, false );	// エラーを出さない。 6.9.2.0 (2018/03/05)
		final DBColumn dbClm  = table.getDBColumn( lblNos );				// 6.9.2.0 (2018/03/05)

		// jsChartDataﾀｸﾞの変数宣言
		for( int i=0; i<clmSize; i++ ) {
			final String chtClm = jsChartData.get(i).getChartColumn();
			clmNos[i] = table.getColumnNo( chtClm, false );	// エラーを出さない。
		}

		// canvasﾀｸﾞの設定
		rtn.append( "<canvas class=\""  ).append( CANVAS_NAME )
			.append( "\" id=\""			).append( id     )
			.append( "\" width=\""		).append( width  )
			.append( "\" height=\""		).append( height )
			.append( "\"><!-- --></canvas>" )

			// 6.8.3.1 (2017/12/01) 不要なデータを出力しないようにします。
			.append( "<script>var " ).append( qd ).append( "={\"DATA\":[" );		// query情報の取得(JSON)

		final boolean isYcateType  = TYPE_CATEGORY.equals( yscaleType );	// 6.8.5.0 (2018/01/09) yscaleType が category かどうか。
		final boolean isXlinerType = TYPE_LINEAR.equals( xscaleType );		// 6.8.5.0 (2018/01/09) xscaleType が linear かどうか。

		if( isXlinerType ) {
			// 何か、isXlinerType はうまく動かない
			final String[] clmNms = table.getNames();
			for( int row=0; row<table.getRowCount(); row++ ) {
				// ラベル部の出力
				rtn.append( "{\"" ).append( clmNms[lblNos] ).append( "\":\"" ).append( table.getValue( row,lblNos ) ).append( '"' );
				// データ部の出力
				for( final int clm : clmNos ) {
					final String val = table.getValue( row,clm );
					rtn.append( ",\"" ).append( clmNms[clm] ).append( "\":\"" ).append( val ).append( '"' );
				}
				rtn.append( "}," );								// 最後に
			}
			rtn.append( "]};" ).append( CR );
		}
		else {
			for( int row=0; row<table.getRowCount(); row++ ) {
				// ラベル部の出力
				final String lval = table.getValue( row,lblNos );
				final String lblVal = useRenderer ? StringUtil.jsonFilter( dbClm.getRendererValue(row,lval) ) : lval ;
				rtn.append( '[' ).append( '"' ).append( lblVal ).append( '"' );
				// データ部の出力
				for( final int clm : clmNos ) {
					final String val = table.getValue( row,clm );
					rtn.append( ',' );
					if( isYcateType ) {						// 6.8.5.0 (2018/01/09) yscaleType が category
						rtn.append( '"' ).append( val ).append( '"' );
					}
					else {
						rtn.append( val );
					}
				}
				rtn.append( "]," );
			}
			rtn.append( "]};" ).append( CR );
		}

		// jsChartDataﾀｸﾞの変数宣言
		for( int i=0; i<clmSize; i++ ) {
			rtn.append( " var " ).append( jsChartData.get( i ).getChartColumn() ).append( "=[];" );
		}
		rtn.append( "var " ).append( lblClm ).append( "=[];" )

		// query情報をjsChartDataの変数に入れ替え 
			.append( "for(var i=0; i < ").append( qd ).append( ".DATA.length; i++){" );
		for( int i=0; i<clmSize; i++ ) {
			final String chtClm = jsChartData.get( i ).getChartColumn();
			// x軸がlinearｽｹｰﾙの場合
			if( isXlinerType ) {
				// {x:ﾗﾍﾞﾙ, y:値}の形式で値を設定
				rtn.append( chtClm ).append( "[i]={x:" ).append( qd ).append( ".DATA[i]." ).append( labelColumn )
										.append( ",y:" ).append( qd ).append( ".DATA[i]." ).append( chtClm ).append( "};" );
			}
			else {
				// その他は値を設定
				rtn.append( chtClm ).append( "[i]=" ).append(qd).append( ".DATA[i][" ).append( i+1 ).append( "];" );
			}
		}
		if( isXlinerType ) {
			rtn.append( lblClm ).append( "[i]=").append( qd ).append( ".DATA[i]." ).append( labelColumn ).append( ";}" );
		}
		else {
			rtn.append( lblClm ).append( "[i]=").append( qd ).append( ".DATA[i][0];}" );
		}

		// y軸にｶﾃｺﾞﾘｰｽｹｰﾙを設定した場合
		if( isYcateType ) {
			rtn.append( "var ycateList=[];" );
			if( !StringUtil.isNull( ycategoryList ) ) {						// 6.8.5.0 (2018/01/09)
				// 「,」を「','」に変換して設定。(,前後の半角ｽﾍﾟｰｽは除去する)
				final String regex = " *, *";
				final Pattern pttn = Pattern.compile( regex );

				final Matcher mtch = pttn.matcher( ycategoryList );
				// y軸ｶﾃｺﾞﾘｰﾘｽﾄの設定
				rtn.append( "ycateList=['" ).append( mtch.replaceAll( "','" ) ).append( "'];" );
			}
		}

		// jsChartDataの設定
		rtn.append( "var ").append( cd ).append( "={labels:" ).append( lblClm );
		// y軸にｶﾃｺﾞﾘｰｽｹｰﾙを設定した場合
		if( isYcateType ) {
			rtn.append( ",yLabels:ycateList" );
		}
		rtn.append( ",datasets:[" );
		for( int i=0; i<clmSize; i++ ) {
			if( i != 0 ) {
				rtn.append( ',' );
			}
			rtn.append( jsChartData.get( i ).getParameter() );
		}
		rtn.append( "]};" )

		// jsChartの生成
			.append(  "var "    ).append( myChart   ).append( "=new Chart(" ).append( id )
			.append( ",{type:'" ).append( chartType )
			.append( "',data:"  ).append( cd )
			.append( ",options:{responsive:false" );	// ﾚｽﾎﾟﾝｼﾌﾞ OFF

		// ｸﾘｯｸｲﾍﾞﾝﾄの設定
		if( !StringUtil.isNull( onClick ) ) {						// 6.8.5.0 (2018/01/09)
			rtn.append( ",onClick:function(event,obj){" ).append( onClick ).append( '}' );
		}

		// ﾀｲﾄﾙ属性の設定
		if( !StringUtil.isNull( title ) ) {						// 6.8.5.0 (2018/01/09)
			rtn.append( ",title:{display:true" );
			setProp( rtn, ",text:'"    , title        , "'" );
			setProp( rtn, ",position:'", titlePosition, "'" );
			rtn.append( '}' );
		}

		// 凡例属性の設定
		if( !StringUtil.isNull( legendDisplay ) ) {				// 6.8.5.0 (2018/01/09)
			rtn.append( ",legend:{" );
			setProp( rtn, "display:"   , legendDisplay );
			setProp( rtn, ",position:'", legendPosition, "'" );
			rtn.append( '}' );
		}

		// 点のスタイル属性の設定
		setProp( rtn, ",usePointStyle:"	, usePointStyle );		// 6.8.5.0 (2018/01/09)

		// chartTypeの円形ﾁｪｯｸ
		final List<String> list = Arrays.asList( CTYPE_CI );
		if( list.contains( chartType ) ) {
			// 円形の場合はscale属性に値を設定
			rtn.append( ",scale:{ticks:{beginAtZero:" ).append( ybeginAtZero );		// 6.8.5.0 (2018/01/09)
			setProp( rtn, ",max:"		, max );
			setProp( rtn, ",min:"		, min );
			setProp( rtn, ",stepSize:"	, stepSize );
			rtn.append( "}}" );
		}
		else {
			// 円形以外の場合はscales属性に設定
			rtn.append( ",scales:{" );
			if( CTYPE_HBAR.equals( chartType ) ) {
				// 横棒線の場合はx軸の設定
				rtn.append( "xAxes" );
			}
			else {
				// それ以外はy軸の設定
				rtn.append( "yAxes" );
			}
			rtn.append( ":[{type:'" ).append( yscaleType ).append( '\'' );
			// y軸にｶﾃｺﾞﾘｰｽｹｰﾙを設定した場合
			if( isYcateType ) {
				rtn.append( ",position:'left'" );
			}
			if( !StringUtil.isNull( ylabel ) ) {						// 6.8.5.0 (2018/01/09)
				rtn.append( ",scaleLabel:{display:true" )
					.append( ",labelString:'" ).append( ylabel ).append( "'}" );
			}
			rtn.append( ",ticks:{beginAtZero:" ).append( ybeginAtZero );	// 6.8.5.0 (2018/01/09)
			setProp( rtn, ",max:"		, max );
			setProp( rtn, ",min:"		, min );
			setProp( rtn, ",stepSize:"	, stepSize );
			setProp( rtn, ",callback:"	, yscaleCallback );
			rtn.append( "}}]," );

			if( CTYPE_HBAR.equals( chartType ) ) {
				// 横棒線の場合はy軸の設定
				rtn.append( "yAxes" );
			}
			else {
				// それ以外はx軸の設定
				rtn.append( "xAxes" );
			}
			rtn.append( ":[{type:'" ).append( xscaleType ).append( '\'' );
			setProp( rtn, ",categoryPercentage:", barWidthPer  );
			// x軸にﾘﾆｱｽｹｰﾙを設定した場合
			if( isXlinerType ) {
				rtn.append( ",position:'bottom'" );
			}
			// ﾁｬｰﾄﾀｲﾌﾟが横棒線の場合
			if(  CTYPE_HBAR.equals( chartType ) ){
				rtn.append( ",position:'left'" );
			}

			if( !StringUtil.isNull( xlabel ) ) {						// 6.8.5.0 (2018/01/09)
				rtn.append(  ",scaleLabel:{display:true," )
					.append( "labelString:'" ).append( xlabel ).append( "'}" );
			}
			// 固定値がないので、先頭カンマが使えない。
			rtn.append( ",time:{" );
			setProp( rtn, "format:'", timeSetFormat, "'," );
			// timeLblFormatが指定されている場合、全てのdisplayFormatsにtimeLblFormatを設定する
			if( !StringUtil.isNull( timeLblFormat ) ) {						// 6.8.5.0 (2018/01/09)
				rtn.append(  "displayFormats:{year:'" ).append( timeLblFormat )
					.append( "',quarter:'"	).append( timeLblFormat )
					.append( "',month:'"	).append( timeLblFormat )
					.append( "',week:'"		).append( timeLblFormat )
					.append( "',day:'"		).append( timeLblFormat )
					.append( "',hour:'"		).append( "',minute:'"		).append( timeLblFormat )
											 .append( "',second:'"		).append( timeLblFormat )
											 .append( "',millisecond:''}," );
			}
			setProp( rtn, "max:"			, timeMax			, "," );
			setProp( rtn, "min:"			, timeMin			, "," );
			setProp( rtn, "unit:"			, timeUnit			, "," );
			setProp( rtn, "unitStepSize:"	, timeUnitStepSize	, "," );
			rtn.append( "}," );

			// 固定値がないので、先頭カンマが使えない。
			rtn.append( "ticks:{" );
			setProp( rtn, "callback:", xscaleCallback	, ","  );
			// x軸にﾘﾆｱｽｹｰﾙを設定した場合
			if( isXlinerType ) {
				setProp( rtn, "beginAtZero:"	,  String.valueOf( xbeginAtZero ) , "," );		// 6.8.5.0 (2018/01/09)
				setProp( rtn, "max:"			, xmax			, "," );
				setProp( rtn, "min:"			, xmin			, "," );
				setProp( rtn, "stepSize:"		, xstepSize		, "," );
			}
			rtn.append( "}}]}" );

			// 6.8.5.0 (2018/01/09) markValues,markColors,markLbls,markAdjust 属性対応
			final String[] mkVals = StringUtil.csv2Array( markValues );
			final int vCnt = mkVals.length;
			if( vCnt > 0 ) {
				final String[] mkCols = StringUtil.csv2Array( markColors	, ',' , vCnt , MARK_DEF_COLOR );
				final String[] mkLbls = StringUtil.csv2Array( markLbls		, ',' , vCnt );
				final String[] mkAjst = StringUtil.csv2Array( markAdjust	, ',' , vCnt , MARK_DEF_ADJUST );

				rtn.append( ",annotation:{annotations:[" );
				for( int i=0; i<vCnt; i++ ) {
					rtn.append( "{type:'line',scaleID:'y-axis-0',mode:'horizontal',borderWidth:2" );
					setProp( rtn, ",value:"			, mkVals[i] );
					setProp( rtn, ",borderColor:'"	, mkCols[i] , "'" );
					if( !mkLbls[i].isEmpty() ) {
						rtn.append( ",label:{enabled:'true',position:'left',backgroundColor:'rgba(0,0,0,0)',fontSize:10" );
						setProp( rtn, ",yAdjust:"	, mkAjst[i] );
						setProp( rtn, ",content:'"	, mkLbls[i] , "'" );
						setProp( rtn, ",fontColor:'", mkCols[i] , "'" );
						rtn.append( '}' );
					}
					rtn.append( "}," );
				}
				rtn.append( "]}" );
			}

			// 6.8.5.0 (2018/01/09) ズーム処理を使用するかどうか
			if( useZoom ) {
				rtn.append( ",pan:{enabled:true,mode:'xy'},zoom:{enabled:true,drag:false,mode:'xy'}" );
			}
		}
		setProp( rtn, ",", optionAttributes );

		rtn.append( "}});" );

		// ｲﾍﾞﾝﾄ設定用 5.9.19.0
		// 5.9.27.0 (2017/12/01) MODIFY ｲﾍﾞﾝﾄにkeyupを追加
		// widthEventColumn設定
		if( !StringUtil.isNull( widthEventColumn ) ) {						// 6.8.5.0 (2018/01/09)
			rtn.append( "$(document).delegate('#" ).append( widthEventColumn ).append( "','mouseup keyup',function(){" )
				.append( "var width=$(this).val();" )
				.append( "$('#" ).append( id ).append( "').attr('width',width);" )
				.append( myChart ).append( ".chart.width=width;" )
				.append( myChart ).append( ".update();" )
				.append( "});" )
				.append( "$(function(){" )
				.append( "var chartWidth=$('#" ).append( id ).append("').attr('width');" )
				.append( "$('#" ).append( widthEventColumn ).append( "').val(chartWidth);" )		// 初期値を設定
				.append( "});" );
		}
		// heightEventColumn設定
		if( !StringUtil.isNull( heightEventColumn ) ) {						// 6.8.5.0 (2018/01/09)
			rtn.append( "$(document).delegate('#" ).append( heightEventColumn ).append( "','mouseup keyup',function(){" )
				.append( "var height=$(this).val();" )
				.append( "$('#" ).append( id ).append( "').attr('height',height);" )
				.append( myChart ).append( ".chart.height=height;" )
				.append( myChart ).append( ".update();" )
				.append( "});")
				.append( "$(function(){")
				.append( "var chartHeight=$('#" ).append( id ).append("').attr('height');" )
				.append( "$('#" ).append( heightEventColumn ).append( "').val(chartHeight);" )	// 初期値を設定
				.append( "});" );
		}
		// minEventColumn設定
		if( !StringUtil.isNull( minEventColumn ) ) {						// 6.8.5.0 (2018/01/09)
			rtn.append( "$(document).delegate('#" ).append( minEventColumn ).append( "','mouseup keyup',function(){" )
				// 5.9.27.0 (2017/12/01) MODIFY IntからFloat型に変更
				.append( "var min=parseFloat($(this).val());")
				.append( myChart ).append( ".options.scales.yAxes[0].ticks.min = min;" )
				.append( myChart ).append( ".update();")
				.append( "});" )
				.append( "$(function(){" )
				.append( "var chartMax=" ).append( myChart ).append( ".scales['y-axis-0'].max;" )
				.append( "var chartMin=" ).append( myChart ).append( ".scales['y-axis-0'].min;" )
				.append( "$('#" ).append( minEventColumn ).append( "').val(chartMin);" )					// 初期値を設定
				.append( "$('#" ).append( minEventColumn ).append( "').attr({'max':chartMax});" )			// 初期値を設定
				.append( "$('#" ).append( minEventColumn ).append( "').attr({'min':chartMin});" )			// 初期値を設定
				.append( "});" );
		}
		// maxEventColumn設定
		if( !StringUtil.isNull( maxEventColumn ) ) {						// 6.8.5.0 (2018/01/09)
			rtn.append( "$(document).delegate('#").append( maxEventColumn ).append( "','mouseup keyup',function(){" )
				// 5.9.27.0 (2017/12/01) MODIFY IntからFloat型に変更
				.append( "var max=parseFloat($(this).val());")
				.append( myChart ).append( ".options.scales.yAxes[0].ticks.max = max;")
				.append( myChart ).append( ".update();")
				.append( "});")
				.append( "$(function(){" )
				.append( "var chartMax=" ).append( myChart ).append( ".scales['y-axis-0'].max;" )
				.append( "var chartMin=" ).append( myChart ).append( ".scales['y-axis-0'].min;" )
				.append( "$('#" ).append( maxEventColumn ).append( "').val(chartMax);" )					// 初期値を設定
				.append( "$('#" ).append( maxEventColumn ).append( "').attr({'max':chartMax});" )			// 初期値を設定
				.append( "$('#" ).append( maxEventColumn ).append( "').attr({'min':chartMin});" )			// 初期値を設定
				.append( "});" );
		}

		// 6.9.2.0 (2018/03/05) ズーム処理を使用する場合、ｸﾀﾞﾌﾞﾙｸﾘｯｸで元に戻すためのｲﾍﾞﾝﾄを発生させます。
		if( useZoom ) {
			rtn.append( "window.onload=function(){$('#").append( id ).append( "').dblclick(function(){window." )
				.append( myChart ).append( ".resetZoom();});}" );
		}

		rtn.append( "</script>" );

		return rtn.toString();
	}

	/**
	 * setに値が存在する場合、sbにstr + setの形で値を追加する。
	 * 
	 * @param sb	ベースとなるStringBuilder
	 * @param str	文字列１
	 * @param set	文字列２
	 */
	private void setProp( final StringBuilder sb, final String str, final String set ) {
		if( !StringUtil.isNull( set ) ) {						// 6.8.5.0 (2018/01/09)
			sb.append( str ).append( set );
		}
	}

	/**
	 * setに値が存在する場合、sbにstr + set + endの形で値を追加する。
	 * 
	 * @param sb	ベースとなるStringBuilder
	 * @param str	文字列１
	 * @param set	文字列２
	 * @param end	文字列３
	 */
	private void setProp( final StringBuilder sb, final String str, final String set, final String end ) {
		if( !StringUtil.isNull( set ) ) {						// 6.8.5.0 (2018/01/09)
			sb.append( str ).append( set ).append( end );
		}
	}

	/**
	 * ﾊﾟﾗﾒｰﾀﾁｪｯｸ用ﾒｿｯﾄﾞ。
	 * 
	 * @param trg		ターゲット
	 * @param set		使用可能なキーワードのSet
	 * @param trgStr	ターゲットの名称
	 */
	private void checkPara( final String trg, final Set<String> set, final String trgStr ) {
		if( !StringUtil.isNull( trg ) && !check( trg, set ) ) {						// 6.8.5.0 (2018/01/09)
			final StringBuilder errMsg = new StringBuilder( BUFFER_MIDDLE )
				.append( "指定の" ).append( trgStr ).append( "は指定できません。" )
				.append( CR )
				.append( trgStr ).append( "=[" ).append( trg ).append( "]" )
				.append( CR );
			for( final String lst : set ) {
				errMsg.append( " | " );
				errMsg.append( lst );
			}
			throw new HybsSystemException( errMsg.toString() );
		}
	}

	/**
	 * 【TAG】ﾁｬｰﾄの種類を指定します[line/bar/horizontalBar/radar/polarArea/pie/doughnut](必須)。
	 *
	 * @og.tag
	 * 
	 * @param cType ﾁｬｰﾄﾀｲﾌﾟ [line/bar/horizontalBar/radar/polarArea/pie/doughnut]
	 */
	public void setChartType( final String cType ) {
		chartType = getRequestParameter( cType );

		if( !StringUtil.isNull( chartType ) && !check( chartType, CTYPE_SET ) ) {
			final StringBuilder errMsg = new StringBuilder( BUFFER_MIDDLE )
				.append( "指定のチャートタイプは実行できません。"        ).append( CR )
				.append( "chartType=[" ).append( chartType ).append( "]" ).append( CR );
			for( final String lst : CTYPE_SET ) {
				errMsg.append( " | " ).append( lst );
			}
			throw new HybsSystemException( errMsg.toString() );
		}
	}

	/**
	 * 【TAG】canvasﾀｸﾞのidを指定します(初期値:hybscanvas)。
	 *
	 * @og.tag
	 * canvasﾀｸﾞのidに設定します。
	 * 
	 * @param id canvasﾀｸﾞのid
	 */
	@Override
	public void setId( final String id ) {
		this.id = nval( getRequestParameter( id ),this.id );

	}

	/**
	 * 【TAG】ﾁｬｰﾄの高さを指定します(初期値:400)。
	 *
	 * @og.tag
	 * canvasﾀｸﾞの高さに設定します。
	 * 
	 * @param hei 設定する高さ
	 */
	public void setHeight( final String hei ) {
		height = nval( getRequestParameter( hei ),height );

	}

	/**
	 * 【TAG】ﾁｬｰﾄの幅を指定します(初期値:400)。
	 *
	 * @og.tag
	 * canvasﾀｸﾞの横幅を設定します。
	 * 
	 * @param wid 設定する横幅
	 */
	public void setWidth( final String wid ) {
		width = nval( getRequestParameter( wid ),width );

	}

	/**
	 * 【TAG】ﾗﾍﾞﾙのｶﾗﾑ名を指定します(表示名称）(必須)。
	 *
	 * @og.tag
	 * 
	 * @param lblclm ﾗﾍﾞﾙｶﾗﾑ
	 */
	public void setLabelColumn( final String lblclm ) {
		labelColumn = nval( getRequestParameter( lblclm ),labelColumn );
	}

	/**
	 * 【TAG】ﾀｲﾄﾙを指定します。
	 *
	 * @og.tag
	 * 
	 * @param title ﾀｲﾄﾙ
	 */
	public void setTitle( final String title ) {
		this.title = getRequestParameter( title );
	}

	/**
	 * 【TAG】ﾀｲﾄﾙの表示位置[top/right/bottom/left]を指定します(初期値:top)。
	 *
	 * @og.tag
	 * 
	 * @param titlePosition ﾀｲﾄﾙの表示位置
	 */
	public void setTitlePosition( final String titlePosition ) {
		this.titlePosition = getRequestParameter( titlePosition );

		checkPara( this.titlePosition, SET_POSITION, "titlePosition" );
	}

	/**
	 * 【TAG】x軸のラベルを指定します。
	 *
	 * @og.tag
	 * 
	 * @param xlabel x軸のラベル
	 */
	public void setXlabel( final String xlabel ) {
		this.xlabel = getRequestParameter( xlabel );
	}

	/**
	 * 【TAG】y軸のラベルを指定します。
	 *
	 * @og.tag
	 * 
	 * @param ylabel y軸のラベル
	 */
	public void setYlabel( final String ylabel ) {
		this.ylabel = getRequestParameter( ylabel );
	}

	/**
	 * 【TAG】凡例の表示位置[top/right/bottom/left]を指定します(初期値:top)。
	 *
	 * @og.tag
	 * 
	 * @param legendPosition 凡例の表示位置
	 */
	public void setLegendPosition( final String legendPosition ) {
		this.legendPosition = getRequestParameter( legendPosition );

		checkPara( this.legendPosition, SET_POSITION, "legendPosition" );
	}

	/**
	 * 【TAG】凡例を表示するか[true/false]を指定します。
	 *
	 * @og.tag
	 * 
	 * @param legendDisplay 凡例を表示するか [true/false]
	 */
	public void setLegendDisplay( final String legendDisplay ) {
		this.legendDisplay = getRequestParameter( legendDisplay );

		checkPara( this.legendDisplay, SET_BOOLEAN, "legendDisplay" );
	}

	/**
	 * 【TAG】x軸ｺｰﾙﾊﾞｯｸを指定します。
	 *
	 * @og.tag
	 * x軸のメモリ編集用スケールバックを設定します。
	 * 
	 * @param xscaleCallback x軸ｺｰﾙﾊﾞｯｸ
	 */
	public void setXscaleCallback( final String xscaleCallback ) {
		this.xscaleCallback = getRequestParameter( xscaleCallback );
	}

	/**
	 * 【TAG】y軸ｺｰﾙﾊﾞｯｸを指定します。
	 *
	 * @og.tag
	 * y軸のメモリ編集用スケールバックを設定します。
	 * 
	 * @param yscaleCallback y軸ｺｰﾙﾊﾞｯｸ
	 */
	public void setYscaleCallback( final String yscaleCallback ) {
		this.yscaleCallback = getRequestParameter( yscaleCallback );
	}

	/**
	 * 【TAG】x軸のｽｹｰﾙﾀｲﾌﾟ[category/time/linear]を指定します(初期値:category)。
	 *
	 * @og.tag
	 * 
	 * @param xscaleType x軸のｽｹｰﾙﾀｲﾌﾟ
	 */
	public void setXscaleType( final String xscaleType ) {
		this.xscaleType = getRequestParameter( xscaleType );

		checkPara( this.xscaleType, SET_XSCALE, "xscaleType" );
	}

	/**
	 * 【TAG】x軸を０から書き始まるかどうか(初期値:true)。
	 *
	 * @og.tag
	 * 
	 * @og.rev 6.8.5.0 (2018/01/09) 新規追加
	 * 
	 * @param xZero x軸のゼロ開始
	 */
	public void setXbeginAtZero( final String xZero ) {
		xbeginAtZero = nval( getRequestParameter( xZero ) , xbeginAtZero ) ;
	}

	/**
	 * 【TAG】y軸を０から書き始まるかどうか(初期値:true)(円形の場合もこの値)。
	 *
	 * @og.tag
	 * 
	 * @og.rev 6.8.5.0 (2018/01/09) 新規追加
	 * 
	 * @param yZero x軸のゼロ開始
	 */
	public void setYbeginAtZero( final String yZero ) {
		ybeginAtZero = nval( getRequestParameter( yZero ) , ybeginAtZero ) ;
	}

	/**
	 * 【TAG】y軸のｽｹｰﾙﾀｲﾌﾟ[linear/category]を指定します(初期値:linear)。
	 *
	 * @og.tag
	 * 
	 * @param yscaleType y軸のｽｹｰﾙﾀｲﾌﾟ
	 */
	public void setYscaleType( final String yscaleType ) {
		this.yscaleType = getRequestParameter( yscaleType );

		checkPara( this.yscaleType, SET_YSCALE, "yscaleType" );
	}

	/**
	 * 【TAG】y軸のﾒﾓﾘﾘｽﾄをカンマ区切りで指定します(xscaleTypeがcategoryの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param ycategoryList y軸のﾒﾓﾘﾘｽﾄ
	 */
	public void setYcategoryList( final String ycategoryList ) {
		this.ycategoryList = getRequestParameter( ycategoryList );
	}

	/**
	 * 【TAG】x軸の最大値を指定します(xscaleTypeがlinearの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param xmax x軸の最大値
	 */
	public void setXmax( final String xmax ) {
		this.xmax = getRequestParameter( xmax );
	}

	/**
	 * 【TAG】x軸の最小値を指定します(xscaleTypeがlinearの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param xmin x軸の最小値
	 */
	public void setXmin( final String xmin ) {
		this.xmin = getRequestParameter( xmin );
	}

	/**
	 * 【TAG】x軸のメモリ幅を指定します(xscaleTypeがlinearの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param xstepSize x軸のメモリ幅
	 */
	public void setXstepSize( final String xstepSize ) {
		this.xstepSize = getRequestParameter( xstepSize );
	}

	/**
	 * 【TAG】棒線の横幅を指定します(初期値:0.8, typeがbar,horizontalBarの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param barWidthPer 棒線の横幅
	 */
	public void setBarWidthPer( final String barWidthPer ) {
		this.barWidthPer = getRequestParameter( barWidthPer );
	}

	/**
	 * jsChartData情報をﾘｽﾄに追加します。
	 * 
	 * @og.rev 6.7.5.0 (2017/03/10) ﾘｽﾄの初期化方法を変更します。
	 * 
	 * @param jsData jsChartData情報
	 */
	protected void addJsChartData( final JsChartData jsData ) {
		jsChartData.add( jsData );
	}

	/**
	 * 登録済みのjsChartData情報の個数を返します。
	 * 
	 * @og.rev 6.7.7.0 (2017/03/31) 新規追加
	 * 
	 * @return 登録済みのjsChartData情報の個数
	 */
	protected int getJsChartDataSize() {
		return jsChartData.size();
	}

	/**
	 * 【TAG】x軸のﾀｲﾑの単位[year/quarter/month/week/day/hour/minute/second/millsecond]を指定します。
	 *
	 * @og.tag
	 * (xscaleTypeがtimeの場合に有効。指定しない場合は自動)
	 * 
	 * @param timeUnit x軸のﾀｲﾑの単位
	 */
	public void setTimeUnit( final String timeUnit ) {
		this.timeUnit = getRequestParameter( timeUnit );

		checkPara( this.timeUnit, SET_TIMEUNIT, "timeUnit" );
	}

	/**
	 * 【TAG】x軸のﾀｲﾑの単位幅を指定します(xscaleTypeがtimeの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param timeUnitStepSize x軸のﾀｲﾑの単位幅
	 */
	public void setTimeUnitStepSize( final String timeUnitStepSize ) {
		this.timeUnitStepSize = getRequestParameter( timeUnitStepSize );
	}

	/**
	 * 【TAG】x軸の設定するﾀｲﾑのﾌｫｰﾏｯﾄを指定します(xscaleTypeがtimeの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param timeSetFormat x軸の設定するﾀｲﾑのﾌｫｰﾏｯﾄ
	 */
	public void setTimeSetFormat( final String timeSetFormat ) {
		this.timeSetFormat = getRequestParameter( timeSetFormat );
	}

	/**
	 * 【TAG】x軸の表示するﾀｲﾑのﾌｫｰﾏｯﾄを指定します(xscaleTypeがtimeの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param timeLblFormat x軸の表示するﾀｲﾑのﾌｫｰﾏｯﾄ
	 */
	public void setTimeLblFormat( final String timeLblFormat ) {
		this.timeLblFormat = getRequestParameter( timeLblFormat );
	}

	/**
	 * 【TAG】x軸のﾀｲﾑの最大値を指定します(xscaleTypeがtimeの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param timeMax x軸のﾀｲﾑの最大値
	 */
	public void setTimeMax( final String timeMax ) {
		this.timeMax = getRequestParameter( timeMax );
	}

	/**
	 * 【TAG】x軸のﾀｲﾑの最小値を指定します(xscaleTypeがtimeの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param timeMin x軸のﾀｲﾑの最小値
	 */
	public void setTimeMin( final String timeMin ) {
		this.timeMin = getRequestParameter( timeMin );
	}

	/**
	 * 【TAG】y軸の最大値を指定します(xscaleTypeがlinearの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param max メモリの最大値
	 */
	public void setMax( final String max ) {
		this.max = nval( getRequestParameter( max ) , this.max );
	}

	/**
	 * 【TAG】y軸の最小値を指定します(xscaleTypeがlinearの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param min メモリの最小値
	 */
	public void setMin( final String min ) {
		this.min = nval( getRequestParameter( min ) , this.min );
	}

	/**
	 * 【TAG】y軸のメモリ幅を指定します(xscaleTypeがlinearの場合に有効)。
	 *
	 * @og.tag
	 * 
	 * @param stepSize y軸のメモリ幅
	 */
	public void setStepSize( final String stepSize ) {
		this.stepSize = nval( getRequestParameter( stepSize ) , this.stepSize );
	}

	/**
	 * 【TAG】ﾁｬｰﾄｸﾘｯｸ時のｲﾍﾞﾝﾄを指定します。
	 *
	 * @og.tag
	 * 下記の値が引数として渡されます。
	 * 
	 * event:ｲﾍﾞﾝﾄ情報 
	 * obj:ｸﾘｯｸされたｵﾌﾞｼﾞｪｸﾄの情報
	 * 
	 * @param click チャートクリック時のイベントを指定
	 */
	public void setOnClick( final String click ) {
		onClick = nval( getRequestParameter( click ),onClick );
	}

	/**
	 * 【TAG】点のスタイル属性を使用するかどうか[true/false]を指定します(初期値:false)。
	 *
	 * @og.tag
	 * 具体的なスタイルは、jsChartDataタグで、指定します。
	 * 複数データの場合、片方だけ指定したい場合は、usePointStyle="true" にしておき、
	 * jsChartDataタグ側で、指定したいほうだけ、pointStyle属性を設定してください。
	 * 
	 * @og.rev 6.8.5.0 (2018/01/09) 新規追加
	 * 
	 * @param usePstyle 点のスタイル属性を使用するかどうか [true:使用する/false:使用しない]
	 */
	public void setUsePointStyle( final String usePstyle ) {
		usePointStyle = nval( getRequestParameter( usePstyle ),usePointStyle );
	}

	/**
	 * 【TAG】(通常は使いません)sessionから所得する DBTableModelオブジェクトの ID。
	 *
	 * @og.tag
	 * 
	 * @param tableId テーブルID
	 */
	public void setTableId( final String tableId ) {
		this.tableId = getRequestParameter( tableId );
	}

	/**
	 * 【TAG】マーカーラインの設定値をCSV形式で複数指定します。
	 *
	 * @og.tag
	 * annotation オプションに値を設定します。
	 * X軸に平行に固定値の線を引きます。線の値を、CSV形式で指定します。
	 * type: 'line',scaleID: 'y-axis-0',mode: 'horizontal',borderWidth: 2 固定です。
	 * 
	 * @og.rev 6.8.5.0 (2018/01/09) 新規追加
	 * 
	 * @param mkVals マーカーラインの設定値(CSV形式)
	 */
	public void setMarkValues( final String mkVals ) {
		markValues = nval( getRequestParameter( mkVals ) , markValues );
	}

	/**
	 * 【TAG】マーカーラインの色をCSV形式で複数指定します。
	 *
	 * @og.tag
	 * annotation オプションに値を設定します。
	 * X軸に平行に固定値の線を引きます。線の色を、CSV形式で指定します。
	 * markValues が指定されており、markColorsが指定されていない場合は、青色(BLUE)になります。
	 * 
	 * @og.rev 6.8.5.0 (2018/01/09) 新規追加
	 * 
	 * @param mkCols マーカーラインの色(CSV形式)
	 */
	public void setMarkColors( final String mkCols ) {
		markColors = nval( getRequestParameter( mkCols ) , markColors );
	}

	/**
	 * 【TAG】マーカーラインのラベルをCSV形式で複数指定します。
	 *
	 * @og.tag
	 * annotations の label 属性 の content 属性に値をセットします。
	 * label 属性は、enabled: 'true',position: 'left',backgroundColor: 'rgba(0,0,0,0)',
	 * fontSize: 10, は固定で、fontColor は、markColors 属性で指定した
	 * マーカーラインの色を使用します。
	 * 
	 * @og.rev 6.8.5.0 (2018/01/09) 新規追加
	 * 
	 * @param mklbls マーカーラインのラベル(CSV形式)
	 */
	public void setMarkLbls( final String mklbls ) {
		markLbls = nval( getRequestParameter( mklbls ) , markLbls );
	}

	/**
	 * 【TAG】マーカーラインのラベル表示位置の上下方向を調整します(初期値:-6)。
	 *
	 * @og.tag
	 * annotation オプションに値を設定します。
	 * annotations の label 属性の yAdjust に値をセットします。
	 * これは、ラインに対するラベルの位置を表します。＋で、下側、－で上側に表示します。
	 * 初期値は、－６ で、ラインの上側に来るように調整しています。
	 * 
	 * @og.rev 6.8.5.0 (2018/01/09) 新規追加
	 * 
	 * @param mkAjst マーカーラインのラベル表示位置の上下方向調整
	 */
	public void setMarkAdjust( final String mkAjst ) {
		markAdjust = nval( getRequestParameter( mkAjst ) , markAdjust );
	}

	/**
	 * 【TAG】ズーム処理を使用するかどうか[true/false]を指定します。
	 *
	 * @og.tag
	 * annotation オプションにpan と zoom を設定します。
	 * これは、chartjs-plugin-zoom.js を使用します。
	 * 初期値は、false:使用しないです。
	 * 
	 * <ul>
	 *   <li>ﾎｲｰﾙでxy軸の拡大、縮小			</li>
	 *   <li>canvasをクリックでzoomリセット	</li>
	 *   <li>ｸﾘｯｸした状態で移動で、ﾊﾟﾝ動作	</li>
	 *   <li>数値(日付)ｽｹｰﾙの方向のみ可能	</li>
	 * </ul>
	 * 
	 * @og.rev 6.8.5.0 (2018/01/09) 新規追加
	 * 
	 * @param zoom ズーム処理を使用するかどうか [true:使用する/false:使用しない] (初期値:false)。
	 */
	public void setUseZoom( final String zoom ) {
		useZoom = nval( getRequestParameter( zoom ) , useZoom );
	}

	/**
	 * 【TAG】横幅の動的設定カラムを設定します。
	 *
	 * @og.tag
	 * 
	 * @og.rev 5.9.19.0 (2017/04/07) 追加
	 * 
	 * @param widthEventColumn 横幅の動的設定カラム
	 */
	public void setWidthEventColumn( final String widthEventColumn ) {
		this.widthEventColumn = getRequestParameter( widthEventColumn );
	}

	/**
	 * 【TAG】縦幅の動的設定カラムを設定します。
	 *
	 * @og.tag
	 * 
	 * @og.rev 5.9.19.0 (2017/04/07) 追加
	 * 
	 * @param heightEventColumn 縦幅の動的設定カラム
	 */
	public void setHeightEventColumn( final String heightEventColumn ) {
		this.heightEventColumn = getRequestParameter( heightEventColumn );
	}

	/**
	 * 【TAG】minの動的設定カラムを設定します。
	 *
	 * @og.tag
	 * 
	 * @og.rev 5.9.19.0 (2017/04/07) 追加
	 * 
	 * @param minEventColumn minの動的設定カラム
	 */
	public void setMinEventColumn( final String minEventColumn ) {
		this.minEventColumn = getRequestParameter( minEventColumn );
	}

	/**
	 * 【TAG】maxの動的設定カラムを設定します。
	 *
	 * @og.tag
	 * 
	 * @og.rev 5.9.19.0 (2017/04/07) 追加
	 * 
	 * @param maxEventColumn maxの動的設定カラム
	 */
	public void setMaxEventColumn( final String maxEventColumn ) {
		this.maxEventColumn = getRequestParameter( maxEventColumn );
	}

	/**
	 * 【TAG】ﾃﾞｰﾀが０の場合、使用しない（除外する）かどうかを指定します[true:０ﾃﾞｰﾀを除外する](初期値:false)。
	 *
	 * @og.tag
	 * JSON データを作成して、JsChartに渡しますが、このフラグを true に設定すると
	 * 0 または、null（空文字列）のデータを出力しません。  6.8.3.0 (2017/11/27)
	 * グラフ系で、0 が、ありえない値として設定されている場合に、使用すると、
	 * 出力するデータ量を抑えることが出来ます。
	 * 
	 * @og.rev 6.7.7.0 (2017/03/31) useZeroDataOmit属性の追加
	 * 
	 * @param useZeroOmit ﾃﾞｰﾀが０の場合、使用しないかどうか
	 */
	public void setUseZeroDataOmit( final String useZeroOmit ) {
		this.useZeroDataOmit = nval( getRequestParameter( useZeroOmit ) , this.useZeroDataOmit );
	}

//	/**
//	 * 【TAG】ﾃﾞｰﾀを、間引いて表示します。(初期値:0:間引かない)。
//	 *
//	 * @og.tag
//	 * データ量が非常に多いと、JavaScriptの表示が遅くなります。
//	 * そこで、指定のﾃﾞｰﾀ量を間引きます。
//	 * 単純に間引くと、重要なデータが消失する可能性があるため、間引いている間の
//	 * ﾃﾞｰﾀは、最大値と最小値の２つの配列に設定し、そのﾃﾞｰﾀを表示します。
//	 * yscaleType が  category か、xscaleType が linear の場合は、間引き処理は行いません。
//	 * マイナスを指定すると、自動設定になります。
//	 * 自動設定は、{@og.value #AUTO_SKIP_MIN_COUNT} 以上の行数の場合、
//	 * {@og.value #AUTO_SKIP_SIZE} になるように、間引き件数を決めます。
//	 * 初期値は、0:間引かないです。
//	 * 
//	 * @og.rev 6.9.2.0 (2018/03/05) skipDataNum 属性の追加
//	 * 
//	 * @param skipDataNum ﾃﾞｰﾀを、間引く数
//	 * @see		#AUTO_SKIP_MIN_COUNT
//	 * @see		#AUTO_SKIP_SIZE
//	 */
//	public void setSkipDataNum( final String skipDataNum ) {
//		this.skipDataNum = nval( getRequestParameter( skipDataNum ) , this.skipDataNum );
//	}

	/**
	 * 【TAG】JSON出力で、値出力にレンデラを利用するかどうかを指定します。
	 *
	 * @og.tag
	 * JSONのデータのレンデラー変換を行うかどうか。
	 * 数値部分にはレンデラー変換は行いません。ラベル文字に行います。
	 * 指定しない場合は使用しない(false)です。
	 * 
	 * @og.rev 6.7.9.0 (2017/04/28) useRenderer 追加
	 *
	 * @param	usernd レンデラーを利用するかどうか
	 */
	public void setUseRenderer( final String usernd ) {
		this.useRenderer = nval( getRequestParameter( usernd ) , this.useRenderer );
	}

	/**
	 * 【TAG】検索結果をこのカラムでソートし直します(初期値:null)。
	 *
	 * @og.tag
	 * query で検索した結果を、JsChartで利用する場合、チャート上のソート順と、
	 * リストや、別のチャートでの表示準が異なる場合に、このカラムで、ソートしなおします。
	 * 通常は、labelColumn と同じ値でソートすることで、X軸の順番に表示されます。
	 * 
	 * @og.rev 6.8.0.0 (2017/06/02) sortColumn 追加
	 *
	 * @param	sortClm このカラムでソートし直す
	 */
	public void setSortColumn( final String sortClm ) {
		sortColumn = nval( getRequestParameter( sortClm ) , sortColumn );
	}

	/**
	 * 【TAG】オプション情報を指定します。
	 *
	 * @og.tag
	 *  
	 * @param attri オプションの値
	 */
	public void setOptionAttributes( final String attri ) {
		optionAttributes = nval( getRequestParameter( attri ),optionAttributes );
	}

	/**
	 * このオブジェクトの文字列表現を返します。
	 * 基本的にデバッグ目的に使用します。
	 * 
	 * @og.rev 2017/03/28 widthEventColumn,heightEventColumn,minEventColumn,maxEventColumnを追加
	 * 
	 * @return このクラスの文字列表現
	 */
	@Override
	public String toString() {
		return ToString.title( this.getClass().getName() )
			.println( "VERSION"				, VERSION				)
			.println( "id"					, id					)
			.println( "tableId"				, tableId				)
			.println( "chartType"			, chartType				)
			.println( "width"				, width					)
			.println( "height"				, height				)
			.println( "max"					, max					)
			.println( "min"					, min					)
			.println( "stepSize"			, stepSize				)
			.println( "barWidthPer"			, barWidthPer			)
			.println( "timeUnit"			, timeUnit				)
			.println( "timeUnitStepSize"	, timeUnitStepSize		)
			.println( "timeLblFormat"		, timeLblFormat			)
			.println( "timeSetFormat"		, timeSetFormat			)
			.println( "timeMax"				, timeMax				)
			.println( "timeMin"				, timeMin				)
			.println( "title"				, title					)
			.println( "titlePosition"		, titlePosition			)
			.println( "xlabel"				, xlabel				)
			.println( "ylabel"				, ylabel				)
			.println( "legendPosition"		, legendPosition		)
			.println( "legendDisplay"		, legendDisplay			)
			.println( "yscaleCallback"		, yscaleCallback		)
			.println( "xscaleCallback"		, xscaleCallback		)
			.println( "xscaleType"			, xscaleType			)
			.println( "xmax"				, xmax					)
			.println( "xmin"				, xmin					)
			.println( "xstepSize"			, xstepSize				)
			.println( "yscaleType"			, yscaleType			)
			.println( "ycategoryList"		, ycategoryList			)
			.println( "widthEventColumn"	, widthEventColumn		)	// 2017/03/28 追加
			.println( "heightEventColumn"	, heightEventColumn		)	// 2017/03/28 追加
			.println( "minEventColumn"		, minEventColumn		)	// 2017/03/28 追加
			.println( "maxEventColumn"		, maxEventColumn		)	// 2017/03/28 追加
			.println( "optionAttributes"	, optionAttributes		)
			.fixForm().toString();
	}
}
