The Chart is part of Telerik UI for Xamarin, a
professional grade UI component library for building modern and feature-rich applications. To try it out sign up for a free 30-day trial.
Chart for Xamarin.iOS: Custom Drawing
TKChart
has a powerful drawing engine to help you customize your chart appearance. It allows you to:
- define different kinds of fills. Solid color, Linear gradient, Radial gradient, fill with image content.
- define strokes which contain information about stroke fill, dash pattern, line width etc.
- define fill & stroke's corner radius, which corners to apply that radius to. It also supports drawing insets.
Working with fills
There are several kinds of fills:
Solid fill
TKSolidFill
is the simplest of all fills. It paints chart items with a single color. Here is how you define it:
var fill = new TKSolidFill (UIColor.Red);
After you set it to a palette (discussed later) you get result like this:
You can also specify corner radius:
var fill = new TKSolidFill (UIColor.Red, 5.0f);
This results in columns looking like this:
All fills and strokes allow you to specify not only corner radius, but also which corners to round. Semi-transparent red fill with only two corners rounded can be defined like this:
var fill = new TKSolidFill (new UIColor (1.0f, 0.0f, 0.0f, 0.5f), 8.0f);
fill.Corners = UIRectCorner.TopLeft | UIRectCorner.BottomRight;
There you get:
Linear gradient fill
TKLinearGradientFill
allows you to fill an item with color gradients. You can specify which colors to use and relative to the size positions of gradient stops.
Here is how you define linear gradient with 3 colors (green to red to blue) with transparency:
var fill = new TKLinearGradientFill (new UIColor[] {
new UIColor (0.0f, 1.0f, 0.0f, 0.6f),
new UIColor (1.0f, 0.0f, 0.0f, 0.6f),
new UIColor (0.0f, 0.0f, 1.0f, 0.6f)
},
new CGPoint(0, 0),
new CGPoint(1, 1));
If you wish to distribute those colors unevenly and change gradient direction here is how to do it:
var fill = new TKLinearGradientFill (new UIColor[] {
new UIColor (0.0f, 1.0f, 0.0f, 0.6f),
new UIColor (1.0f, 0.0f, 0.0f, 0.6f),
new UIColor (0.0f, 0.0f, 1.0f, 0.6f)
},
new NSObject[] { new NSNumber(0.6), new NSNumber(0.8), new NSNumber(1.0) },
new CGPoint(0, 0),
new CGPoint(1, 1));
Warning: All coordinates for locations, startPoint and endPoint parameters are relative to the size of drawing surface. The values of locations array must be monotonically increasing.
Radial gradient fill
TKRadialGradientFill
draws a fill with two colors using centers relative to the drawing size. Radius is set in different measures depending on TKGradientRadiusType parameter. It is hard to master and most of the time you can achieve the same functionality with linear gradient. Here is a possible usage:
var fill = new TKRadialGradientFill (new UIColor[] {
new UIColor (0.0f, 1.0f, 0.0f, 0.7f),
new UIColor (1.0f, 0.0f, 0.0f, 0.0f)
},
new CGPoint (0.5f, 0.5f),
0.7f,
new CGPoint (0, 1),
0.3f,
TKGradientRadiusType.RectMax);
The resulting ghost column chart looks like this:
Image fill
TKImageFill
fills the drawing area with the content of an image. There is also a ResizingMode
which specify how to draw image. Here is an example usage of tiled image:
var fill = new TKImageFill (new UIImage ("pattern1.png"), 4.0f);
fill.ResizingMode = TKImageFillResizingMode.Tile;
this is the source (pattern) image to draw:
<= original <= 8 times magnified version
Filling with images in stretch mode is even easier:
var fill = new TKImageFill (new UIImage ("building1.png"), 4.0f);
Sometimes you like to specify your own stretchable image. Stretching this image with your own code, leads to the following result:
UIImage image = new UIImage ("pattern2.png");
var fill = new TKImageFill (image.CreateResizableImage (new UIEdgeInsets (10, 10, 10, 10)));
fill.ResizingMode = TKImageFillResizingMode.None;
Adding stroke
TKStroke
is a powerful tool which allows you to customize how you apply strokes to your charts.
You can create a simple stroke like this:
var stroke = new TKStroke (UIColor.Blue);
With rounded corners:
var stroke = new TKStroke (UIColor.Blue, 1.0f);
stroke.CornerRadius = 5.0f;
With dash pattern:
var stroke = new TKStroke (UIColor.Blue, 1.0f);
stroke.CornerRadius = 5.0f;
stroke.DashPattern = new NSNumber[] { new NSNumber(2), new NSNumber(2), new NSNumber(5), new NSNumber(2) };
You can fill a stroke with a gradient:
var fill = new TKLinearGradientFill (new UIColor[] {
new UIColor (0.0f, 1.0f, 0.0f, 0.6f),
new UIColor (1.0f, 0.0f, 0.0f, 0.6f),
new UIColor (0.0f, 0.0f, 1.0f, 0.6f)
}, new CGPoint(0, 0), new CGPoint(1, 1));
var stroke = new TKStroke (fill, 1.0f);
stroke.CornerRadius = 5.0f;
Or combine most of it in one place:
var fill = new TKLinearGradientFill(new UIColor[] {
new UIColor (0.0f, 1.0f, 0.0f, 0.6f),
new UIColor (1.0f, 0.0f, 0.0f, 0.6f),
new UIColor (0.0f, 0.0f, 1.0f, 0.6f)
}, new CGPoint(0, 0), new CGPoint(1, 1));
var stroke = new TKStroke (fill, 1.0f);
stroke.CornerRadius = 5.0f;
stroke.DashPattern = new NSNumber[] { new NSNumber(2), new NSNumber(2), new NSNumber(5), new NSNumber(2) };
stroke.Corners = UIRectCorner.TopRight | UIRectCorner.BottomLeft;
And here is the result of all samples:
or with line chart using strokes with width = 2
Customizing TKChart
Customizing TKChart
can be done using TKChartPalette
. You can access the palette from TKChartSeries
using series.Style.Palette variable. By default, palette is nil which means that TKChart
will use its default theme. To specify your own, you need to create it:
TKChartSeries series = null;
series.Style.Palette = new TKChartPalette();
TKChartPalette is a collection of TKChartPaletteItem
instances. Every item contains information about drawing the item at its index. By default, a palette item index addresses the order in which you add series. For example, you may have a palette with red and blue fills and two TKChartColumnSeries
using this palette. The first series you add will be red and the second blue. However, TKChartPieSeries
by default uses another mode when every palette item is used to display a data point at its index. You can explicitly set how you distribute a palette items using:
series.Style.PaletteMode = TKChartSeriesStylePaletteMode.UseItemIndex;
or
series.Style.PaletteMode = TKChartSeriesStylePaletteMode.UseSeriesIndex;
Whenever TKChartPalette
runs out of colors (because there are more series or more data points than TKChartPaletteItem
items inside) it starts over effectively cycling through its items.
To illustrate the difference between palette modes, consider the following setup:
List<TKChartDataPoint> gdpInPoundsPoints = null;
var series = new TKChartColumnSeries (gdpInPoundsPoints.ToArray());
series.Style.Palette = new TKChartPalette ();
var redFill = new TKSolidFill (UIColor.Red);
series.Style.Palette.AddPaletteItem (new TKChartPaletteItem (redFill));
var blueFill = new TKSolidFill (UIColor.Blue);
series.Style.Palette.AddPaletteItem (new TKChartPaletteItem (blueFill));
var greenFill = new TKSolidFill (UIColor.Green);
series.Style.Palette.AddPaletteItem (new TKChartPaletteItem (greenFill));
series.Style.PaletteMode = TKChartSeriesStylePaletteMode.UseItemIndex;
chart.AddSeries (series);
As you see we are using TKChartSeriesStylePaletteModeUseItemIndex
palette mode and the result is:
Here the palette items are used to color the different data points. Since palette items inside are 3 and data points are 5, the palette starts over reusing the items it has. If you remove the line:
series.Style.PaletteMode = TKChartSeriesStylePaletteMode.UseItemIndex;
or change it to:
series.Style.PaletteMode = TKChartSeriesStylePaletteMode.UseSeriesIndex;
you will get:
This is because you have added only one series. Adding a second series with the same palette will make its data points blue. Adding a third series will make its data points green and fourth would be red again.
Palette items
TKChartPaletteItem
is the building block of TKChartPalette
and contains information about how to draw items. The simple way to use it is to specify a fill and/or stroke. Consider one of the following constructors:
var paletteItem1 = new TKChartPaletteItem (new TKSolidFill (UIColor.Red));
var paletteItem2 = new TKChartPaletteItem(new TKStroke(UIColor.Blue));
var plaetteItem3 = new TKChartPaletteItem(new TKStroke(UIColor.Blue), new TKSolidFill(UIColor.Red));
series.Style.Palette.AddPaletteItem (paletteItem1);
When you initialize a palette item with stroke and fill the stroke is always drawn last.
There is also an alternative and a more flexible way to create a palette item by specifying an array of fills and strokes in the order you would like them to be drawn:
series.Style.Palette = new TKChartPalette ();
var redFill = new TKSolidFill (UIColor.Red, 2.0f);
var stroke1 = new TKStroke (UIColor.Yellow, 1.0f);
stroke1.CornerRadius = 2.0f;
stroke1.Insets = new UIEdgeInsets (1, 1, 1, 1);
var stroke2 = new TKStroke (UIColor.Black, 1.0f);
stroke2.CornerRadius = 2.0f;
series.Style.Palette.AddPaletteItem(new TKChartPaletteItem(new TKDrawing[] { redFill, stroke1, stroke2 }));
here you create a palette item with red fill and two borders. The sample also shows another powerful feature: insets. Insets can be applied to both fills and strokes. Here is the final result:
Customizing line series
TKChartLineSeries
uses only TKStroke instances of TKChartPaletteItem
and ignores any fills. You can specify a wide first stroke and thin second stroke if you need more than one stroke.
Customizing area series
TKChartAreaSeries
uses TKStroke instances of TKChartPaletteItem
for the line and fills for area part.
Customizing scatter series
TKChartScatterSeries
uses palette items to draw its shapes. However you might also change shape's type using code like:
series.Style.PointShape = new TKPredefinedShape (TKShapeType.Rhombus, new CGSize (15, 15));
series.Style.PointShape also applies to line and area series in case you need to show shapes on data points.
Customizing pie series
TKChartPieSeries always use series.Style.PaletteMode = TKChartSeriesStylePaletteModeUseItemIndex;
. If you have strokes with insets, only Insets.Top value will be used and will be applied relatively to the outer radius of the pie chart slices.
@warning Customization is a very powerful feature of TKChart. However, we recommend using that feature at an acceptable rate. Using too many fills and strokes may affect performance. Combining all features like a dashed stroke with gradient plus several semi transparent fills will draw much slower than a simple solid color fill.