• Home
  • Nchart3D
  • NGrid
  • Customers
  • Live demo
  • Download
  • Purchase
  • Blog
  • Support
  • Login
Contact us Terms of service Privacy policy ©   Anjuta Software

NChart3D API Documentation

The complete documentation of NChart3D classes, constants and public API methods for all supported platforms.

NChart3D iOS API
NChart3D macOS API
NChart3D visionOS API
NChart3D Android API

NChart3D FAQ

Frequently asked questions about NChart3D, covering some special use-cases and customization issues.

Code samples are provided in every supported language.

How can I create pie / doughnut chart?

To create pie chart with for example 3 sectors you need to:

  • Create 3 objects of NChartPieSeries. Each one will represent a sector.
  • Create data source that returns array with one point for each series. Actually you can return more points for each sector and this will be displayed as concentric circles.

To create doughnut you just need to set hole ratio to whatever you want.
Here is the code snippet to create simple doughnut chart with 3 sectors:

@interface ViewController : UIViewController 

@property(nonatomic, retain) NSMutableArray *brushes;

@end

@implementation ViewController
{
    NChartView *m_view;
}

- (void)dealloc
{
    [m_view release];
    [super dealloc];
}

- (void)loadView
{
    // Create a chart view that will display the chart.
    m_view = [[NChartView alloc] initWithFrame:CGRectZero];
    
    // Paste your license key here.
    m_view.chart.licenseKey = @"";
    
    // Margin to ensure some free space for the iOS status bar.
    m_view.chart.polarSystem.margin = NChartMarginMake(10.0f, 10.0f, 10.0f, 20.0f);
    
    // Create brushes.
    self.brushes = [NSMutableArray array];
    [self.brushes addObject:[NChartSolidColorBrush solidColorBrushWithColor:[UIColor colorWithRed:0.38f green:0.8f blue:0.91f alpha:1.0f]]];
    [self.brushes addObject:[NChartSolidColorBrush solidColorBrushWithColor:[UIColor colorWithRed:0.8f green:0.86f blue:0.22f alpha:1.0f]]];
    [self.brushes addObject:[NChartSolidColorBrush solidColorBrushWithColor:[UIColor colorWithRed:0.9f green:0.29f blue:0.51f alpha:1.0f]]];
    
    for (int i = 0; i < 3; ++i)
    {
        // Create series that will be displayed on the chart.
        NChartPieSeries *series = [NChartPieSeries series];
        
        // Set data source for the series.
        series.dataSource = self;
        
        // Set tag of the series.
        series.tag = i;
        
        // Set brush that will fill that series with color.
        series.brush = [self.brushes objectAtIndex:i % self.brushes.count];
        
        // Add series to the chart.
        [m_view.chart addSeries:series];
    }

    // Set hole ratio.
    NChartPieSeriesSettings *settings = [NChartPieSeriesSettings seriesSettings];
    settings.holeRatio = 0.1f;
    [m_view.chart addSeriesSettings:settings];
    
    // Update data in the chart.
    [m_view.chart updateData];
    
    // Set chart view to the controller.
    self.view = m_view;
}

#pragma mark - NChartSeriesDataSource

- (NSArray *)seriesDataSourcePointsForSeries:(NChartSeries *)series
{
    // Create one point with some data for the series.
    NSMutableArray *result = [NSMutableArray array];
    [result addObject:[NChartPoint pointWithState:[NChartPointState pointStateWithCircle:0 value:(rand() % 30) + 1]
                                        forSeries:series]];
    return result;
}

- (NSString *)seriesDataSourceNameForSeries:(NChartSeries *)series
{
    // Get name of the series.
    return [NSString stringWithFormat:NSLocalizedString(@"Series %d", nil), series.tag + 1];
}

@end
class ViewController: UIViewController, NChartSeriesDataSource {

    // Create a chart view that will display the chart.
    var m_view: NChartView = NChartView()
    
    // Create brushes.
    let m_brushes: [NChartSolidColorBrush] = [
        NChartSolidColorBrush(color: UIColor(red: 0.38, green: 0.8, blue: 0.91, alpha: 1.0)),
        NChartSolidColorBrush(color: UIColor(red: 0.8, green: 0.86, blue: 0.22, alpha: 1.0)),
        NChartSolidColorBrush(color: UIColor(red: 0.9, green: 0.29, blue: 0.51, alpha: 1.0))
    ]
    
