//-------------------------------------------------------------------
//
//  S7GraphView.m
//  S7Touch
//
//  Created by Aleks Nesterow on 9/27/09.
//  aleks.nesterow@gmail.com
//  
//  Thanks to http://snobit.habrahabr.ru/ for releasing sources for his
//  Cocoa component named GraphView.
//  
//  Copyright © 2009, 7touchGroup, Inc.
//  All rights reserved.
//  
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are met:
//  * Redistributions of source code must retain the above copyright
//  notice, this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above copyright
//  notice, this list of conditions and the following disclaimer in the
//  documentation and/or other materials provided with the distribution.
//  * Neither the name of the 7touchGroup, Inc. nor the
//  names of its contributors may be used to endorse or promote products
//  derived from this software without specific prior written permission.
//  
//  THIS SOFTWARE IS PROVIDED BY 7touchGroup, Inc. "AS IS" AND ANY
//  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//  DISCLAIMED. IN NO EVENT SHALL 7touchGroup, Inc. BE LIABLE FOR ANY
//  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
//  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
//  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//  
//-------------------------------------------------------------------
// iOS7対応 by AIG-Soft 2014/9/24

#import "S7GraphView.h"
#import "NSString+drawiOS7.h"

@interface S7GraphView (PrivateMethods)

- (void)initializeComponent;
- (void)drawGridSub:(CGContextRef)c sx:(CGFloat)sx sy:(CGFloat)sy ex:(CGFloat)ex ey:(CGFloat)ey;
- (void)drawAxisGrid:(CGRect)rect contentRef:(CGContextRef)c;

@end

//-------------------------------------------------------------------

@implementation S7GraphView

@synthesize dataSource = _dataSource, xValuesFormatter = _xValuesFormatter;
@synthesize drawAxisX = _drawAxisX, drawAxisY = _drawAxisY, drawGridX = _drawGridX, drawGridY = _drawGridY;
@synthesize xValuesColor = _xValuesColor, yValuesColor = _yValuesColor, gridXColor = _gridXColor, gridYColor = _gridYColor;
@synthesize drawInfo = _drawInfo, info = _info, infoColor = _infoColor;

@synthesize maxYValue,minYValue;
@synthesize ycount;
@synthesize colThreshold;
@synthesize fpeak;

//-------------------------------------------------------------------

UIColor *colorByIndex(NSInteger index)
// 番号から色を返す関数
{
	UIColor *color;
	
	switch (index) {
		case 0:
		//	color = RGB(  5, 141, 191); // 水色 0
			color = RGB(  5,   4, 250); // 青
			break;
		case 1:
			color = RGB( 80, 180,  50); // 深緑
			break;		
		case 2:
			color = RGB(255, 102,   0); // 朱色
			break;
		case 3:
			color = RGB(255, 158,   1); // オレンジ
			break;
		case 4:
			color = RGB(252, 210,   2);
			break;
		case 5:
			color = RGB(248, 255,   1);
			break;
		case 6:
			color = RGB(176, 222,   9);
			break;
		case 7:
			color = RGB(106, 249, 196); // 薄黄緑 7
			break;
		case 8:
			color = RGB(178, 222, 255); // 淡水色 8
			break;
		case 9:
			color = RGB(  4, 210,  21); // 緑 9
			break;
		default:
			color = RGB(204, 204, 204);
			break;
	}
	
	return color;
}

//-------------------------------------------------------------------

- (id)initWithFrame:(CGRect)frame
{
	// ここでグラフの描画範囲がself.frameに設定される
	// 以下の処理の座標系は、すべてこのframe内における相対座標になる(frameさえ変形／移動すればグラフもそれに従うということ)
    if (self = [super initWithFrame:frame]) {
		[self initializeComponent];
    }

    return self;
}

- (id)initWithCoder:(NSCoder *)decoder
{
	if (self = [super initWithCoder:decoder]) {
		[self initializeComponent];
	}
	
	return self;
}

//-------------------------------------------------------------------

-(void)setThreshold:(float)value1 value2:(float)value2 fValue1Hidden:(BOOL)fValue1Hidden fValue2Hidden:(BOOL)fValue2Hidden color:(UIColor *)col
// 閾値情報を内部へコピーする
{
	threshold1  =value1;	// (1)側
	threshold2  =value2;	// (2)側
	fthreshold1Hidden =fValue1Hidden;
	fthreshold2Hidden =fValue2Hidden;	// thresholdを表示/処理しないかどうか
	nslog(@"setThreshold:%f/%f/%d/%d/col=%@",value1,value2,fValue1Hidden,fValue2Hidden,col);
	self.colThreshold=col;	// propertyを使うのでselfが必要
}

