So I'm subclassing SChartCrosshairMultiValueTooltip to implement a custom multi-value (OHLC) tooltip. I can get the OHLC data from the chart OK. But I'm having difficulty understanding how to present the data in the way the Shinobi frameworks intend me to.
Specifically, I do not understand how to use the labels
property. I first assumed that it would be pre-populated with labels generated by the superclass calling keyValueDisplayPairsForDataPoint:onSeries:withXAxis:withYAxis:
, but that is not correct as the debugger reveals that the labels array is empty.
So I tried calling that method and manually adding UILabels to the labels
array in my overridden - (void)setDataPoint:(id<SChartData>)dataPoint fromSeries:(SChartSeries *)series fromChart:(ShinobiChart *)chart
method, but nothing is shown. So then I tried adding them as a subviews to self.view. That works, but because I've just added them myself they are not styled according to the tooltip, and anyway that just feels wrong since there's virtually no point subclassing if I have to do everything myself. I also have to ensure [self layoutContents]
is not called for this to work, which feels double-wrong.
The code that works as described above looks like this:-
- (void)setDataPoint:(id<SChartData>)dataPoint fromSeries:(SChartSeries *)series fromChart:(ShinobiChart *)chart
{
SChartMultiYDataPoint *dp = (SChartMultiYDataPoint *)dataPoint;
NSDictionary *dict = [self keyValueDisplayPairsForDataPoint:dp onSeries:series withXAxis:chart.xAxis withYAxis:chart.yAxis];
for (UILabel *label in self.labels)
{
[label removeFromSuperview];
}
[self.labels removeAllObjects];
CGFloat y = 0;
const CGFloat kHeight = 25.0f;
for (id key in [dict allKeys])
{
UILabel *keyLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, y, 80, kHeight)];
keyLabel.text = key;
UILabel *valueLabel = [[UILabel alloc] initWithFrame:CGRectMake(80, y, 80, kHeight)];
valueLabel.text = dict[key];
[self.labels addObject:keyLabel];
[self.labels addObject:valueLabel];
y += kHeight;
[self addSubview:keyLabel];
[self addSubview:valueLabel];
}
}
- (void)setPosition:(struct SChartPoint)pos onCanvas:(SChartCanvas *)canvas
{
// [self layoutContents]; // do NOT call this
self.frame = CGRectMake(0, 0, 160, 100);
}
Does anyone know a better way?