    override func loadView() {
        
        // Paste your license key here.
        m_view.chart.licenseKey = ""
        
        // Margin to ensure some free space for the iOS status bar.
        m_view.chart.polarSystem.margin = NChartMarginMake(10.0, 10.0, 10.0, 20.0)
        
        for i in 0..<3 {
            // Create series that will be displayed on the chart.
            let series = NChartPieSeries()
            
            // Set data source for the series.
            series.dataSource = self
            
            // Set tag of the series.
            series.tag = i
            
            // Set brush that will fill that series with color.
            series.brush = m_brushes[i]
            
            // Add series to the chart.
            m_view.chart.addSeries(series)
        }
        
        // Set hole ratio.
        let settings = NChartPieSeriesSettings()
        settings.holeRatio = 0.1
        m_view.chart.add(settings)
        
        // Update data in the chart.
        m_view.chart.updateData()
        
        // Set chart view to the controller.
        self.view = m_view
    }
    
    // MARK: NChartSeriesDataSource
    
    func seriesDataSourcePoints(for series: NChartSeries!) -> [Any]! {
        // Create points with some data for the series.
        return [NChartPoint(state: NChartPointState(circle: 0, value: Double((arc4random() % 30) + 1)),
                            for: series)]
    }
    
    func seriesDataSourceName(for series: NChartSeries!) -> String! {
        // Get name of the series.
        return "My series \(series.tag)"
    }
}
public class ChartingDemoActivity extends Activity implements NChartSeriesDataSource {
    NChartView mNChartView;
    Random random = new Random();
    NChartBrush[] brushes;

    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.main);
        mNChartView = (NChartView) findViewById(R.id.surface);
        loadView();
    }

    private void loadView() {
        // Paste your license key here.
        mNChartView.getChart().setLicenseKey("");

        // Margin
        mNChartView.getChart().getPolarSystem().setMargin(new NChartMargin(10.0f, 10.0f, 10.0f, 40.0f));

        // Create brushes.
        brushes = new NChartBrush[3];
        brushes[0] = new NChartSolidColorBrush(Color.argb(255, (int) (255 * 0.38), (int) (255 * 0.8), (int) (255 * 0.92)));
        brushes[1] = new NChartSolidColorBrush(Color.argb(255, (int) (255 * 0.8), (int) (255 * 0.86), (int) (255 * 0.22)));
        brushes[2] = new NChartSolidColorBrush(Color.argb(255, (int) (255 * 0.9), (int) (255 * 0.29), (int) (255 * 0.51)));

        for (int i = 0; i < 3; ++i) {
            // Create series that will be displayed on the chart.
            NChartPieSeries series = new NChartPieSeries();

            // Set data source for the series.
            series.setDataSource(this);

            // Set tag of the series.
            series.tag = i;

            // Set brush that will fill that series with color.
            series.setBrush(brushes[i % brushes.length]);

            // Add series to the chart.
            mNChartView.getChart().addSeries(series);
        }

        // Set hole ratio.
        NChartPieSeriesSettings settings = new NChartPieSeriesSettings();
        settings.setHoleRatio(0.1f);
        mNChartView.getChart().addSeriesSettings(settings);

        // Update data in the chart.
        mNChartView.getChart().updateData();
    }

    protected void onResume() {
        super.onResume();
        mNChartView.onResume();
    }

    protected void onPause() {
        super.onPause();
        mNChartView.onPause();
    }

    // NChartSeriesDataSource

    public NChartPoint[] points(NChartSeries series) {
        // Create one point with some data for the series.
        NChartPoint[] result = new NChartPoint[1];
        result[0] = new NChartPoint(NChartPointState.PointStateWithCircleValue(0, random.nextInt(30) + 1), series);
        return result;
    }

    public String name(NChartSeries series) {
        return String.format("Series #%d", series.tag + 1);
    }

    public Bitmap image(NChartSeries series) {
        return null;
    }
    
    public NChartPoint[] extraPoints(NChartSeries series) {
        return null;
    }
}
How do I set margin for pie chart?

Pie is a polar chart so you have to use polar coordinate system to set the margin:

m_view.chart.polarSystem.margin = NChartMarginMake(10.0f, 10.0f, 10.0f, 10.0f);
m_view.chart.polarSystem.margin = NChartMarginMake(10.0, 10.0, 10.0, 10.0)
m_view.getChart().getPolarSystem().setMargin(new NChartTypes.Margin(10, 10, 10, 10));
How to change color of grid lines in the chart?

To alter the appearance of grid lines, you can use properties of the class NChartAxisGrid. To access the grid lines, you can use getters of cartesianSystem like xAlongY and similar. For example, to change the color of grid lines that are perpendicular to X-axis and stroke along Y-axis, you can do the following:

m_view.chart.cartesianSystem.xAlongY.color = [UIColor redColor];
m_view.chart.cartesianSystem.xAlongY.color = UIColor.red
m_view.getChart().getCartesianSystem().getXAlongY().setColor(Color.RED);
How to change number format on the axes?

