Skip to content

Instantly share code, notes, and snippets.

@ykst
Created January 28, 2015 14:13
Show Gist options
  • Save ykst/04abb7e4a4ae95fce81e to your computer and use it in GitHub Desktop.
Save ykst/04abb7e4a4ae95fce81e to your computer and use it in GitHub Desktop.
[iOS] 逆引きCorePlot

[iOS] 逆引きCorePlot

CorePlotを使う上でのTipsをまとめていきます。随時更新。

データソース

###データを更新する

- (void) reloadGraphData:(CPTGraph*)graph
{
    // データ取得の各種delegateが実行される。
    // graphに加えた表示上の変更はこれを実行しなくても即座に反映される。
    [graph reloadData];
}

描画領域

###グラフにパディングを入れる パディング無しで開始値0の場合、軸に沿ったラベルが見えなくなるので要注意。

- (void) setGraphPadding:(CPTGraph*)graph
{
    graph.plotAreaFrame.paddingLeft = 40.0;
    graph.plotAreaFrame.paddingTop = 20.0;
    graph.plotAreaFrame.paddingRight = 0.0;
    graph.plotAreaFrame.paddingBottom = 20.0;
}

###外枠を消す

- (void) eraseOutermostBorder:(CPTGraph*)graph
{
    graph.plotAreaFrame.borderLineStyle = nil;
}

###グラフ領域の背景を透過させる

- (void) transparentBackground:(CPTGraph*)graph
{
    CPTFill *transparentFill = [CPTFill fillWithColor:[CPTColor colorWithComponentRed:0.0f green:0.0f blue:0.0f alpha:0.0f]];
    graph.plotAreaFrame.fill = transparentFill;
    graph.fill = transparentFill;
}

##Scatterプロット ###折れ線の下にグラデーションを付ける

- (void) gradientScatterPlot:(CPTScatterPlot *)plot
{
    CPTColor *beginningColor = [CPTColor colorWithComponentRed:0 green:0.5 blue:1.0 alpha:1];
    CPTColor *endingColor = [CPTColor colorWithComponentRed:0 green:0.5 blue:1.0 alpha:0];

    CPTGradient *areaGradient = [CPTGradient
                                 gradientWithBeginningColor:beginningColor
                                 endingColor:endingColor];
    // 上から下へグラデーション
    areaGradient.angle = -90.0;

    CPTFill* areaGradientFill = [CPTFill fillWithGradient:areaGradient];
    plot.areaFill = areaGradientFill;
    plot.areaBaseValue = CPTDecimalFromString(@"0.0");
}

###折れ線の色や太さを変える

- (void) changeLineStyle:(CPTScatterPlot *)plot
{
    CPTMutableLineStyle *lineStyle = [plot.dataLineStyle mutableCopy];
    // 太さ
    lineStyle.lineWidth = 1;
    // 色
    lineStyle.lineColor = [CPTColor blueColor];

    plot.dataLineStyle = lineStyle;
}

###タップされたグラフ上のレコード位置を取得する CPTScatterPlotDelegateプロトコルが簡単。説明の行数を減らすために例ではA2DyamicDelegateを使用。ホストビューまでのuserInteractionEnabledがYESになっていないと動かない。

- (void) setInteractiveAction:(CPTScatterPlot *)plot
{
    // Scatter Plotの場合はタップ領域のマージンを設定しないと押せない
    plot.plotSymbolMarginForHitDetection = 100.0f;

    A2DynamicDelegate *dd = plot.dynamicDelegate;
    [dd implementMethod:@selector(scatterPlot:plotSymbolWasSelectedAtRecordIndex:)
              withBlock:^(CPTScatterPlot *plot, NSUInteger idx) {
        NSLog(@"%d selected!", idx);
    }];
    plot.delegate = dd;
}

###ドラッグされたグラフ上のレコード位置を取得する CPTPlotSpaceDelegateプロトコルが必要。この例でもA2DynamicDelegateを使っているが、プロトコル名が推測出来ないパターンなので<objc/runtime.h>のobjc_getProtocolを使って直接指定をしている。

- (void) setDragPointEvent:(CPTGraph *)graph
{
    CPTPlotSpace *plotSpace = graph.defaultPlotSpace;
    A2DynamicDelegate *dd = [plotSpace dynamicDelegateForProtocol:objc_getProtocol("CPTPlotSpaceDelegate")];

    [dd implementMethod:@selector(plotSpace:shouldHandlePointingDeviceDraggedEvent:atPoint:) withBlock:^(CPTPlotSpace *plotSpace, CPTNativeEvent *event, CGPoint point) {
        // パディング分を差し引いて調整する
        point.x -= graph.plotAreaFrame.paddingLeft;
        // タッチ位置をグラフ上の座標に変換する
        CGPoint pointInPlotArea = [graph convertPoint:point toLayer:graph.plotAreaFrame];
        NSDecimal newPoint[2];
        [graph.defaultPlotSpace plotPoint:newPoint forPlotAreaViewPoint:pointInPlotArea];
        NSDecimalRound(&newPoint[0], &newPoint[0], 0, NSRoundPlain);
        // レコード位置に変換する。最大/最小値をはみ出す事があるので、適宜カットオフが必要
        int idx = [[NSDecimalNumber decimalNumberWithDecimal:newPoint[0]] intValue];
        NSLog(@"Drag on %d", idx);
        return YES;
    }];

    plotSpace.delegate = dd;
}

###点線グラフにする

- (void) setPlotDashLine:(CPTScatterPlot *)plot
{
    CPTMutableLineStyle *lineStyle = [plot.dataLineStyle mutableCopy];
    lineStyle.dashPattern =  @[@5.0f, @5.0f]; // [実線のピクセル数, 実線間のピクセル数]
    plot.dataLineStyle = lineStyle;
}

###データ点に丸を付ける

- (void) setPlotSymbol:(CPTScatterPlot *)plot
{
    // 縁のラインスタイル
    CPTColor *fringeColor = [CPTColor redColor];
    CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
    lineStyle.lineColor = fringeColor;
    // 楕円のスタイル
    CPTColor *ellipseColor = [CPTColor orangeColor];
    CPTPlotSymbol *symbol = [CPTPlotSymbol ellipsePlotSymbol];
    symbol.fill = [CPTFill fillWithColor:ellipseColor];
    symbol.lineStyle = lineStyle;
    symbol.size = CGSizeMake(15.0f, 15.0f); // 楕円のサイズ

    plot.plotSymbol = symbol;
}

表示する最小値、最大値を制限する

- (void) limitRange:(CPTGraph*)graph
{
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
    // X軸
    [plotSpace setXRange: [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0) length:CPTDecimalFromFloat(100)]];
    // Y軸
    [plotSpace setYRange: [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0) length:CPTDecimalFromFloat(100)]];
}

###グリッドを表示する

- (void) setGrid:(CPTGraph*)graph
{
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
    CPTMutableLineStyle *gridStyle = [CPTMutableLineStyle lineStyle];
    CPTColor *gridColor = [CPTColor colorWithComponentRed:0 green:0 blue:0 alpha:0.1f];
    gridStyle.lineColor = gridColor;
    gridStyle.lineWidth = 1;
    // Y軸に設定
    axisSet.yAxis.majorGridLineStyle = gridStyle;
}

###小さい方の補助線を消す

- (void) eraseMinorTicks:(CPTGraph*)graph
{
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
    // X軸
    axisSet.xAxis.minorTicksPerInterval = 0;
    // Y軸
    axisSet.yAxis.minorTicksPerInterval = 0;
}

###原点周囲の補助線を消す 原点付近を綺麗な直角にした方が見栄えが良い場合に有効。

- (void) eraseOriginTicks:(CPTGraph*)graph
{
    NSArray *exclusionRanges = @[[CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(0)]];
    axisSet.xAxis.labelExclusionRanges = exclusionRanges;
    axisSet.xAxis.labelExclusionRanges = exclusionRanges;
}

##Pieチャート ###グラフの開始角度を変える

- (void) changeStartAngle:(CPTPieChart*)chart
{
    chart.startAngle = M_PI_2; // (index = 0)の開始角度。90°で0時の位置。
}

###データ表示順を変える

- (void) changeSliceDirection:(CPTPieChart*)chart
{
    chart.sliceDirection = CPTPieDirectionClockwise; // またはCPTPieDirectionCounterClockwise
}

###縁に陰影を付ける

- (void) gradientFringe:(CPTPieChart*)chart
{
    CPTGradient *overlayGradient = [[CPTGradient alloc] init];
    const double startPosition = 0.8f;  // 内側の距離
    const double endPosition = 1.0f; // 外側の距離

    overlayGradient.gradientType = CPTGradientTypeRadial;
    overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.0] atPosition:startPosition];
    overlayGradient = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.4] atPosition:endPosition];

    chart.overlayFill = [CPTFill fillWithGradient:overlayGradient];
}

##凡例 ###外枠線を消す

- (void) hideLegendBorder:(CPTLegend*)legend
{
    legend.borderLineStyle = nil;
}

###色見本を消す

- (void) hideLegendBorder:(CPTLegend*)legend
{
    legend.swatchSize = CGSizeMake(1,0); // (0,0)だと文字サイズの正方形で表示される
}

##ラベル ###任意の値でラベルを表示する

- (void) customLabelLocation:(CPTGraph*)graph
{
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
    axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyLocationsProvided;
    axisSet.yAxis.majorTickLocations = [NSSet setWithArray:@[@50, @100]]; // 任意の組み合わせ
}

###ラベルの表示文字列をフォーマットする

- (void) customLabelLocation:(CPTGraph*)graph
{
    // 任意のNSFormatterが使用可能
    NSNumberFormatter *nfm = [NSNumberFormatter new];
    [nfm setMaximumFractionDigits:0];
    axisSet.yAxis.labelFormatter = nfm;
}

###任意の文字列のラベルを表示する

- (void) arbitraryLabels:(CPTGraph*)graph
{
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;

    NSMutableArray *labels = [NSMutableArray arrayWithCapacity:3];
    int idx = 0;
    for (NSString *year in @[@"A",@"B",@"C"]) // ラベルの文字列
    {
        CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:year
                                                       textStyle:axisSet.xAxis.labelTextStyle];
        label.tickLocation = CPTDecimalFromInt(idx); // ラベルを追加するレコードの位置
        label.offset = 5.0f; // 軸からラベルまでの距離
        [labels addObject:label];
        ++idx;
    }
    // X軸に設定
    axisSet.xAxis.axisLabels = [NSSet setWithArray:labels];
    axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyNone; // これ重要
}
@atsumori
Copy link

atsumori commented Sep 9, 2015

thanks!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment