SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, iOS Chart, Android Chart and JavaScript Chart Components
Please note! These examples are new to SciChart iOS v4 release! SciChart’s OpenGL ES and Metal iOS and Metal macOS Chart library ships with hundred of Objective-C and Swift iOS&macOS Chart Examples which you can browse, play with and view the source-code. All of this is possible with the new and improved SciChart iOS Examples Suite and demo application for Mac, which ships as part of the SciChart SDK.
Generates a Grouped Stacked Column chart, grouped side by side in code. See Documentation on how to use this type here: The iOS Stacked Column Chart.
The SCIStackedColumnRenderableSeries API can be used to render columns stacked above each other, or side by side in either Swift or Objective C. Grouping is performed when you place multiple SCIStackedColumnRenderableSeries into a SCIVerticallyStackedMountainsCollection or for horizontal column groups, the SCIHorizontallyStackedColumnsCollection.
Data is provided by a DataSeries, e.g. the SCIXyDataSeries, SCIXyyDataSeries (uses Y1 only) or SCIOhlcDataSeries (renders close).
The Swift and Objective-C source code for the iOS and macOS Stacked Column Chart Grouped Side by Side example is included below (Scroll down!).
Did you know that we have the source code for all our example available for free on Github?
Clone the SciChart.iOS.Examples from Github.
Also the SciChart iOS and Scichart macOS Trials contain the full source for the examples (link below).
//******************************************************************************
// SCICHART® Copyright SciChart Ltd. 2011-2019. All rights reserved.
//
// Web: http://www.scichart.com
// Support: support@scichart.com
// Sales: sales@scichart.com
//
// StackedColumnSideBySideChartView.m is part of the SCICHART® Examples. Permission is hereby granted
// to modify, create derivative works, distribute and publish any part of this source
// code whether for commercial, private or personal use.
//
// The SCICHART® examples are distributed in the hope that they will be useful, but
// without any warranty. It is provided "AS IS" without warranty of any kind, either
// expressed or implied.
//******************************************************************************
#import "StackedColumnSideBySideChartView.h"
#import "SCDDataManager.h"
#import <SciChart/SCILabelProviderBase+Protected.h>
@interface YearsLabelProvider : SCILabelProviderBase
- (instancetype)init;
@end
@implementation YearsLabelProvider {
NSArray *_xLabels;
}
- (instancetype)init {
self = [super initWithAxisType:@protocol(ISCINumericAxis)];
if (self) {
_xLabels = [[NSMutableArray alloc] initWithObjects:@"2000", @"2010", @"2014", @"2050", nil];
}
return self;
}
- (id<ISCIString>)formatLabel:(id<ISCIComparable>)dataValue {
int i = (int)dataValue.toDouble;
NSString *result = @"";
if (i >= 0 && i < 4) {
result = _xLabels[i];
}
return result;
}
- (id<ISCIString>)formatCursorLabel:(id<ISCIComparable>)dataValue {
int i = (int)dataValue.toDouble;
NSString *result;
if (i >= 0 && i < 4) {
result = _xLabels[i];
} else if (i < 0) {
result = _xLabels[0];
} else {
result = _xLabels[3];
}
return result;
}
@end
@implementation StackedColumnSideBySideChartView
- (Class)associatedType { return SCIChartSurface.class; }
- (void)initExample {
id<ISCIAxis> xAxis = [SCINumericAxis new];
xAxis.autoTicks = NO;
xAxis.majorDelta = @(1.0);
xAxis.minorDelta = @(0.5);
xAxis.drawMajorBands = YES;
xAxis.labelProvider = [YearsLabelProvider new];
id<ISCIAxis> yAxis = [SCINumericAxis new];
yAxis.drawMajorBands = YES;
yAxis.axisTitle = @"billions of People";
yAxis.growBy = [[SCIDoubleRange alloc] initWithMin:0.0 max:0.1];
yAxis.autoRange = SCIAutoRange_Always;
double china[] = {1.269, 1.330, 1.356, 1.304};
double india[] = {1.004, 1.173, 1.236, 1.656};
double usa[] = {0.282, 0.310, 0.319, 0.439};
double indonesia[] = {0.214, 0.243, 0.254, 0.313};
double brazil[] = {0.176, 0.201, 0.203, 0.261};
double pakistan[] = {0.146, 0.184, 0.196, 0.276};
double nigeria[] = {0.123, 0.152, 0.177, 0.264};
double bangladesh[] = {0.130, 0.156, 0.166, 0.234};
double russia[] = {0.147, 0.139, 0.142, 0.109};
double japan[] = {0.126, 0.127, 0.127, 0.094};
double restOfTheWorld[] = {2.466, 2.829, 3.005, 4.306};
SCIXyDataSeries *chinaDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
chinaDataSeries.seriesName = @"China";
SCIXyDataSeries *indiaDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
indiaDataSeries.seriesName = @"India";
SCIXyDataSeries *usaDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
usaDataSeries.seriesName = @"USA";
SCIXyDataSeries *indonesiaDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
indonesiaDataSeries.seriesName = @"Indonesia";
SCIXyDataSeries *brazilDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
brazilDataSeries.seriesName = @"Brazil";
SCIXyDataSeries *pakistanDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
pakistanDataSeries.seriesName = @"Pakistan";
SCIXyDataSeries *nigeriaDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
nigeriaDataSeries.seriesName = @"Nigeria";
SCIXyDataSeries *bangladeshDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
bangladeshDataSeries.seriesName = @"Bangladesh";
SCIXyDataSeries *russiaDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
russiaDataSeries.seriesName = @"Russia";
SCIXyDataSeries *japanDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
japanDataSeries.seriesName = @"Japan";
SCIXyDataSeries *restOfTheWorldDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
restOfTheWorldDataSeries.seriesName = @"Rest Of The World";
SCIXyDataSeries *totalDataSeries = [[SCIXyDataSeries alloc] initWithXType:SCIDataType_Double yType:SCIDataType_Double];
totalDataSeries.seriesName = @"Total";
for (int i = 0; i < 4; i++) {
double xValue = i;
[chinaDataSeries appendX:@(xValue) y:@(china[i])];
if (i != 2) {
[indiaDataSeries appendX:@(xValue) y:@(india[i])];
[usaDataSeries appendX:@(xValue) y:@(usa[i])];
[indonesiaDataSeries appendX:@(xValue) y:@(indonesia[i])];
[brazilDataSeries appendX:@(xValue) y:@(brazil[i])];
} else {
[indiaDataSeries appendX:@(xValue) y:@(NAN)];
[usaDataSeries appendX:@(xValue) y:@(NAN)];
[indonesiaDataSeries appendX:@(xValue) y:@(NAN)];
[brazilDataSeries appendX:@(xValue) y:@(NAN)];
}
[pakistanDataSeries appendX:@(xValue) y:@(pakistan[i])];
[nigeriaDataSeries appendX:@(xValue) y:@(nigeria[i])];
[bangladeshDataSeries appendX:@(xValue) y:@(bangladesh[i])];
[russiaDataSeries appendX:@(xValue) y:@(russia[i])];
[japanDataSeries appendX:@(xValue) y:@(japan[i])];
[restOfTheWorldDataSeries appendX:@(xValue) y:@(restOfTheWorld[i])];
[totalDataSeries appendX:@(xValue) y:@(china[i] + india[i] + usa[i] + indonesia[i] + brazil[i] + pakistan[i] + nigeria[i] + bangladesh[i] + russia[i] + japan[i] + restOfTheWorld[i])];
}
SCIHorizontallyStackedColumnsCollection *columnCollection = [SCIHorizontallyStackedColumnsCollection new];
[columnCollection add:[self getRenderableSeriesWithDataSeries:chinaDataSeries fillColor:0xff3399ff strokeColor:0xff2D68BC]];
[columnCollection add:[self getRenderableSeriesWithDataSeries:indiaDataSeries fillColor:0xff014358 strokeColor:0xff013547]];
[columnCollection add:[self getRenderableSeriesWithDataSeries:usaDataSeries fillColor:0xff1f8a71 strokeColor:0xff1B5D46]];
[columnCollection add:[self getRenderableSeriesWithDataSeries:indonesiaDataSeries fillColor:0xffbdd63b strokeColor:0xff7E952B]];
[columnCollection add:[self getRenderableSeriesWithDataSeries:brazilDataSeries fillColor:0xffffe00b strokeColor:0xffAA8F0B]];
[columnCollection add:[self getRenderableSeriesWithDataSeries:pakistanDataSeries fillColor:0xfff27421 strokeColor:0xffA95419]];
[columnCollection add:[self getRenderableSeriesWithDataSeries:nigeriaDataSeries fillColor:0xffbb0000 strokeColor:0xff840000]];
[columnCollection add:[self getRenderableSeriesWithDataSeries:bangladeshDataSeries fillColor:0xff550033 strokeColor:0xff370018]];
[columnCollection add:[self getRenderableSeriesWithDataSeries:russiaDataSeries fillColor:0xff339933 strokeColor:0xff2D732D]];
[columnCollection add:[self getRenderableSeriesWithDataSeries:japanDataSeries fillColor:0xff00aba9 strokeColor:0xff006C6A]];
[columnCollection add:[self getRenderableSeriesWithDataSeries:restOfTheWorldDataSeries fillColor:0xff560068 strokeColor:0xff3D0049]];
SCILegendModifier *legendModifier = [SCILegendModifier new];
legendModifier.position = SCIAlignment_Top | SCIAlignment_Left;
legendModifier.margins = (SCIEdgeInsets){.left = 10, .top = 10, .right = 10, .bottom = 10};
[SCIUpdateSuspender usingWithSuspendable:self.surface withBlock:^{
[self.surface.xAxes add:xAxis];
[self.surface.yAxes add:yAxis];
[self.surface.renderableSeries add:columnCollection];
[self.surface.chartModifiers addAll:legendModifier, [SCITooltipModifier new], nil];
}];
}
- (SCIStackedColumnRenderableSeries *)getRenderableSeriesWithDataSeries:(SCIXyDataSeries *)dataSeries fillColor:(uint)fillColor strokeColor:(uint)strokeColor {
SCIStackedColumnRenderableSeries *rSeries = [SCIStackedColumnRenderableSeries new];
rSeries.dataSeries = dataSeries;
rSeries.fillBrushStyle = [[SCISolidBrushStyle alloc] initWithColorCode:fillColor];
rSeries.strokeStyle = [[SCISolidPenStyle alloc] initWithColorCode:strokeColor thickness:1];
[SCIAnimations waveSeries:rSeries duration:3.0 andEasingFunction:[SCICubicEase new]];
return rSeries;
}
@end
//******************************************************************************
// SCICHART® Copyright SciChart Ltd. 2011-2019. All rights reserved.
//
// Web: http://www.scichart.com
// Support: support@scichart.com
// Sales: sales@scichart.com
//
// StackedColumnSideBySideChartView.swift is part of the SCICHART® Examples. Permission is hereby granted
// to modify, create derivative works, distribute and publish any part of this source
// code whether for commercial, private or personal use.
//
// The SCICHART® examples are distributed in the hope that they will be useful, but
// without any warranty. It is provided "AS IS" without warranty of any kind, either
// expressed or implied.
//******************************************************************************
import SciChart.Protected.SCILabelProviderBase
class YearsLabelProvider: SCILabelProviderBase<SCINumericAxis> {
let _xLabels = ["2000", "2010", "2014", "2050"]
init() {
super.init(axisType: ISCINumericAxis.self)
}
override func formatLabel(_ dataValue: ISCIComparable) -> ISCIString {
let i = Int(dataValue.toDouble())
return NSString(string: i >= 0 && i < 4 ? _xLabels[i] : "")
}
override func formatCursorLabel(_ dataValue: ISCIComparable) -> ISCIString {
let i = Int(dataValue.toDouble())
var result: String
if (i >= 0 && i < 4) {
result = _xLabels[i]
} else if (i < 0) {
result = _xLabels[0]
} else {
result = _xLabels[3]
}
return NSString(string: result)
}
}
class StackedColumnSideBySideChartView: SCDSingleChartViewController<SCIChartSurface> {
override var associatedType: AnyClass { return SCIChartSurface.self }
override func initExample() {
let xAxis = SCINumericAxis()
xAxis.autoTicks = false
xAxis.majorDelta = NSNumber(value: 1.0)
xAxis.minorDelta = NSNumber(value: 0.5)
xAxis.drawMajorBands = true
xAxis.labelProvider = YearsLabelProvider()
let yAxis = SCINumericAxis()
yAxis.drawMajorBands = true
yAxis.axisTitle = "billions of People"
yAxis.growBy = SCIDoubleRange(min: 0, max: 0.1)
yAxis.autoRange = .always
let china = [1.269, 1.330, 1.356, 1.304]
let india = [1.004, 1.173, 1.236, 1.656]
let usa = [0.282, 0.310, 0.319, 0.439]
let indonesia = [0.214, 0.243, 0.254, 0.313]
let brazil = [0.176, 0.201, 0.203, 0.261]
let pakistan = [0.146, 0.184, 0.196, 0.276]
let nigeria = [0.123, 0.152, 0.177, 0.264]
let bangladesh = [0.130, 0.156, 0.166, 0.234]
let russia = [0.147, 0.139, 0.142, 0.109]
let japan = [0.126, 0.127, 0.127, 0.094]
let restOfTheWorld = [2.466, 2.829, 3.005, 4.306]
let chinaDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
chinaDataSeries.seriesName = "China"
let indiaDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
indiaDataSeries.seriesName = "India"
let usaDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
usaDataSeries.seriesName = "USA"
let indonesiaDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
indonesiaDataSeries.seriesName = "Indonesia"
let brazilDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
brazilDataSeries.seriesName = "Brazil"
let pakistanDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
pakistanDataSeries.seriesName = "Pakistan"
let nigeriaDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
nigeriaDataSeries.seriesName = "Nigeria"
let bangladeshDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
bangladeshDataSeries.seriesName = "Bangladesh"
let russiaDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
russiaDataSeries.seriesName = "Russia"
let japanDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
japanDataSeries.seriesName = "Japan"
let restOfTheWorldDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
restOfTheWorldDataSeries.seriesName = "Rest Of The World";
let totalDataSeries = SCIXyDataSeries(xType: .double, yType: .double)
totalDataSeries.seriesName = "Total"
for i in 0 ..< 4 {
chinaDataSeries.append(x: i, y: china[i])
if (i != 2) {
indiaDataSeries.append(x: i, y: india[i])
usaDataSeries.append(x: i, y: usa[i])
indonesiaDataSeries.append(x: i, y: indonesia[i])
brazilDataSeries.append(x: i, y: brazil[i])
} else {
indiaDataSeries.append(x: i, y: Double.nan)
usaDataSeries.append(x: i, y: Double.nan)
indonesiaDataSeries.append(x: i, y: Double.nan)
brazilDataSeries.append(x: i, y: Double.nan)
}
pakistanDataSeries.append(x: i, y: pakistan[i])
nigeriaDataSeries.append(x: i, y: nigeria[i])
bangladeshDataSeries.append(x: i, y: bangladesh[i])
russiaDataSeries.append(x: i, y: russia[i])
japanDataSeries.append(x: i, y: japan[i])
restOfTheWorldDataSeries.append(x: i, y: restOfTheWorld[i])
totalDataSeries.append(x: i, y: china[i] + india[i] + usa[i] + indonesia[i] + brazil[i] + pakistan[i] + nigeria[i] + bangladesh[i] + russia[i] + japan[i] + restOfTheWorld[i])
}
let columnCollection = SCIHorizontallyStackedColumnsCollection()
columnCollection.add(getRenderableSeriesWith(dataSeries: chinaDataSeries, fillColor:0xff3399ff, strokeColor:0xff2D68BC))
columnCollection.add(getRenderableSeriesWith(dataSeries: indiaDataSeries, fillColor:0xff014358, strokeColor:0xff013547))
columnCollection.add(getRenderableSeriesWith(dataSeries: usaDataSeries, fillColor:0xff1f8a71, strokeColor:0xff1B5D46))
columnCollection.add(getRenderableSeriesWith(dataSeries: indonesiaDataSeries, fillColor:0xffbdd63b, strokeColor:0xff7E952B))
columnCollection.add(getRenderableSeriesWith(dataSeries: brazilDataSeries, fillColor:0xffffe00b, strokeColor:0xffAA8F0B))
columnCollection.add(getRenderableSeriesWith(dataSeries: pakistanDataSeries, fillColor:0xfff27421, strokeColor:0xffA95419))
columnCollection.add(getRenderableSeriesWith(dataSeries: nigeriaDataSeries, fillColor:0xffbb0000, strokeColor:0xff840000))
columnCollection.add(getRenderableSeriesWith(dataSeries: bangladeshDataSeries, fillColor:0xff550033, strokeColor:0xff370018))
columnCollection.add(getRenderableSeriesWith(dataSeries: russiaDataSeries, fillColor:0xff339933, strokeColor:0xff2D732D))
columnCollection.add(getRenderableSeriesWith(dataSeries: japanDataSeries, fillColor:0xff00aba9, strokeColor:0xff006C6A))
columnCollection.add(getRenderableSeriesWith(dataSeries: restOfTheWorldDataSeries, fillColor:0xff560068, strokeColor:0xff3D0049))
let legendModifier = SCILegendModifier()
legendModifier.position = [.left, .top]
legendModifier.margins = SCIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
SCIUpdateSuspender.usingWith(surface) {
self.surface.xAxes.add(xAxis)
self.surface.yAxes.add(yAxis)
self.surface.renderableSeries.add(columnCollection)
self.surface.chartModifiers.add(legendModifier)
self.surface.chartModifiers.add(SCITooltipModifier())
}
}
fileprivate func getRenderableSeriesWith(dataSeries: SCIXyDataSeries, fillColor: uint, strokeColor: uint) -> SCIStackedColumnRenderableSeries {
let rSeries = SCIStackedColumnRenderableSeries()
rSeries.dataSeries = dataSeries
rSeries.fillBrushStyle = SCISolidBrushStyle(color: fillColor)
rSeries.strokeStyle = SCISolidPenStyle(color: strokeColor, thickness: 1)
SCIAnimations.wave(rSeries, duration: 3.0, andEasingFunction: SCICubicEase())
return rSeries
}
}