You can change the format by overriding the double-to-string conversion of the needed axis. This can be achieved by implementing the corresponding method of value axis data source valueAxisDataSourceDouble:toStringForValueAxis:.

For example, use the following code:

Do not forget to set the data source for the axis you want to customize, for example:

- (NSString *)valueAxisDataSourceDouble:(double)value toStringForValueAxis:(NChartValueAxis *)axis
{
    return [NSString stringWithFormat:@"value %f", value];
}
func valueAxisDataSourceDouble(_ value: Double, toStringFor axis: NChartValueAxis!) -> String! {
    return "value \(value)"
}
public String doubleToString(double value, NChartValueAxis axis) {
    return String.format("value %f", value);
}
How to enable discontinuous axis?

You can use NChartValueAxisMark to display ticks with irregular step. For example, if you need to have ticks with values 0.42, 0.43, 1.5, 2.7 on the X-Axis, you can do the following:

You can set up the ticks drawn for each mark through tick property of the mark.

You can also switch off the regular ticks of the value axis to let marks be the only ticks displayed:

double values[4] = { 0.42, 1.33, 1.75, 2.7 };
for (int i = 0; i < 4; ++i)
{
    NChartValueAxisMark *m = [NChartValueAxisMark mark];
    m.value = values[i];
    m.tick.visible = YES;
    [m_view.chart.cartesianSystem.xAxis addMark:m];
}
let values = [0.42, 0.43, 1.5, 2.7]
for i in 0...3 {
    let m = NChartValueAxisMark()
    m.value = Double(values[i])
    m.tick.visible = true
    m_view.chart.cartesianSystem.xAxis.addMark(m)
}
double[] values = new double[] {0.42, 0.43, 1.5, 2.7};
for (int i = 0; i < 4; ++i) {
    NChartValueAxisMark m = new NChartValueAxisMark();
    m.setValue(values[i]);
    m.tick().setVisible(true);
    mNChartView.getChart().getCartesianSystem().getXAxis().addMark(m);
}
How to hide grid lines and axes lines?

There are two ways to achieve this.

The first one is to hide the whole coordinate system:

The second one is to hide lines only by altering properties of axes and grid lines.

To alter the appearance of axes, you can use properties of the class NChartValueAxis. To access the axes, you can use getters of cartesianSystem like xAxis and similar.

For example, to hide the line of X-axis, do the following:

To alter the appearance of grid lines, you can use properties of the class NChartAxisGrid. To access the grid lines, you can use getters of cartesianSystem like xAlongY and similar. For example, to hide grid lines that are perpendicular to X-axis and stroke along Y-Axis, do the following:

However after that the border of plot area will still be visible. To hide it too, do the following:

m_view.chart.cartesianSystem.visible = NO;
m_view.chart.cartesianSystem.visible = false
m_view.getChart().getCartesianSystem().setVisible(false);
How to hide zero on the axis?

You can hide zero or any other value on the axis by customizing the number format of axis’ ticks. Please, see previous question for details.

For example, your conversion code might look like:

- (NSString *)valueAxisDataSourceDouble:(double)value toStringForValueAxis:(NChartValueAxis *)axis
{
    return value == 0.0 ? @"" : [NSString stringWithFormat:@"%f", value];
}
func valueAxisDataSourceDouble(value: Double, toStringForValueAxis axis: NChartValueAxis!) -> String! {
    return value == 0.0 ? "" : "\(value)"
}
public String doubleToString(double value, NChartValueAxis axis) {
    return value == 0.0 ? "" : String.format("%f", value);
}
How to rotate axis labels?

You can use property labelsAngle of corresponding axis. For example, do the following:

Note, that you also can alter the labels alignment relative to the axes’ ticks with the property labelsAlignment.

m_view.chart.cartesianSystem.xAxis.labelsAngle = -M_PI_4;
m_view.chart.cartesianSystem.xAxis.labelsAngle = -Float.pi / 4.0
m_view.getChart().getCartesianSystem().getXAxis().setLabelsAngle(Math.PI / 4.0);
I want to update the chart in realtime, but updateData seems to be very slow. How can I seed it up?

There are several optimization options depending on the circumstances.

If the number of chart points does not change and you are updating values only, you can use so called streaming mode. You can find the streaming usage example in the sample called Streaming inside the NChart3D package.

If the number of points change, but you are sure, minimal and maximal values wont change, you can use this method instead of regular updateData.

If minimum and maximum change as well as the number of points, but the points are changed incrementally (new points are added, but the old ones are still in the chart), you can use special mechanism for data appending. You can find the usage example of this mechanism in the sample called AutoScroll inside the NChart3D package.

Also, if you don't need points to be selected by click, you can set this property to NO. This will speed up data updating in all the cases.