//-------------------------------------------------------------------
// 座標計算式
#define withOffsetX(x)	(x+offsetX)
#define withOffsetY(y)	(self.frame.size.height - (y) - offsetY)
#define calcYpoint(f)	(((f)+zeroOffsetYValue) * stepY)
#define	calcXpoint(i)	((i)*stepX)

//-------------------------------------------------------------------

-(BOOL)calcAxisGrid:(float)minY_ maxYValue:(float)maxY_
// 軸計算
// ビューの大きさに合わせた軸を計算する
// minY_〜maxY_が値の範囲;yは負数も可能
// すべてのグラフで共通のこと
// xは要素数(.count)から取得される
// これは初期化時のみ呼び出すこと；途中で軸を変えると、しきい値も初期化される
{
	nslog(@"calcAxisGrid:%f〜%f",minY_,maxY_);

	minYValue=minY_;
	maxYValue=maxY_;
	
	// グラフの本数取得
	NSUInteger numberOfPlots = [self.dataSource graphViewNumberOfPlots:self];
	nslog(@"numberOfPlots=%d",(int)numberOfPlots);
	if (numberOfPlots==0) {
		return(NO); // 描画なし
	}
	
	if (maxYValue<=minYValue) { // 自動設定モード
		NSUInteger counts=0;
		for (NSUInteger plotIndex = 0; plotIndex < numberOfPlots; plotIndex++) {
			NSUInteger count=[self.dataSource graphView:self yValuesCount:plotIndex];
			// 配列内にデータがないときは処理しない
			nslog(@"count=%d",(int)count);
			if (count==0) continue;
			counts+=count;
			
			NSUInteger valueIndex = 0;
			float f = [self.dataSource graphView:self yValuesForPlot:plotIndex index:valueIndex];
			minYValue=maxYValue=f;
			for (; valueIndex < count; valueIndex++) {
				f = [self.dataSource graphView:self yValuesForPlot:plotIndex index:valueIndex];
				if (f > maxYValue) maxYValue = f; // 最大値
				if (minYValue < f) minYValue = f; // 最小値
			}
		}
		if (counts==0) return(NO); // データがないときは以降の処理をしない
	}
	nslog(@"補正前Y=%f〜%f",minYValue,maxYValue);
	
	// グラフを正の範囲に収めるための調整
	if ((zeroOffsetYValue=minYValue)<0.0) {
		zeroOffsetYValue=-minYValue;	// オフセット値
		minYValue=0.0;	// 0.0〜にする
		maxYValue+=zeroOffsetYValue;	// 最大値側も移動
	}
	
#if 0
	// グラフ範囲の調整
	if (maxYValue < 100) {
		maxYValue = ceil(maxYValue / 10) * 10; // ceil():切り上げ
	} 
	if (maxYValue > 100 && maxYValue < 1000) {
		maxYValue = ceil(maxYValue / 100) * 100;
	} 
	if (maxYValue > 1000 && maxYValue < 10000) {
		maxYValue = ceil(maxYValue / 1000) * 1000;
	}
	if (maxYValue > 10000 && maxYValue < 100000) {
		maxYValue = ceil(maxYValue / 10000) * 10000;
	}
#endif
	nslog(@"補正後Y=%f〜%f(zeroOffsetYValue=%f)",minYValue,maxYValue,zeroOffsetYValue);

#if 0
	offsetX = ( _drawAxisY ?              60.0f : 10.0f);
	offsetY = ((_drawAxisX || _drawInfo)? 60.0f : 40.0f);
#else
	// 軸を別Viewで描画するようにしたので、グラフ側は軸の描画にかかわらずオフセットは「軸あり」で固定にする
	offsetX = 55.0f;	// offsetXは、y軸値が表示できる幅を持つこと。グラフはoffsetXから描画される
						// これを変えたときは、単位の表示位置も変更したほうがいいかもしれない
	offsetXr= offsetX/2;
	offsetY = 25.0f;
	offsetYu= offsetY/2;
#endif
	// x軸
	NSMutableArray *xValues = [self.dataSource graphViewXValues:self];
	xValuesCount = xValues.count; // x軸個数記録
//	nslog(@"x軸数=%d",xValuesCount);
	
	if (xValuesCount > XCOUNT) {
		NSUInteger stepCount = XCOUNT;
		NSUInteger count = xValuesCount - 1;
		
		for (NSUInteger i = XCOUNT-1; i < (XCOUNT-1)*2; i++) {
			if (count % i == 0) {
				stepCount = i;
			}
		}
		xstep = xValuesCount / stepCount;
		maxStep = stepCount + 1;
	} else {
		xstep = 1;
		maxStep = xValuesCount;
	}
#if 0
	nslog(@"minYValue=%f"		,	minYValue);
	nslog(@"maxYValue=%f"		,	maxYValue);
	nslog(@"zeroOffsetYValue=%f",	zeroOffsetYValue);
	nslog(@"offsetX=%f"			,	offsetX);
	nslog(@"offsetY=%f"			,	offsetY);
	nslog(@"xstep=%d"			,	xstep);
	nslog(@"maxStep=%d"			,	maxStep);
#endif	
	// 描画あり
	return(YES);

}

