I've got a test Shinobi Control chart working but wnat to put a hoop, "O", at each data point.
How do you do this?
You need to set the point color on the series style object appropriately. The series which have the ability to show point (SChartScatterSeries, SChartLineSeries, SChartBandSeries) all have a pointStyle property within their style object, which is an instance of SChartPointStyle. This has the following relevant properties:
innerColor
color
innerRadius
outerRadius
showPoints
Depending on the effect you want (and the series type you are using) you need to set these appropriately. For example, to show 'hoops' on an SChartScatterSeries, you could use the following for the data source method:
- (SChartSeries *)sChart:(ShinobiChart *)chart seriesAtIndex:(int)index
{
_series = [SChartColumnSeries new];
SChartScatterSeries *series = [SChartScatterSeries new];
series.style.pointStyle.innerColor = [UIColor whiteColor];
return series;
}
Note, if you're using SChartBandSeries or SChartLineSeries, these have showPoints set to NO by default, so you would need to set this to YES yourself.
Related
I am using the charts framework for iOS in Objective-C.
I am trying to plot data value labels (y values) on a chart which has 4 data sets. if there are 1, 2 or 3 data sets on my chart, the label values show up just fine. If I add a 4th data set, the label values do not show up at all.
I am using a NSMutableArray of UIColor objects for each dataset. I set the label color to [UIColor clearColor] when I don't want the label to show up and I set it to [UIColor whiteColor] when I do want it to show up, for each data point.
NSMutableArray *labelColors = [[NSMutableArray alloc] init];
for (NSDictionary *data in dataArray )
{
if (condition)
{
[labelColors addObject:UIColor.whiteColor];
}
else
{
[labelColors addObject:UIColor.clearColor];
}
}
dataSet.valueColors = labelColors;
Again, this technique works fine if I plot 1, 2, or 3 data sets on my X axis, but if I plot a 4th data set, it stops drawing labels completely. The way I have my chart set up, two data sets are on the left Y axis and two data sets are on the right Y axis.
Does anybody know why my labels are not showing?
I fixed this with one line in viewDidLoad where I first set up my chart.
_chartView.maxVisibleCount = 500;
I guess after adding the 4th data set I had more than the default value of maxVisibleCount (whatever that is) and when that happens no data labels are drawn regardless of other settings.
I figured this out when modifying my data set's drawValuesEnabled field and inside the auto complete text it said "this value is ignored when maxVisibleCount is reached".
I have a bar graph chart working and I can select bars by tapping them.
In -sChart:seriesAtIndex: of my ShinobiChart datasource I have implemented:
SChartColumnSeries *series = [[SChartColumnSeries alloc] init];
series.detectTapsOutsideBar = YES;
series.selectionMode = SChartSelectionPoint;
Which is working well. What I want to do now is to be able to select a specific bar based on the index of the data behind it. How do you do this? I have looked on the chart, the series but cannot find any method to select a column.
Also for extra points :) I need to ensure at least one column is always selected.
UPDATE:
I tried adding the following code:
for (int index = 0; index < self.chartView.series[0].dataSeries.dataPoints.count; index++)
{
SChartDataPoint *point = (SChartDataPoint *)self.chartView.series[0].dataSeries.dataPoints[index];
if (lapIndex == index)
{
point.selected = YES;
}
else
{
point.selected = NO;
}
}
Seemed to have no effect at all. I also tried re drawing the chart.
In the end I removed that code and called -reloadData and -redrawChart on the chart and then set selected in the datasource. This is working.
DISCLAIMER I am a developer at ShinobiControls.
We have recently changed our data point selection API which shall be coming up in our next release to make this a bit clearer.
Currently, you have to loop through your series' data points via the "dataSeries.dataPoints" array. Then cast the point you pulled off the array from type id to SChartDataPoint and set the selected property on that point.
Or if you want to select a data point when your chart initially draws, you can just set the selected property of the SChartDataPoint object you return in the SChartDatasource method "dataPointAtIndex:".
To make sure only one point is selected at a time you can set the "togglePointSelection" BOOL property to NO. Setting this property to YES means you can select more than one point at a time.
In the iOS Charts library, unlike the BarChartDataSet class, the PieChartDataSet does not contain any property highlightAlpha that can be used to set a different alpha to the selected slice on the pie chart.
Although such a property can be introduced and using CGContextSetAlpha() we can modify the transparency of the highlighted slice, I want to do it without making any change in the library code. How can it be done?
I checked the code, currently, it does not support this.
public override func drawHighlighted(context context: CGContext, indices: [ChartHighlight])
{
...
CGContextSetFillColorWithColor(context, set.colorAt(xIndex).CGColor)
...
}
This just read data set color and use it to highlight. I think you are welcome to file a PR for such feature. Or I will do it when I have time.
For you, changing the source code seems the only option right now. That's why I think it's good for you to contribute.
For now, I have solved the problem using the delegate method:
- (void)chartValueSelected:(ChartViewBase * __nonnull)chartView
entry:(ChartDataEntry * __nonnull)entry
dataSetIndex:(NSInteger)dataSetIndex
highlight:(ChartHighlight * __nonnull)highlight
{
PieChartView *pPieChartView = (PieChartView *)chartView;
PieChartDataSet *pDataSet = (PieChartDataSet *)[pPieChartView.data.dataSets objectAtIndex:dataSetIndex];
NSMutableArray *pColors = [[NSMutableArray alloc] initWithArray:pDataSet.colors
copyItems:YES];
for (int nIndex = 0; nIndex < pColors.count; nIndex++) {
UIColor *pColor = [pColors objectAtIndex:nIndex];
if (nIndex == entry.xIndex) {
pColor = [pColor colorWithAlphaComponent:1];
}
else {
pColor = [pColor colorWithAlphaComponent:0.3];
}
[pColors replaceObjectAtIndex:nIndex
withObject:pColor];
}
pDataSet.colors = pColors;
}
In my case, I load the slices with alpha component less than 1. On highlighting the slice, the alpha value is changed to 1.
The same effect can be achieved if the highlightAlpha property is introduced in PieChartDataSet class. In the drawHighlighted method, CGContextSetAlpha(context, highlightAlpha) needs to be called. The BarChartDataSet has highlight colors as well, which are absent in PieChartDataSet.
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.
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)
I am using coreplot 0.9 .I had tried setting linecolor property for CPTLineStyle by
But it is giving error that color or fontSize is readonly property. Please give me some solution for this.
static CPTTextStyle *labelTextStyle= nil ;
labelTextStyle = [[CPTTextStyle alloc]init];
labelTextStyle.color =[CPTColor whiteColor];
labelTextStyle.fontSize = 10.0f ;
Use a CPTMutableTextStyle. In Core Plot, text styles, line styles, shadows, and numeric data objects come in two variants—mutable and immutable. This follows the pattern common to many Cocoa objects like NSString and NSArray.