When there are a lot of ticks on the X-axis, some of them are not visible. How to fix this?

If there are too many ticks, some of them hide automatically and are visible by zooming the chart only. You can alter the minimal size required for one tick with the property minTickSpacing of the corresponding value axis. To disable the auto hiding, just set this space to zero:

m_view.chart.cartesianSystem.xAxis.minTickSpacing = 0.0f;
m_view.chart.cartesianSystem.xAxis.minTickSpacing = 0.0
m_view.getChart().getCartesianSystem().getXAxis().setMinTickSpacing(0.0f);
Why ticks of the X-axis are shifted from the axis' beginning?

This is called axes' offset and it is turned on for X-axis by default. If you do not need it, do the following:

m_view.chart.cartesianSystem.xAxis.hasOffset = NO;
m_view.chart.cartesianSystem.xAxis.hasOffset = false
m_view.getChart().getCartesianSystem().getXAxis().setHasOffset(false);
Why transparent background does not work?

If your are using NChart3D for iOS, to make the transparency of background work you have to switch off the opacity of the NChartView instance just after you created it:

However this can hit the performance in some cases, because NChart3D is based on OpenGLES and alpha-blending of its grapical content with other UI may be inefficient.

If you are using NChart3D for macOS, you have to set the "Compositing Filter" in the settings of the view in corresponding XIB. The default value of this property is "No Filter", but you have to set for example "Color Blend Mode".

m_view.opaque = NO;
m_view.isOpaque = false
m_view.setBackgroundColor(Color.TRANSPARENT);
m_view.getChart().setBackground(new NChartSolidColorBrush(Color.TRANSPARENT));
Chart stops updating after unlocking device. How to fix it? Objective-C only

Sometiems iOS relayouts the application's view when the application enters background and this leads to failure of internal graphical context. To prevent this, you have to use the following property of the chart view: isUpdatingEnabled

Disable updating when application enters background and reenable it when application resumes. For this, implement the following methods of your applicatin delegate (assuming you have access to your NChartView instance in the m_chartView variable):

Please, note, that if you have many instances of NChartView, you have to switch the isUpdatingEnabled value of each one.

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    m_chartView.isUpdatingEnabled = NO;
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    m_chartView.isUpdatingEnabled = YES;
}
I have a memory leak on Android when I remove the chart view. Am I missing something? Java only

You have to call cleanup method of the NChartView every time you deleting the view.

For example, you can have the following code in your activity:   

// Chart view
NChartView chartView;

@Override
public void onDestroy() {
    super.onDestroy();
    chartView.destroyDrawingCache();
    chartView.cleanup();
    chartView = null;
}
I see white screen instead of a chart, what am I doing wrong? Java only

Here are some common mistakes you could have occasionally done:

  • You forgot to call updateData() of the chart or called it in the wrong place. The proper initialization sequence is: 
  1. Create series.
  2. Set data source to ALL series.
  3. Add series to the chart.
  4. Call updateData().
  • You return null of too few points from your implementation of NChartSeriesDataSource. Some series like Surface or Line need more than one point to be displayed. Check your implementation of NChartPoint[] points(NChartSeries series) method.
  • You did not retain data source for series in the member variable. This is probably the most common but also most non-obvious pitfall. Chart stores data source in a weak reference. This means, if you don't retain it somewhere outside of the chart, it will be cleaned by GC.
  • Calling beginTransaction() you forgot to call endTransaction(). You have to call beginTransaction() if you use another thread to update data, and you have to call endTransaction() in the end of your updating method.
NChart3D works in debug but does not in release. What am I missing? Java only

Probably the problem is that you are using ProGuard when building a release APK. NChart3D contains native methods which should not be modified. To prevent the modification you have to exclude all the classes matching the mask com.nchart3d.*  from obfuscation.

NChartView does not work in storyboard. How to fix this? Objective-C only

If you use NChartView as IBOutlet, xcode can generate some problems like

  •  'Unknown class NChartView in Interface Builder file'
  •  '-[UIView chart]: unrecognized selector sent to instance'

The problem is that it's not so straightforward to link storyboard with the custom view. The app does not load third-party framework (for example, NChart3D) before creating storyboard, so at the time storyboard is created there are no symbols from NChart3D available. This is how iOS is organized right now.

The workaround is to subclass NChartView with you own class and use this class in storyboard:
 

Also don't forget that storyboard creates and loads view by itself and you don't need to implement -(void)loadView.

You just need to customize chart in -(void)viewDidLoad method.

@interface MyChartView : NChartView
@end

@implementation MyChartView
@end

@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet MyChartView *chartView;
@end

NGrid API Documentation

The complete documentation of NGrid classes, constants and public API methods.

NGrid Objective-C API