Реализация графиков и визуализации IoT-данных (температура, влажность, давление)

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Реализация графиков и визуализации IoT-данных (температура, влажность, давление)
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    760
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    646
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1056
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    878
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    450

Реализация графиков и визуализации IoT-данных (температура, влажность, давление)

Отобразить линию температуры за неделю просто. Проблемы начинаются когда данных 50 000 точек, пользователь зумирует до диапазона в 10 минут, и при этом граф должен прокручиваться плавно на бюджетном Android-устройстве. Неправильный выбор библиотеки или наивная реализация даёт 3–4 FPS на скролл и OOM при попытке отрендерить всё сразу.

Выбор библиотеки для графиков

На Android — три реальных варианта:

Библиотека Производительность Кастомизация Особенности
MPAndroidChart Хорошая до ~5к точек Средняя Mature, XML+Compose wrapper
Vico Отличная, Compose-first Хорошая Нативный Compose, активная разработка
Charts (Compose) Хорошая Базовая Простые кейсы

Для IoT с большим объёмом данных и зумом — Vico на Compose или MPAndroidChart с LineDataSet.setDrawCircles(false) + setMode(CUBIC_BEZIER) выключенным (сплайн = дорого на больших наборах).

На iOS — Charts (fork MPAndroidChart для Swift) или DGCharts. Нативный Swift Charts (iOS 16+) — простой API, хорошая производительность, но ограниченная кастомизация.

Downsampling: ключ к производительности

50 000 точек за месяц — на экране шириной 400dp поместится максимум 400 точек. Отображать все 50 000 — пустая работа GPU.

LTTB (Largest-Triangle-Three-Buckets) — алгоритм прореживания данных с сохранением визуального профиля. На Android:

fun lttbDownsample(data: List<DataPoint>, threshold: Int): List<DataPoint> {
    if (data.size <= threshold) return data
    val sampled = mutableListOf<DataPoint>()
    sampled.add(data.first())

    val bucketSize = (data.size - 2).toDouble() / (threshold - 2)
    var a = 0

    for (i in 0 until threshold - 2) {
        val bucketStart = ((i + 1) * bucketSize).toInt() + 1
        val bucketEnd = minOf(((i + 2) * bucketSize).toInt() + 1, data.size - 1)
        val nextA = bucketStart until bucketEnd

        val avgX = nextA.sumOf { data[it].x } / nextA.count()
        val avgY = nextA.sumOf { data[it].y } / nextA.count()

        var maxArea = -1.0
        var maxPoint = bucketStart

        for (j in bucketStart until bucketEnd) {
            val area = Math.abs(
                (data[a].x - avgX) * (data[j].y - data[a].y) -
                (data[a].x - data[j].x) * (avgY - data[a].y)
            ) * 0.5
            if (area > maxArea) { maxArea = area; maxPoint = j }
        }

        sampled.add(data[maxPoint])
        a = maxPoint
    }

    sampled.add(data.last())
    return sampled
}

При зуме до короткого диапазона — загружать исходные данные с сервера для этого периода без downsampling. Ширина диапазона < 1 часа → запрос данных с оригинальным разрешением.

Зум и скролл

Жест pinch-to-zoom для графика — через ScaleGestureDetector (Android) или MagnificationGesture / onMagnification modifier. При изменении диапазона — запрос новых данных с сервера.

Паттерн «бесконечный скролл» для временных серий: при скролле к краю загруженных данных — подгрузить следующий период. Paging 3 для этого использовать нельзя напрямую (он не для временных серий), но принцип тот же: prefetchDistance — загружать данные когда до края осталось N единиц времени.

Несколько параметров на одном графике

Температура + влажность на одной оси — плохо: разные единицы и диапазоны. Правильно — две оси Y (MPAndroidChart поддерживает через axisLeft / axisRight) или два отдельных синхронизированных графика с общей осью X.

При синхронизированном скролле двух графиков — добавить OnChartGestureListener к каждому и при скролле одного программно скроллить второй:

chart1.onChartGestureListener = object : OnChartGestureListener {
    override fun onChartTranslate(me: MotionEvent?, dX: Float, dY: Float) {
        chart2.viewPortHandler.setTranslation(chart1.viewPortHandler.transX, 0f)
        chart2.invalidate()
    }
    // другие методы интерфейса...
}

Аннотации и события на графике

Точки аномалий, пороговые линии, события (открытие двери, перезагрузка устройства) — важны для анализа. LimitLine в MPAndroidChart для горизонтальных порогов. Точечные аннотации — кастомный MarkerView или VerticalHighlight с иконкой.

Цветовые диапазоны

Для температуры: зелёный (норма) → жёлтый (предупреждение) → красный (критично). LinearGradient по Y-оси в Compose Canvas или GradientColor в MPAndroidChart. Визуально сразу понятно без легенды, где проблемный период.

Реализация графиков IoT-данных с зумом, downsampling и аннотациями: 3–5 недель. Стоимость зависит от числа параметров, источников данных и требований к кастомизации.