-(void)calcGraphStep
// 軸の間隔計算
{
	printSelf();
	wx=(self.frame.size.width - (offsetX +offsetXr)); // グラフx実有効幅
	stepX = wx / (xValuesCount - 1); // ｘ軸描画間隔
#if 1
	nslog(@"width=%f"	,	self.frame.size.width);
	nslog(@"height=%f"	,	self.frame.size.height);
	nslog(@"offsetX=%f"	,	offsetX);
	nslog(@"wx=%f"		,	wx);
	nslog(@"stepX=%f"	,	stepX);
#endif	
	yValueStep = (maxYValue - minYValue) / ycount;
	stepY = (self.frame.size.height - (offsetY+offsetYu)) / (maxYValue-minYValue); // y軸描画間隔
#if 0
	nslog(@"yValueStep=%f"	,	yValueStep);
	nslog(@"stepY=%f"		,	stepY);
#endif
}

//-------------------------------------------------------------------

-(void)drawGridLine:(CGContextRef)c sx:(CGFloat)sx sy:(CGFloat)sy ex:(CGFloat)ex ey:(CGFloat)ey
{
	CGPoint startPoint = CGPointMake(sx, sy);
	CGPoint endPoint   = CGPointMake(ex, ey);
	CGContextMoveToPoint(   c, startPoint.x, startPoint.y);
	CGContextAddLineToPoint(c, endPoint.x  , endPoint.y  );
	CGContextClosePath(c); // 線描画
	CGContextStrokePath(c);
}

-(void)drawGridSub:(CGContextRef)c sx:(CGFloat)sx sy:(CGFloat)sy ex:(CGFloat)ex ey:(CGFloat)ey
// 軸描画サブルーチン
{
	CGFloat lineDash[2];
	lineDash[0] = 6.0f;
	lineDash[1] = 6.0f;
	
	CGContextSetLineDash( c, 0.0f, lineDash, sizeof(lineDash)/sizeof(CGFloat));
	CGContextSetLineWidth(c, 0.1f);
	CGContextSetStrokeColorWithColor(c, self.gridXColor.CGColor);
	
	[self drawGridLine:c sx:sx sy:sy ex:ex ey:ey];
}

-(void)drawThreshold1:(CGContextRef)c threshold:(float)threshold
// しきい値線の描画
{
	CGFloat y = (threshold+zeroOffsetYValue) * stepY;
	y= self.frame.size.height - y - offsetY;
	printSelf();
	nslog(@"%f→座標:%f(color=%@)",threshold,y,self.colThreshold);

	CGFloat lineDash[2];
	lineDash[0] = 2.0f;
	lineDash[1] = 2.0f;
	CGContextSetLineDash( c, 0.0f, lineDash, sizeof(lineDash)/sizeof(CGFloat));
	CGContextSetLineWidth(c, 0.3f); // 線の太さ
	CGContextSetStrokeColorWithColor(c, colThreshold.CGColor);
	
	[self drawGridLine:c
					sx:offsetX
					sy:y
					ex:self.frame.size.width - offsetXr
					ey:y
	 ];

}

- (void)drawAxisGrid:(CGRect)rect contentRef:(CGContextRef)c
// 軸描画
{
	printSelf();
	
	// まず全領域を消す
	CGContextSetFillColorWithColor(c, self.backgroundColor.CGColor);
	CGContextFillRect(c, rect);
	
	UIFont *font = [UIFont systemFontOfSize:11.0f];
	
	// 縦軸描画
	NSMutableArray *xValues = [self.dataSource graphViewXValues:self];

	[self calcGraphStep];
	
	for (NSUInteger i = 0; i < maxStep; i++) {
		CGFloat x = (i * xstep) * stepX;
		if (x > wx) x = wx;
		
		NSUInteger index = i * xstep;
		if (index >= xValuesCount) {
			index = xValuesCount - 1;
		}
		if (_drawGridX) {
			// 縦格子
			[self drawGridSub:c
						   sx:x + offsetX
						   sy:    offsetYu
						   ex:x + offsetX
						   ey:self.frame.size.height - offsetY
			 ];
		}
		
		if (_drawAxisX) {
			// x軸数値
			id value = xValues[index]; // x軸は数値でなくてもいいみたい
			NSString *str;
			if (_xValuesFormatter) {
				str = [_xValuesFormatter stringForObjectValue:value];
			} else {
				str = [NSString stringWithFormat:@"%@",value];
			}
			//nslog(@"x軸=%@",str);
//			[self.xValuesColor set];
			[str drawInRect7:CGRectMake(x-font.pointSize/2, self.frame.size.height -offsetY + 5.0f, 120.0f, 20.0f) // 軸を数値の中心にするx-font.pointSize/2は実は適当
				   withFont:font
				   withColor:self.xValuesColor
			  lineBreakMode:NSLineBreakByTruncatingTail
				  alignment:NSTextAlignmentCenter
			 ];
		}
	}
	
	// 横軸描画
	for (NSUInteger i = 0; i < ycount+1; i++) {
		CGFloat y = (i * yValueStep) * stepY;
		CGFloat yy= withOffsetY(y);
		if (_drawGridY) {
			// 横格子
			[self drawGridSub:c
						   sx:offsetX
						   sy:yy
						   ex:self.frame.size.width - offsetXr
						   ey:yy
			 ];
		}
		
		if (_drawAxisY) {
			// y軸数値
			NSString *str;
			if ([self.dataSource respondsToSelector:@selector(graphViewYFormatter: cnt:step:offset:)]) { // メソッドの実装があるときだけ
				str = [self.dataSource graphViewYFormatter:self cnt:i step:yValueStep offset:zeroOffsetYValue];
			} else {
				NSNumber *f = [NSNumber numberWithFloat:((float)i * yValueStep)-zeroOffsetYValue];
				str = [f stringValue];
			}
			//nslog(@"y軸=%@",str);
//			[self.yValuesColor set];
			[str drawInRect7:CGRectMake(0.0f, yy-font.lineHeight/2, 50.0f, 20.0f) // -font.lineHeight/2は軸を数値の中心にするため(こちらは正確)
				   withFont:font
				   withColor:self.yValuesColor
			  lineBreakMode:NSLineBreakByTruncatingTail
				  alignment:NSTextAlignmentRight
			 ];
			 // retainしているので
		}
	}
	
	// しきい値描画(最大2本)
	if (!fthreshold1Hidden) {
		[self drawThreshold1:c threshold:threshold1];
	}
	if (!fthreshold2Hidden) {
		[self drawThreshold1:c threshold:threshold2];
	}
}

//-------------------------------------------------------------------

-(void)drawPeak:(CGContextRef)c peak:(float)f
// peakの表示
// peakはグラフ側に表示する；グラフに重ならないように表示する（軸と重ねると軸が欠けてしまう）
{
	#define PEAK_TRI_WX	(offsetX/4)
	#define PEAK_TRI_WY	8
	CGFloat y = calcYpoint(f);
	CGPoint triangle[3];
	// >　この先が(offsetX,y)である三角形
	// (offsetX-PEAK_TRI_WX,y-PEAK_TRY_WY/2)〜(offsetX,y)〜(offsetX-PEAK_TRI_WX,y+PEAK_TRY_WY/2)〜最初でfill
	triangle[2].y=withOffsetY(y+PEAK_TRI_WY/2);
	triangle[2].x=
	triangle[0].x=withOffsetX(-PEAK_TRI_WX);
	triangle[0].y=withOffsetY(y-PEAK_TRI_WY/2);
	triangle[1].x=withOffsetX(0);
	triangle[1].y=withOffsetY(y);
	CGContextAddLines(c,triangle,3);
	CGContextFillPath(c); // 先に描画した領域を塗りつぶし指示;色は呼び出し前に設定しておくこと
}

//-------------------------------------------------------------------

-(CGPoint)setPoint:(NSUInteger)valueIndex y:(float)f
// 即値を与える時
{
//	printSelfs(@"%f",f);
	CGFloat y = calcYpoint(f);
	CGFloat x = calcXpoint(valueIndex);
	return CGPointMake(withOffsetX(x), withOffsetY(y));
}

-(CGPoint)setPoint:(NSUInteger)valueIndex plot:(NSUInteger)plot
// 要素番号を与えるとき
{
	float f=[self.dataSource graphView:self yValuesForPlot:plot index:valueIndex];
	CGFloat y = calcYpoint(f);
	CGFloat x = calcXpoint(valueIndex);
//	nslog(@"setPoint:(%d→%f)",valueIndex,x);
	return CGPointMake(withOffsetX(x), withOffsetY(y));
}

- (void)drawRect:(CGRect)rect
// 実グラフ描画
{
	printSelf();

	// UIGraphicsGetCurrentContext()はdrawRect:中でのみ値を返す
	CGContextRef c = UIGraphicsGetCurrentContext();
	nslog(@"UIGraphicsGetCurrentContext=%@",c);

	if (_drawGridY || _drawGridX || _drawAxisY || _drawAxisX) {
		nslog(@"軸描画");
		[self drawAxisGrid:rect contentRef:c];
		return;
	}
	
	// グラフの本数取得
	NSUInteger numberOfPlots = [self.dataSource graphViewNumberOfPlots:self];
	nslog(@"グラフ描画開始:本数=%d",(int)numberOfPlots);

	// グラフの描画
	CGContextSetLineDash(c, 0, NULL, 0);
	for (NSUInteger plotIndex = 0; plotIndex < numberOfPlots; plotIndex++) { // データ別
		if ([self.dataSource graphViewOnOff:self gno:plotIndex]==NO) continue; // 一時的にグラフ描画がOFFにされている

		NSUInteger count = [self.dataSource graphView:self yValuesCount:plotIndex];
		if (count==0) continue; // データがないグラフは描かない
		//nslog(@"データ個数=%d",count);
		
		[self calcGraphStep];
		
		// 描画色
		UIColor *col=colorByIndex(plotIndex);
		CGColorRef plotColor = col.CGColor;
		CGContextSetLineWidth(c, 1.5f); // 線の太さ

		BOOL shouldFill = NO;
		if ([self.dataSource respondsToSelector:@selector(graphView:shouldFillPlot:)]) {
			shouldFill = [self.dataSource graphView:self shouldFillPlot:plotIndex];
		}
		if (shouldFill) { // 下からグラフまでの塗りつぶしあり
			NSUInteger valueIndex = 0;
			CGPoint startPoint=[self setPoint:valueIndex plot:plotIndex];
			for (; valueIndex < count - 1; valueIndex++) {
				CGPoint endPoint  =[self setPoint:valueIndex+1 plot:plotIndex];
				CGPoint box[4];
				box[1].x=box[0].x=startPoint.x;
				box[3].y=box[0].y=withOffsetY(0);
				box[1].y=startPoint.y;
				box[3].x=box[2].x=endPoint.x;
				box[2].y=endPoint.y;
				CGContextSetFillColorWithColor(c, plotColor); // 塗りつぶし色
				CGContextAddLines(c,box,sizeof(box)/sizeof(CGPoint));
				CGContextFillPath(c); // 先に描画した領域を塗りつぶし指示
				startPoint=endPoint;
			}
		} else {
			// 塗りつぶし無しの時は高速描画
			CGPoint *lines;
			lines=(CGPoint *)malloc(sizeof(CGPoint)*count);
			for (NSUInteger valueIndex = 0; valueIndex < count ; valueIndex++) {
				lines[valueIndex]  =[self setPoint:valueIndex plot:plotIndex];
			}
			CGContextSetStrokeColorWithColor(c, plotColor); // 線色指定
			CGContextAddLines(c,lines,count);
			CGContextStrokePath(c); // 線画指定
			free(lines);
		}
		if (fpeak) {
			// peakの表示
			CGContextSetFillColorWithColor(c, plotColor); // 塗りつぶし色
			[self drawPeak:c peak:[self.dataSource graphViewPeakMax:self gno:plotIndex]];
			[self drawPeak:c peak:[self.dataSource graphViewPeakMin:self gno:plotIndex]];
		}

	}
	if (_drawInfo) {
//		[self.infoColor set];
		[_info drawInRect7:CGRectMake(0.0f, 5.0f, self.frame.size.width, 20.0f)
				 withFont:[UIFont boldSystemFontOfSize:13.0f]
				 withColor:self.infoColor
			lineBreakMode:NSLineBreakByTruncatingTail
				alignment:NSTextAlignmentCenter
		 ];
	}
	
	// 描画終了時処理
	[self.dataSource graphViewEndOfPlots:self];

}

//-------------------------------------------------------------------

-(CGPoint)checkPoint:(CGPoint)point frame:(CGRect)frame
// 画面上座標からグラフ上座標に変換する
{
	// グラフビュー内の相対位置に変換
	nslog(@"絶対位置=(%f,%f)",point.x,point.y);
	point.x-=frame.origin.x;
	point.y-=frame.origin.y;
	nslog(@"ビュー内位置=(%f,%f)",point.x,point.y);
	nslog(@"width=%f/offsetXr=%f/offsetX=%f",frame.size.width,offsetXr,offsetX);
	if (point.x>frame.size.width-offsetXr || point.x<offsetX) {
		// xがグラフ範囲を越えるとき
	OVER_GRAPH:;
		nslog(@"グラフ範囲を越えるとき");
		point.x=point.y=-1.0;
		return(point);
	}
	// yが超えるときは範囲ギリギリにする
	nslog(@"height=%f/offsetYu=%f/offsetY=%f",frame.size.height,offsetYu,offsetY);
	if (point.y<0||point.y>frame.size.height) goto OVER_GRAPH; // ビューを超えるときは範囲外にする
	// ビュー内でグラフ圏外は最小/最大値に設定する
	if (point.y>frame.size.height-offsetY) {
		point.y=frame.size.height-offsetY;
	}
	if (point.y<offsetYu) {
		point.y=offsetYu;
	}
	return(point);
}

-(float)calcPoint2Yvalue:(CGPoint)point frame:(CGRect)frame
// グラフ内y座標からy数値にする
// 基本的にタッチ座標から得るので、厳密な値ではない
{
	CGFloat y=(frame.size.height-offsetY)-point.y;
	nslog(@"座標:point.y=%f→%f→%f:値",point.y,frame.size.height-point.y,y);
	// リターン値は即値
	return ((y/stepY)-zeroOffsetYValue);
#if 0	// 描画演算式:setPoint
	CGFloat y = (f+zeroOffsetYValue) * stepY;
	return CGPointMake(x + offsetX, self.frame.size.height - y - offsetY);
#endif
}

-(BOOL)checkThresholdArea:(float)threshold value:(float)f
// 値fがしきい値thresholdから一定範囲内にあるかどうか
// yValueStepを使うため、ここにある
{
	float vf=yValueStep/2;
	printf("値=%f:%f〜%f(step=%f)：範囲",f,threshold-vf,threshold+vf,yValueStep);
	if (f>=threshold-vf && f<=threshold+vf) {
		// 操作範囲内
		printf("内\n");
		return(YES);
	}
	// 範囲外
	printf("外\n");
	return (NO);
}

//-------------------------------------------------------------------

#pragma mark PrivateMethods

- (void)initializeComponent
{
	_drawAxisX = YES;
	_drawAxisY = YES;
	_drawGridX = YES;
	_drawGridY = YES;
	
	_xValuesColor = [UIColor blackColor];
	_yValuesColor = [UIColor blackColor];
	
	_gridXColor	  = [UIColor blackColor];
	_gridYColor   = [UIColor blackColor];
	
	_infoColor	  = [UIColor blackColor];
	_drawInfo	  = NO;
	
	// デフォルト動作は自動設定
	minYValue= 0.0;
	maxYValue=-1.0;
	
	// しきい値は表示しない
	fthreshold1Hidden=
	fthreshold2Hidden=YES;
}

//-------------------------------------------------------------------

@end
