Site icon AppTractor

Создаем гистограмму с помощью Swift Charts

На WWDC 22 Apple представила Swift Charts, фреймворк, позволяющий визуализировать данные в виде гистограмм. До его появления нам приходилось подключать всевозможные сторонние решения для построения графиков в SwiftUI. Визуализация данных с помощью аналогичного декларативного синтаксиса в SwiftUI — это просто фантастика.

Гистограмма — это всего лишь один из доступных вариантов визуализации данных. В целом, многие из методов, о которых вы сегодня узнаете, применимы и к другим графикам. Фактически, вы можете заменить всего один элемент, чтобы перейти от гистограммы к линейной диаграмме. Давайте погрузимся в работу!

Настройка данных диаграммы

Прежде чем приступить к созданию графика, важно иметь данные для работы. В этой статье я буду использовать данные о сборках, которые я использую в RocketSim:

/// Describes an Xcode build activity on a certain data, for a given duration.
struct BuildActivity: Identifiable, Codable {
    var id: TimeInterval { date.timeIntervalSince1970 }
    let date: Date
    let scheme: String
    let numberOfBuilds: Int
}

При запуске нового графика я рекомендую создать образец данных для работы. Вы можете использовать эти данные как в работающем приложении, так и в превью SwiftUI:

extension BuildActivity {
    static func sampleData() -> [BuildActivity] {
        [
            sampleData(for: "RocketSim"),
            sampleData(for: "Stock Analyzer")
        ].flatMap { $0 }
    }
    
    private static func sampleData(for scheme: String) -> [BuildActivity] {
        (0...365).map { index -> BuildActivity in
            /// Create a random number of builds. Some days will not have any builds
            let numberOfBuilds = Int.random(in: 0...100)
            
            /// Using the index, we're creating a full year of data
            let date = Calendar.current.date(byAdding: .day, value: -index, to: .now)!
            
            return BuildActivity(
                date: date,
                scheme: scheme,
                numberOfBuilds: numberOfBuilds
            )
        }
    }
}

Эти статические методы позволяют создать коллекцию активностей сборок для двух разных схем. Этот набор данных отлично подходит для визуализации гистограммы в этой статье.

Создание базовой гистограммы

Мы можем использовать наши данные для создания базовой гистограммы с помощью Swift Charts в SwiftUI:

Базовый пример гистограммы с использованием Swift Charts в SwiftUI.

Код для этой диаграммы выглядит следующим образом:

import SwiftUI
import Charts

struct BarChart: View {
    
    let buildActivities: [BuildActivity]

    var body: some View {
        Chart(buildActivities) { buildActivity in
            BarMark(
                x: .value("Date", buildActivity.date, unit: .day),
                y: .value("Total Count", buildActivity.numberOfBuilds)
            )
        }
    }
}

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

Значения x и y определяют, как будут визуализированы данные. Мы установили единицу измерения даты в .day, поскольку хотим показывать данные за каждый день. Вы можете изменить это значение, чтобы управлять временным периодом данных.

Управление диапазоном данных на диаграмме

Хотя базовая гистограмма и так выглядит отлично, она не очень удобна при отображении данных за целый год. Возможно, вам захочется увеличить масштаб данных за одну неделю. Это можно сделать двумя способами, каждый из которых дает разные результаты.

Первый способ — использовать модификатор chartXScale:

/// Chart X scale zoom in, but data is visible out of bounds
.chartXScale(
    domain: startDate...Date.now,
    range: .plotDimension(startPadding: 10, endPadding: 10)
)

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

Модификатор x-scale позволяет изменять диапазон данных, отображаемых на графике Swift.

Хотя мы можем четко видеть данные только за последние 7 дней, это не совсем удовлетворительный результат. Столбики выходят за границы, а наши метки шкалы y становятся перекрытыми. Вы все еще можете использовать этот подход в качестве функции масштабирования в сочетании с модификатором chartScrollableAxes, но лучше настроить график только на те данные, которые вы хотите отобразить.

Другими словами, мы разделим наши данные так, чтобы они содержали данные только за семь дней:

BarChart(buildActivities: Array(BuildActivity.sampleData().prefix(7)))

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

Чтобы получить наилучшие результаты, указывайте только те данные, которые вы хотите отобразить в Swift Charts.

Как изменить цвет гистограммы?

Цвет гистограммы по умолчанию будет соответствовать цвету accent вашего приложения. Вы можете изменить цвет с помощью модификатора foreground стиля:

Chart(buildActivities) { buildActivity in
    BarMark(
        x: .value("Date", buildActivity.date, unit: .day),
        y: .value("Total Count", buildActivity.numberOfBuilds)
    )
    /// Change the color of bars to orange
    .foregroundStyle(Color.orange)
}

Как разделить гистограмму на группы?

Гистограммы позволяют разбивать данные на группы и визуализировать их по отдельности. Например, мы можем разделить нашу гистограмму по заданной схеме:

Вы можете сгруппировать гистограмму на основе заданного значения.

Вам необходимо указать конкретное значение, которое будет использоваться для разделения данных. Рекомендуется использовать определенную категорию, которая не приведет к образованию слишком большого количества различных групп. Код для нашего примера выглядит следующим образом:

Chart(buildActivities) { buildActivity in
    BarMark(
        x: .value("Date", buildActivity.date, unit: .day),
        y: .value("Total Count", buildActivity.numberOfBuilds)
    )
        /// Show a different color for each scheme
        .foregroundStyle(
            by: .value("Scheme", buildActivity.scheme)
        )
}

Swift Charts назначает цвет по умолчанию для каждой группы. Вы можете переопределить этот цвет, указав конкретный цвет для каждого идентификатора группы. В нашем случае мы указываем цвет для каждой заданной схемы:

Chart(buildActivities) { buildActivity in
    BarMark(
        x: .value("Date", buildActivity.date, unit: .day),
        y: .value("Total Count", buildActivity.numberOfBuilds)
    )
        /// Show a different color for each scheme
        .foregroundStyle(
            by: .value("Scheme", buildActivity.scheme)
        )
}
    /// Customize the colors for each scheme
    .chartForegroundStyleScale([
        "RocketSim" : .blue,
        "Stock Analyzer": .red
    ])

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

Chart(buildActivities) { buildActivity in
    BarMark(
        x: .value("Date", buildActivity.date, unit: .day),
        y: .value("Total Count", buildActivity.numberOfBuilds)
    )
        /// Show a different color for each scheme
        .foregroundStyle(
            by: .value("Scheme", buildActivity.scheme)
        )
        /// Show bars side by side
        .position(
            by: .value("Scheme", buildActivity.scheme),
            axis: .horizontal,
            span: .ratio(1)
        )
}
    /// Customize the colors for each scheme
    .chartForegroundStyleScale([
        "RocketSim" : .blue,
        "Stock Analyzer": .red
    ])

Значение axis определяет, будут ли столбики показаны друг над другом (вертикальные) или рядом друг с другом (горизонтальные). Span позволяет управлять шириной каждого отдельного столбика. Полученная гистограмма выглядит следующим образом:

Гистограммы, сгруппированные рядом друг с другом с использованием определенных цветов.

Заключение

Swift Charts позволяет просто визуализировать данные в виде гистограмм. Хотя в этой статье мы рассмотрели только основы, вы уже можете увидеть достойный результат. Вы можете настраивать цвет столбиков, группировать значения по определенным категориям и управлять диапазоном отображаемых данных.

Спасибо!

Источник

Exit mobile version