Determines whether to show visibility checkboxes for every RenderableSeries in the Legend or not. These allow hiding or showing their corresponding RenderableSeries.
Allows to specify which RenderableSeries should appear in the Legend, e.g. Visible, Selected, etc. Series. Other will be ignored by the modifier. Expects a member of the SCISourceMode enumeration.
// Assume a surface has been created and configured somewhere
id<ISCIChartSurface> surface;
// Create a Modifier
SCILegendModifier *legendModifier = [SCILegendModifier new];
legendModifier.position = SCIAlignment_Top | SCIAlignment_Left;
legendModifier.margins = UIEdgeInsetsMake(16, 16, 16, 16);
legendModifier.sourceMode = SCISourceMode_AllSeries;
legendModifier.orientation = SCIOrientationHorizontal;
// Add the modifier to the surface
[self.surface.chartModifiers add:legendModifier];
// Assume a surface has been created and configured somewhere
let surface: ISCIChartSurface
// Create a Modifier
let legendModifier = SCILegendModifier()
legendModifier.position = [.left, .top]
legendModifier.margins = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
legendModifier.sourceMode = .allVisibleSeries
legendModifier.orientation = .horizontal
// Add the modifier to the surface
self.surface.chartModifiers.add(legendModifier)
// Assume a surface has been created and configured somewhere
IISCIChartSurface surface;
// Create a Modifier
var legendModifier = new SCILegendModifier();
legendModifier.Position = SCIAlignment.Top | SCIAlignment.Left;
legendModifier.Margins = new UIEdgeInsets(16, 16, 16, 16);
legendModifier.SourceMode = SCISourceMode.AllSeries;
legendModifier.Orientation = SCIOrientation.Horizontal;
// Add the modifier to the surface
Surface.ChartModifiers.Add(legendModifier);
NOTE: By passing false to useAutoPlacement argument you indicate that you want to place SCIChartLegend instance manually, in this case - outside the Chart Surface.
While placing a Legend you might want to use your custom constraints.
There are two most common approaches to define Legend frame:
By default, we calculate Legend size according to its content.
To achieve this, we use some under the hood calculations and apply constraints with priority 800-801.
If you want to allow the Legend to be resized according to its content, a priority of your width and height constraints should be lower than 800.
As an example, let’s assume that you want to place a Legend with the following requirements:
it should be placed at the Top and Leading of the parent view
size should be calculated according to its content.
your SCIChartSurface should be placed trailing to the Legend and fill all available space.
To achieve this you need to add leading and top constraints with a priority higher than 801, e.g. 1000,
trailing and bottom constraints with a priority less than 800, e.g. 500 to the Legend.
// Create Chart Surface
SCIChartSurface *surface = [SCIChartSurface new];
[self addSubview:surface];
// Create surface constraints
surface.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *topSurfaceConstraint = [surface.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor];
NSLayoutConstraint *trailingSurfaceConstraint = [surface.trailingAnchor constraintEqualToAnchor: self.trailingAnchor];
NSLayoutConstraint *bottomSurfaceConstraint = [surface.bottomAnchor constraintEqualToAnchor: self.bottomAnchor];
// Create a legend
SCIChartLegend *legend = [SCIChartLegend new];
SCIView *container = legend.container;
[self addSubview:container];
// Create legend constraints
container.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *leadingLegendConstraint = [container.leadingAnchor constraintEqualToAnchor: self.leadingAnchor];
NSLayoutConstraint *topLegendConstraint = [container.topAnchor constraintEqualToAnchor: self.safeAreaLayoutGuide.topAnchor];
NSLayoutConstraint *trailingLegendConstraint = [container.trailingAnchor constraintEqualToAnchor: surface.leadingAnchor];
// By setting constraint priority to value lower than 800 you indicate that the legend will ignore this constraint and calculate its width or height automatically. Hence these constraints will be ignored, adding them here is optional.
NSLayoutConstraint *bottomLegendConstraint = [container.bottomAnchor constraintEqualToAnchor: self.bottomAnchor];
bottomLegendConstraint.priority = 500;
NSLayoutConstraint *widthLegendConstraint = [container.widthAnchor constraintEqualToConstant:300];
widthLegendConstraint.priority = 500;
[container addConstraint:widthLegendConstraint];
// Add constraints to a superview
[self addConstraints:@[topSurfaceConstraint, trailingSurfaceConstraint, bottomSurfaceConstraint, leadingLegendConstraint, topLegendConstraint, trailingLegendConstraint/*, bottomLegendConstraint*/]];
// Create a dataSource
SCISeriesInfoLegendDataSource *dataSource = [[SCISeriesInfoLegendDataSource alloc] initWithLegend:legend];
// Create a modifier
SCILegendModifier *legendModifier = [[SCILegendModifier alloc] initWithLegend:legend dataSource:dataSource useAutoPlacement:NO];
// Add the modifier to the surface
[self.surface.chartModifiers add:legendModifier];
// Create Chart Surface
let surface = SCIChartSurface()
self.addSubview(surface)
// Create surface constraints
surface.translatesAutoresizingMaskIntoConstraints = false
let topSurfaceConstraint = surface.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor)
let trailingSurfaceConstraint = surface.trailingAnchor.constraint(equalTo: self.trailingAnchor)
let bottomSurfaceConstraint = surface.bottomAnchor.constraint(equalTo: self.bottomAnchor)
// Create a legend
let legend = SCIChartLegend()
guard let container = legend.container else { return }
self.addSubview(container)
// Create legend constraints
container.translatesAutoresizingMaskIntoConstraints = false
let leadingLegendConstraint = container.leadingAnchor.constraint(equalTo: self.leadingAnchor)
let topLegendConstraint = container.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor)
let trailingLegendConstraint = container.trailingAnchor.constraint(equalTo: surface.leadingAnchor)
// By setting constraint priority to value lower than 800 you indicate that the legend will ignore this constraint and calculate its width or height automatically. Hence these constraints will be ignored, adding them here is optional.
let bottomLegendConstraint = container.bottomAnchor.constraint(equalTo: self.bottomAnchor)
bottomLegendConstraint.priority = UILayoutPriority(rawValue: 500)
let widthLegendConstraint = container.widthAnchor.constraint(equalToConstant: 300)
widthLegendConstraint.priority = UILayoutPriority(rawValue: 500)
container.addConstraint(widthLegendConstraint)
// Add constraints to a superview
self.addConstraints([topSurfaceConstraint, trailingSurfaceConstraint, bottomSurfaceConstraint, leadingLegendConstraint, topLegendConstraint, trailingLegendConstraint, bottomLegendConstraint])
// Create a dataSource
guard let dataSource = SCISeriesInfoLegendDataSource(legend: legend) else { return }
// Create a modifier
let legendModifier = SCILegendModifier(legend: legend, dataSource: dataSource, useAutoPlacement: false)
// Add the modifier to the surface
surface.chartModifiers.add(legendModifier)
// Create Chart Surface
var surface = new SCIChartSurface();
View.AddSubview(surface);
// Create surface constraints
surface.TranslatesAutoresizingMaskIntoConstraints = false;
var topSurfaceConstraint = surface.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor);
var trailingSurfaceConstraint = surface.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor);
var bottomSurfaceConstraint = surface.BottomAnchor.ConstraintEqualTo(View.BottomAnchor);
// Create a legend
var legend = new SCIChartLegend();
View.AddSubview(legend);
// Create legend constraints
legend.TranslatesAutoresizingMaskIntoConstraints = false;
var leadingLegendConstraint = legend.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor);
var topLegendConstraint = legend.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor);
var trailingLegendConstraint = legend.TrailingAnchor.ConstraintEqualTo(surface.LeadingAnchor);
// By setting constraint priority to value lower than 800 you indicate that the legend will ignore this constraint and calculate its width or height automatically. Hence these constraints will be ignored, adding them here is optional.
var bottomLegendConstraint = legend.BottomAnchor.ConstraintEqualTo(View.BottomAnchor);
bottomLegendConstraint.Priority = 500;
var widthLegendConstraint = legend.WidthAnchor.ConstraintEqualTo(300);
widthLegendConstraint.Priority = 500;
legend.AddConstraint(widthLegendConstraint);
// Add constraints to a superview
View.AddConstraints(new NSLayoutConstraint[] { topSurfaceConstraint, trailingSurfaceConstraint, bottomSurfaceConstraint, leadingLegendConstraint, topLegendConstraint, trailingLegendConstraint, bottomLegendConstraint });
// Create a dataSource
var dataSource = new SCISeriesInfoLegendDataSource(legend);
// Create a modifier
var legendModifier = new SCILegendModifier(legend: legend, dataSource: dataSource, useAutoPlacement: false);
// Add the modifier to the surface
surface.ChartModifiers.Add(legendModifier);
This produces the following output:
Fill all available space defined by the constraints
Sometimes you might want to place a legend as a normal view with a fixed width or height.
To achieve this, the priority of all your constraints must be higher than 801.
As an example, let’s assume that you want to place a Legend with the following requirements:
at the top of the parent view with leading, top, trailing constraints
with fixed height equal to 70.
SCIChartSurface instance should be below and fill all available space.
in case the content of a Legend is bigger than its height user can scroll it as a normal collection view.
// Create a legend
let legend = SCIChartLegend()
self.addSubview(legend)
// Create legend constraints
legend.translatesAutoresizingMaskIntoConstraints = false
let leadingLegendConstraint = legend.leadingAnchor.constraint(equalTo: self.leadingAnchor)
let topLegendConstraint = legend.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor)
let trailingLegendConstraint = legend.trailingAnchor.constraint(equalTo: self.trailingAnchor)
let heightLegendConstraint = legend.heightAnchor.constraint(equalToConstant: 70)
legend.addConstraint(heightLegendConstraint)
// Create Chart Surface
let surface = SCIChartSurface()
self.addSubview(surface)
// Create surface constraints
surface.translatesAutoresizingMaskIntoConstraints = false
let topSurfaceConstraint = surface.topAnchor.constraint(equalTo: legend.bottomAnchor)
let leadingSurfaceConstraint = surface.leadingAnchor.constraint(equalTo: self.leadingAnchor)
let trailingSurfaceConstraint = surface.trailingAnchor.constraint(equalTo: self.trailingAnchor)
let bottomSurfaceConstraint = surface.bottomAnchor.constraint(equalTo: self.bottomAnchor)
// Add constraints to a superview
self.addConstraints([leadingLegendConstraint, topLegendConstraint, trailingLegendConstraint, topSurfaceConstraint, leadingSurfaceConstraint, trailingSurfaceConstraint, bottomSurfaceConstraint])
// Create a dataSource
guard let dataSource = SCISeriesInfoLegendDataSource(legend: legend) else {
return
}
// Create a modifier
let legendModifier = SCILegendModifier(legend: legend, dataSource: dataSource, useAutoPlacement: false)
// Add the modifier to the surface
surface.chartModifiers.add(legendModifier)
// Create a legend
var legend = new SCIChartLegend();
View.AddSubview(legend);
// Create legend constraints
legend.TranslatesAutoresizingMaskIntoConstraints = false;
var leadingLegendConstraint = legend.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor);
var topLegendConstraint = legend.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor);
var trailingLegendConstraint = legend.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor);
var heightLegendConstraint = legend.HeightAnchor.ConstraintEqualTo(70);
legend.AddConstraint(heightLegendConstraint);
// Create Chart Surface
var surface = new SCIChartSurface();
View.AddSubview(surface);
// Create surface constraints
surface.TranslatesAutoresizingMaskIntoConstraints = false;
var topSurfaceConstraint = surface.TopAnchor.ConstraintEqualTo(legend.BottomAnchor);
var leadingSurfaceConstraint = surface.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor);
var trailingSurfaceConstraint = surface.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor);
var bottomSurfaceConstraint = surface.BottomAnchor.ConstraintEqualTo(View.BottomAnchor);
// Add constraints to a superview
View.AddConstraints(new NSLayoutConstraint[] { leadingLegendConstraint, topLegendConstraint, trailingLegendConstraint, topSurfaceConstraint, leadingSurfaceConstraint, trailingSurfaceConstraint, bottomSurfaceConstraint });
// Create a dataSource
var dataSource = new SCISeriesInfoLegendDataSource(legend);
// Create a modifier
var legendModifier = new SCILegendModifier(legend: legend, dataSource: dataSource, useAutoPlacement: false);
// Add the modifier to the surface
surface.ChartModifiers.Add(legendModifier);
This produces the following output:
Create Legend with a custom item
To create a SCIChartLegend with custom items, you will need to create UICollectionView inheritor and pass it to SCILegendDataSource so we can prepare everything else for you.
Read on to learn how to do that.
Create a Custom Legend Item
Your Custom Legend Item must inherit from UICollectionViewCell and conform to ISCILegendItem protocol. Also, it must be created in xib with reuseIdentifier = LegendItemReuseIdentifier.
// Assume that the CustomLegendItem.xib file is created somewhere in your project
import UIKit
final class CustomLegendItem: UICollectionViewCell, ISCILegendItem {
@IBOutlet private weak var markerView: UIView!
@IBOutlet private weak var seriesNameLabel: UILabel!
override var reuseIdentifier: String? {
return LegendItemReuseIdentifier
}
// MARK: ISCILegendItem
func bindSeriesInfo(with source: Any!, legend: ISCIChartLegend!) {
guard let seriesInfo = source as? SCISeriesInfoCore else {
return
}
markerView.backgroundColor = seriesInfo.seriesColor
seriesNameLabel.text = seriesInfo.seriesName
}
}
// Assume that the CustomLegendItem.xib file is created somewhere in your project
using System;
using Foundation;
using UIKit;
using SciChart.iOS.Charting;
namespace Xamarin.Examples.Demo.iOS
{
public partial class CustomLegendItem : UICollectionViewCell, IISCILegendItem
{
public static readonly NSString Key = new NSString(“CustomLegendItem”);
public static readonly UINib Nib;
static CustomLegendItem()
{
Nib = UINib.FromName(“CustomLegendItem”, NSBundle.MainBundle);
}
protected CustomLegendItem(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public override NSString ReuseIdentifier => SCIChartLegend.LegendItemReuseIdentifier;
public void bindSeriesInfo(NSObject source, IISCIChartLegend legend)
{
var seriesInfo = source as SCISeriesInfoCore;
if (seriesInfo != null)
{
markerView.BackgroundColor = seriesInfo.SeriesColor;
seriesNameLabel.Text = seriesInfo.SeriesName;
}
}
}
}
Adding a Legend with CustomItem to a Chart
To add a Legend with previously created Custom Legend Item you will need to do the following:
use the -[SCILegendDataSource initWithLegend:legendItemXibName:] initializer to create a legend DataSource. Pass legend created in the previous step and your CustomLegendItem.xib name string.
NOTE: By passing true or false to useAutoPlacement argument you indicate whether you want to place your SCIChartLegend instance manually, e.g. - inside or outside the Chart Surface.
Please see the code sample on how to do that below:
// Assume a surface has been created and configured somewhere
ISCIChartSurface surface;
// Create a legend
SCIChartLegend *legend = [SCIChartLegend new];
// Create a dataSource with your custom legend item xib name. Assume a CustomLegendItem class has been created and configured somewhere
SCISeriesInfoLegendDataSource *dataSource = [[SCISeriesInfoLegendDataSource alloc] initWithLegend:legend legendItemXibName:@“CustomLegendItem”];
// Create a modifier.
// By passing `YES` to `useAutoPlacement` argument you indicate that you want to place Legend inside the Chart Surface.
SCILegendModifier *legendModifier = [[SCILegendModifier alloc] initWithLegend:legend dataSource:dataSource useAutoPlacement:YES];
legendModifier.margins = UIEdgeInsetsMake(16, 16, 16, 16);
legendModifier.position = SCIAlignment_Top | SCIAlignment_Left;
// Add the modifier to the surface
[self.surface.chartModifiers add:legendModifier];
// Assume a surface has been created and configured somewhere
let surface: ISCIChartSurface
// Create a legend
let legend = SCIChartLegend()
// Create a dataSource with your custom legend item xib name. Assume a CustomLegendItem class has been created and configured somewhere
let dataSource = SCISeriesInfoLegendDataSource(legend: legend, legendItemXibName: “CustomLegendItem”)
// Create a modifier.
// By passing `true` to `useAutoPlacement` argument you indicate that you want to place Legend inside the Chart Surface.
let legendModifier = SCILegendModifier(legend: legend, dataSource: dataSource, useAutoPlacement: true)
legendModifier.position = [.left, .top]
legendModifier.margins = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
// Add the modifier to the surface
surface.chartModifiers.add(legendModifier)
// Assume a surface has been created and configured somewhere
SCIChartSurface surface;
// Create a legend
var legend = new SCIChartLegend();
// Create a dataSource with your custom legend item xib name. Assume a CustomLegendItem class has been created and configured somewhere
var dataSource = new SCISeriesInfoLegendDataSource(legend: legend, legendItemXibName: “CustomLegendItem”);
// Create a modifier.
// By passing `true` to `useAutoPlacement` argument you indicate that you want to place Legend inside the Chart Surface.
var legendModifier = new SCILegendModifier(legend: legend, dataSource: dataSource, useAutoPlacement: true);
legendModifier.Position = SCIAlignment.Top | SCIAlignment.Left;
legendModifier.Margins = new UIEdgeInsets(16, 16, 16, 16);
// Add the modifier to the surface
surface.ChartModifiers.Add(legendModifier);