Возможно ли реализовать Zoom-in и Zoom-Out с компонентом Chart-Plot Chart на iPhone? Если да, пожалуйста, предложите мне, как это сделать?
Спасибо заранее.
Возможно ли реализовать Zoom-in и Zoom-Out с компонентом Chart-Plot Chart на iPhone? Если да, пожалуйста, предложите мне, как это сделать?
Спасибо заранее.
Да, как я это делаю, настраивая PlotSpace так (возможно, не лучшее решение, но лучшее, что я мог бы придумать):
-(void)zoomOut
{
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
graphScaleX+=5;
graphScaleY+=5;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:plotSpace.xRange.location length:CPDecimalFromFloat(graphScaleX)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:plotSpace.yRange.location length:CPDecimalFromFloat(graphScaleY)];
}
-(void)zoomIn
{
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
graphScaleX-=5;
graphScaleY-=5;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:plotSpace.xRange.location length:CPDecimalFromFloat(graphScaleX)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:plotSpace.yRange.location length:CPDecimalFromFloat(graphScaleY)];
}
Вы можете назначить делегат plotSpace некоторому экземпляру класса, который соответствует протоколу CPTPlotSpaceDelegate (например, self) [plotSpace setDelegate:self];
.
настроить plotSpace, чтобы он взаимодействовал с пользователем [plotSpace setAllowsUserInteraction:YES];
И тогда в этом классе реализует этот метод -(BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint
. Верните YES, если вы хотите, чтобы corePlot автоматически изменял размер вашего графика. Или НЕТ и делать что-то вроде предыдущего ответа.
Примечание. Если вы хотите, чтобы ваш текущий класс контроллера (self) был делегатом, убедитесь, что ваш интерфейс выглядит как @interface CurrentController : UISomeController<...,CPTPlotSpaceDelegate>{}
. Теперь он соответствует протоколу CPTPlotSpaceDelegate.
Использование взаимодействия с пользователем по умолчанию было недостаточно для меня, потому что:
Мое решение состояло в том, чтобы сделать это самостоятельно
Я добавил 2 UIGestureRecognizer для панорамирования, масштабирования
UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panChart:)];
[pan setMinimumNumberOfTouches:1];
[pan setMaximumNumberOfTouches:1];
[self.view addGestureRecognizer:pan];
UIPinchGestureRecognizer* scale = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scaleChart:)];
[self.view addGestureRecognizer:scale];
Затем я реализовал код, чтобы делать то, что мне нужно
Панорамная диаграмма
- (void)panChart:(UIPinchGestureRecognizer *)gestureRecognizer {
CPTGraph *theGraph = [graphs objectAtIndex:0];
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)theGraph.defaultPlotSpace;
CGPoint point = [gestureRecognizer locationInView:self.view];
if([(UIPanGestureRecognizer*)gestureRecognizer state] == UIGestureRecognizerStateBegan) {
firstX = point.x;
firstY = point.y;
originX = chartBounds.origin.x;
originY = chartBounds.origin.y;
//NSLog(@"first (%f,%f)", firstX, firstY);
}
CGRect frame = theGraph.frame;
float xMove = ((firstX-point.x)/(frame.size.width/chartBounds.size.width));
float yMove = ((firstY-point.y)/(frame.size.height/chartBounds.size.height));
if(firstX-point.x == 0){
xMove = 0;
}
if(firstY-point.y == 0){
yMove = 0;
}
//NSLog(@"frame: (%f, %f)",frame.size.width, frame.size.height);
//NSLog(@"touch (%f,%f)",firstX-point.x,firstY-point.y);
//NSLog(@"move (%f,%f)",xMove,yMove);
chartBounds.origin.x = originX+xMove;
chartBounds.origin.y = originY-yMove;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(chartBounds.origin.x) length:CPTDecimalFromFloat(chartBounds.size.width)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(chartBounds.origin.y) length:CPTDecimalFromFloat(chartBounds.size.height)];
}
Масштабная диаграмма
- (void)scaleChart:(UIPinchGestureRecognizer *)gestureRecognizer {
if (kMaxDataPoints < kDataPointsHistory) {
if ([gestureRecognizer scale] < 1) {
if(kMaxDataPoints/10 < 1){
kMaxDataPoints += 1;
}else{
kMaxDataPoints += kMaxDataPoints/10;
}
}
}
if (kMaxDataPoints > 5) {
if ([gestureRecognizer scale] > 1){
if(kMaxDataPoints/10 < 1){
kMaxDataPoints -= 1;
}else{
kMaxDataPoints -= kMaxDataPoints/10;
}
}
}
if(kMaxDataPoints <= 5){
kMaxDataPoints = 5;
}
if(kMaxDataPoints > kDataPointsHistory){
kMaxDataPoints = kDataPointsHistory;
}
chartBounds.size.width = kMaxDataPoints;
CPTGraph *theGraph = [graphs objectAtIndex:0];
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)theGraph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(chartBounds.origin.x) length:CPTDecimalFromFloat(chartBounds.size.width)];
//Need to calculate if its horizontal or vertical pinch gesture (not doing that yet :) )
//plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(chartBounds.origin.y) length:CPTDecimalFromFloat(chartBounds.size.height)];
}
Чтобы масштабировать только по оси x, просто заставьте новую шкалу y быть старой в делегате:
-(BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint;