Search code examples
iosshinobi

Shinobi Charts: example of how to subclass SChartCrosshairTooltip or SChartCrosshairMultiValueTooltip


I'm using the Shinobi Controls charting package on iOS and I cannot fathom how to implement a crosshair tooltip showing multiple y values. In my case I have a candlestick chart showing standard financial OHLC data values using the SChartCandlestickSeries class. The documentation seems to imply that I need to subclass an SChartSeries in order to implement some SChartData protocol methods, but I can't believe it's that involved.

I'm still struggling through the documentation here, but if anyone has some example code it would be worth its weight in gold right now!

Note: I've tried simply assigning an instance of SChartCrosshairMultiValueTooltip to the chart's crosshair.tooltip property but that doesn't seem to do very much - I just see a normal tooltip displaying a single x and y value.


Solution

  • It sounds like you're very much along the right lines. You need a multi-valued series (supplied by the appropriate datasource method):

    - (SChartSeries *)sChart:(ShinobiChart *)chart seriesAtIndex:(int)index
    {
        SChartCandleStickSeries *series = [SChartCandlestickSeries new];
        series.crosshairEnabled = YES;
        return series;
    }
    

    And then the chart needs to have a tooltip set to an instance of the type you mentioned (SChartCrosshairMultiValueTooltip):

    ShinobiChart *chart = [[ShinobiChart alloc] initWithFrame:self.view.bounds
                                         withPrimaryXAxisType:SChartAxisTypeNumber
                                         withPrimaryYAxisType:SChartAxisTypeNumber];
    chart.datasource = self;
    [self.view addSubview:chart];
    chart.delegate = self;
    chart.crosshair.tooltip = [SChartCrosshairMultiValueTooltip new];
    

    For completeness, the following is the data point method of the datasource:

    - (id<SChartData>)sChart:(ShinobiChart *)chart
            dataPointAtIndex:(int)dataIndex
            forSeriesAtIndex:(int)seriesIndex
    {
        SChartMultiYDataPoint *d = [SChartMultiYDataPoint new];
        d.xValue = @(dataIndex);
        [d.yValues setValue:_data[dataIndex] forKey:SChartCandlestickKeyOpen];
        [d.yValues setValue:@([_data[dataIndex] doubleValue] * 1.3) forKey:SChartCandlestickKeyHigh];
        [d.yValues setValue:@([_data[dataIndex] doubleValue] * 0.8) forKey:SChartCandlestickKeyLow];
        [d.yValues setValue:@([_data[dataIndex] doubleValue] * 1.1) forKey:SChartCandlestickKeyClose];
        return d;
    }
    

    (Note that the values here are just samples)

    Sample Chart