Статьи

Работа с CorePlot: стилизация и добавление графиков

При работе с приложениями, интенсивно использующими данные, разработчик часто должен делать больше, чем просто показывать списки записей данных в табличном представлении. Библиотека CorePlot позволит вам добавить потрясающие визуализации данных в ваши приложения. Узнайте, как в этой серии Tuts + Premium!


  1. Работа с CorePlot: настройка проекта
  2. Работа с CorePlot: основы построения
  3. Работа с CorePlot: стилизация и добавление графиков
  4. Работа с CorePlot: создание гистограммы
  5. Работа с CorePlot: создание круговой диаграммы

В прошлый раз мы создали начало нашего первого линейного графика и позволили пользователю перемещаться туда из списка. Мы узнали о методах CPTGraphHostingView, CPTGraph, CPTXYPlotSpace, CPTScatterPlot и CPTScatterPlotDataSource, которые предоставляют данные для графа.

Сегодня мы рассмотрим, как сделать график более полезным для пользователя, указав приращение оси и как форматировать метки приращения. Мы рассмотрим различные способы настройки внешнего вида графика. Наконец, мы собираемся обсудить, как работать с разными графиками на одном графике. Давайте начнем!


Чтобы изменить свойства осей X и Y, мы работаем с объектами CPTXYAxisSet и CPTXAxis. Откройте файл STLineGraphViewController.m и перейдите к методу viewDidLoad. Чуть ниже, где мы работаем с сюжетом Space, введите следующий код:

1
[[graph plotAreaFrame] setPaddingLeft:20.0f];

Давайте пройдемся по всему выше. Во-первых, мы работаем со свойством графа под названием plotAreaFrame. При этом мы можем установить отступ области, в которой фактически рисуется график, и это позволяет нам видеть метки оси (которые ранее были скрыты). Затем мы устанавливаем стиль линии границы на ноль, чтобы избавиться от границы вокруг графика.

Затем мы создаем форматер NSNumber, который мы используем для форматирования меток оси. Мы также создаем что-то под названием «CPTMutableTextStyle». При форматировании строк, заливки раздела и текста для объектов CorePlot мы используем такие объекты, как CPTMutableTextStyle, чтобы сделать это. Пока мы только устанавливаем размер шрифта, но мы также можем установить тип и цвет шрифта.

Затем мы получаем объект CPTXYAxisSet из нашего графа. Этот axisSet содержит xAxis и yAxis (оба объекта типа ‘CPTXYAxis’). Затем мы устанавливаем различные свойства для каждой оси. Длина основного интервала устанавливает интервал для каждого основного тика. Мы также хотим избавиться от мелких тиков, поэтому мы устанавливаем стиль линии на ноль. Мы устанавливаем labellingPolicy на фиксированные интервалы. Затем мы устанавливаем стиль текста для объекта CPTMutableTextStyle, который мы создали ранее, и средства форматирования метки для NSNumberFormatter, который мы создали.


Теперь попробуйте перейти к виду студента и добавить студента. После этого вы можете вернуться к графику, и вы должны увидеть его изменение. Тем не менее, это все еще выглядит немного мягко …


Прежде всего, давайте изменим фактическую строку. Под тем, где у нас есть работа с осью, введите следующий код:

1
2
3
4
5
CPTMutableLineStyle *mainPlotLineStyle = [[studentScatterPlot dataLineStyle] mutableCopy];
[mainPlotLineStyle setLineWidth:2.0f];
[mainPlotLineStyle setLineColor:[CPTColor colorWithCGColor:[[UIColor blueColor] CGColor]]];
      
[studentScatterPlot setDataLineStyle:mainPlotLineStyle];

Это сделает линию на нашем графике синим и увеличит ширину. Если вы более креативны, вы можете сделать цвет немного менее резким, но важно отметить, что для него требуется значение CPTColor. Хотя мы не можем получить CPTColor от UIColor, мы можем получить его от CGColor.

Мы также можем изменить стиль линии оси. Введите следующий код ниже, где мы устанавливаем график dataLineStyle.

1
2
3
4
5
6
7
8
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
[axisLineStyle setLineWidth:1];
[axisLineStyle setLineColor:[CPTColor colorWithCGColor:[[UIColor grayColor] CGColor]]];
      
[xAxis setAxisLineStyle:axisLineStyle];
[xAxis setMajorTickLineStyle:axisLineStyle];
[yAxis setAxisLineStyle:axisLineStyle];
[yAxis setMajorTickLineStyle:axisLineStyle];

Это устанавливает стиль линии и стиль основной галочки для обеих осей. Вы также можете установить серый цвет textStyle, если хотите (это ваш график, сделайте так, как вы хотите!).

Вы также можете добавить градиентную заливку на линейный график, чтобы улучшить внешний вид. Для этого мы создаем объект CPTFill, который мы затем можем назначить на график:

1
2
3
4
5
6
CPTColor *areaColor = [CPTColor blueColor];
CPTGradient *areaGradient = [CPTGradient gradientWithBeginningColor:areaColor endingColor:[CPTColor clearColor]];
[areaGradient setAngle:-90.0f];
CPTFill *areaGradientFill = [CPTFill fillWithGradient:areaGradient];
[studentScatterPlot setAreaFill:areaGradientFill];
[studentScatterPlot setAreaBaseValue:CPTDecimalFromInt(0)];

Это создает заливку области, которую мы помещаем под линейный график, который идет от синего до прозрачного. Угол задает направление градиента, а базовое значение площади задает, откуда начинается градиент на графике. Поскольку мы хотим начать с нижней части графика, мы установили его на 0.

Наконец, иногда полезно иметь указания, где значения отображаются на линейном графике. Для этого нам нужно вызвать метод источника данных CPTScatterPlot с именем symbolForScatterPlot: recordIndex:

01
02
03
04
05
06
07
08
09
10
— (CPTPlotSymbol *)symbolForScatterPlot:(CPTScatterPlot *)aPlot recordIndex:(NSUInteger)index
{
    CPTPlotSymbol *plotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
    [plotSymbol setSize:CGSizeMake(10, 10)];
    [plotSymbol setFill:[CPTFill fillWithColor:[CPTColor blueColor]]];
    [plotSymbol setLineStyle:nil];
    [aPlot setPlotSymbol:plotSymbol];
          
    return plotSymbol;
}

Приведенный выше код создает и возвращает объект CPTPlotSymbol. Мы можем сделать так, чтобы все выглядело как угодно, но наш график будет использовать эллипс (круг), заполненный синим цветом, размером 10 на 10.

После того, как вы реализовали приведенный выше код, ваш график должен выглядеть примерно так:



Мы показываем зачисление студентов через какое-то время, но что, если мы хотим, чтобы зачисление по определенному предмету было на том же графике?

Объекты CPTGraph могут отображать несколько графиков. Мы создаем новый график, как мы это делали в прошлом, и добавляем его в график. В методах источника данных мы затем получаем идентификатор графа и, основываясь на этом, предоставляем правильные данные.

Давайте продолжим и создадим сюжет, показывающий регистрацию с течением времени для компьютерных наук. Под кодом, где мы создаем ‘studentScatterPlot’ (в методе viewDidLoad), добавьте следующее:

1
2
3
4
5
6
7
CPTScatterPlot *csScatterPlot = [[CPTScatterPlot alloc] initWithFrame:[graph bounds]];
[csScatterPlot setIdentifier:@»csEnrollement»];
[csScatterPlot setDelegate:self];
[csScatterPlot setDataSource:self];
      
[[self graph] addPlot:studentScatterPlot];
[[self graph] addPlot:csScatterPlot];

Пока мы находимся в этом методе, мы также должны немного его стилизовать. Давайте сделаем это зеленым. Под тем, где мы устанавливаем dataLineStyle для studentPlot, добавьте следующий код:

1
2
3
4
[studentScatterPlot setDataLineStyle:mainPlotLineStyle];
      
[mainPlotLineStyle setLineColor:[CPTColor greenColor]];
[csScatterPlot setDataLineStyle:mainPlotLineStyle];

Под тем местом, где мы устанавливаем заливку для графика разброса учеников, добавьте следующий код:

1
2
3
4
5
6
areaColor = [CPTColor greenColor];
areaGradient = [CPTGradient gradientWithBeginningColor:areaColor endingColor:[CPTColor clearColor]];
[areaGradient setAngle:-90.0f];
areaGradientFill = [CPTFill fillWithGradient:areaGradient];
[csScatterPlot setAreaFill:areaGradientFill];
[csScatterPlot setAreaBaseValue:CPTDecimalFromInt(0)];

Мы сделали все это раньше, поэтому мы не будем вдаваться в подробности. Теперь мы собираемся изменить наш метод ‘numberForPlot: field: recordIndex:’. Нам не нужно менять метод numberOfRecordsForPlot: потому что в любом случае у нас будет 7 записей. В numberForPlot: field: recordIndex: метод найдите, где мы устанавливаем предикат, и измените его так, чтобы иметь следующее:

01
02
03
04
05
06
07
08
09
10
NSPredicate *predicate = nil;
      
if ([[plot identifier] isEqual:@»studentEnrollment»])
{
    predicate = [NSPredicate predicateWithFormat:@»dayEnrolled == %d», index];
}
else if ([[plot identifier] isEqual:@»csEnrollement»])
{
    predicate = [NSPredicate predicateWithFormat:@»dayEnrolled == %d AND subjectID == %d», index, 0];
}

Это создает предикат, основанный на том, какой график строится, и получает соответствующий счетчик. Наконец, нам нужно установить символы для графа предмета на зеленый:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
— (CPTPlotSymbol *)symbolForScatterPlot:(CPTScatterPlot *)aPlot recordIndex:(NSUInteger)index
{
    CPTPlotSymbol *plotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
    [plotSymbol setSize:CGSizeMake(10, 10)];
      
    if ([[aPlot identifier] isEqual:@»studentEnrollment»])
    {
        [plotSymbol setFill:[CPTFill fillWithColor:[CPTColor blueColor]]];
    }
    else if ([[aPlot identifier] isEqual:@»csEnrollement»])
    {
        [plotSymbol setFill:[CPTFill fillWithColor:[CPTColor greenColor]]];
    }
      
    [plotSymbol setLineStyle:nil];
    [aPlot setPlotSymbol:plotSymbol];
          
    return plotSymbol;
}

Опять же, вышесказанное должно быть само за себя. Мы смотрим на идентификатор графика и, основываясь на том, что это за график, делаем символ графика зеленым или синим.

Теперь сохраните и запустите график, и у вас должно получиться что-то вроде следующего:


И вот оно! Полностью рабочий график, который показывает зачисление студентов с течением времени, а также зачисление в информатику. Как видите, добавить второй график довольно просто, если вы настроили начальный график. Попробуйте добавить больше учеников в приложение и информатику и посмотрите обновление графика.


Мы сегодня немного поработали. Мы установили, как стилизовать наши графики, изменив цвет линий и ширину, а также добавив градиентные заливки. Мы также обрисовали в общих чертах, как вы можете добавлять и управлять несколькими графиками на одном графическом объекте.

В следующий раз мы сосредоточимся на том, как создать и настроить гистограмму, которая показывает общее количество студентов, зачисленных по каждому предмету (каждый предмет будет иметь отдельную полосу). Увидимся в следующий раз!