Графіки в мобільному додатку часто гальмують на 1000 точках? Дотики не чутливі, анімації смикані — знайома біль. Вибір правильної бібліотеки графіків для Flutter, iOS чи Android — ключ до продуктивності. Ми допоможемо оптимізувати діаграми в додатку без зайвих витрат. Наш досвід — 5+ років у мобільній розробці, сертифіковані розробники Flutter та iOS, понад 50 проектів з графікою — дозволяє уникнути цих помилок. Економія часу на оптимізацію сягає 50% (наприклад, 2 дні замість 4). Зв'яжіться з нами, щоб обговорити ваш проект.
Чому вибір бібліотеки — ключове рішення?
Питання «яку бібліотеку взяти» вирішується через вимоги конкретного проекту. Неправильний вибір веде до переробок і гальм.
| Критерій | fl_chart | syncfusion_flutter | MPAndroidChart | DGCharts (iOS) | react-native-chart-kit |
|---|---|---|---|---|---|
| Типи графіків | Line, Bar, Pie, Scatter, Radar | 30+ типів | 8 основних | 10+ типів | Line, Bar, Pie, Progress |
| Zoom/Pan | Немає (потрібен кастом) | Так | Так | Так | Немає |
| Candlestick | Немає | Так | Так | Так | Немає |
| Ліцензія | MIT | Комерційна | Apache 2.0 | Apache 2.0 | MIT |
| Продуктивність при >1000 точок | Знижується | Хороша | Хороша | Хороша | Помірна |
Для фінансових додатків з candlestick і zoom — syncfusion або нативний. Для health/fitness з простими лінійними графіками — fl_chart достатньо. Для React Native використовуйте react-native-chart-kit з простими графіками. Для real-time даних з високою частотою оновлення — WebView + ECharts.
Що таке downsampling і чому він критичний?
Downsampling — зменшення кількості точок даних перед рендерингом. Алгоритм LTTB зберігає візуальну форму кривої, відкидаючи надлишкові точки. Це дає економію часу до 90% порівняно з повним рендерингом. LTTB в 5 разів краще зберігає форму кривої, ніж випадковий downsampling. Без downsampling графіки з 10 000 точок на mid-range Android падають до 15 FPS.
Як оптимізувати LineChart без втрати якості?
Типова помилка — передавати в fl_chart весь масив з 5000 точок. LineChart рендерить кожну точку як FlSpot, і при touchData увімкненому — прораховує hit-testing для кожного. На mid-range Android — FPS падає нижче 20.
Правильно: downsampling перед рендерингом. LTTB в 10 разів швидший за повний рендеринг і дає візуально ідентичний результат для більшості сценаріїв.
На одному проекті з фінансовим додатком ми оптимізували графік candlestick з 10 000 точок до 500 за допомогою LTTB, що знизило середній час рендерингу з 8 с до 1.2 с.
Приклад реалізації LTTB на Flutter
List<FlSpot> lttbDownsample(List<FlSpot> data, int threshold) {
if (data.length <= threshold) return data;
final sampled = <FlSpot>[data.first];
final bucketSize = (data.length - 2) / (threshold - 2);
var a = 0;
for (var i = 0; i < threshold - 2; i++) {
final rangeStart = (i * bucketSize + 1).floor();
final rangeEnd = ((i + 1) * bucketSize + 1).floor().clamp(0, data.length);
final nextA = ((i + 1) * bucketSize + 1).floor().clamp(0, data.length - 1);
double maxArea = -1;
int maxAreaPoint = rangeStart;
for (var j = rangeStart; j < rangeEnd; j++) {
final area = (data[a].x * (data[nextA].y - data[j].y) +
data[nextA].x * (data[j].y - data[a].y) +
data[j].x * (data[a].y - data[nextA].y))
.abs() / 2;
if (area > maxArea) {
maxArea = area;
maxAreaPoint = j;
}
}
sampled.add(data[maxAreaPoint]);
a = maxAreaPoint;
}
sampled.add(data.last);
return sampled;
}
500 точок замість 5000 — FPS повертається до 60. LTTB дає скорочення часу рендерингу в 10 разів порівняно з повним набором.
Порівняння методів downsampling
| Метод | Швидкість | Збереження форми | Застосування |
|---|---|---|---|
| LTTB | Середня | Відмінне | Лінійні графіки |
| Douglas-Peucker | Висока | Добре | Полігони, геодані |
| Random | Дуже висока | Погане | Швидке прототипування |
Для мобільних графіків LTTB — оптимальний баланс.
Руководство з впровадження downsampling за 3 кроки
- Виберіть алгоритм LTTB — він дає найкраще співвідношення швидкості та якості для лінійних графіків.
- Підготуйте дані — відфільтруйте null і NaN, приведіть до набору FlSpot.
- Інтегруйте в LineChart — замініть вихідний масив на результат lttbDownsample перед передачею в LineChartData.
Анімації при появі даних
Анімація лінії, що «малюється» зліва направо — популярний UX-паттерн. На Flutter через AnimationController + TweenAnimationBuilder, обмежуючи кількість відображуваних точок через t:
TweenAnimationBuilder<double>(
tween: Tween(begin: 0.0, end: 1.0),
duration: const Duration(milliseconds: 800),
curve: Curves.easeOut,
builder: (context, value, _) {
final visiblePoints = (allSpots.length * value).round();
return LineChart(
LineChartData(
lineBarsData: [
LineChartBarData(spots: allSpots.take(visiblePoints).toList()),
],
),
);
},
)
Для bar chart — анімація зростання стовпців через fromY параметр і AnimatedContainer.
Як реалізувати real-time оновлення без втрати FPS?
Графіки з оновленням щосекунди (метрики, біржові дані) вимагають setState тільки для змінених даних. Неправильно викликати setState на весь екран — перебудовується все дерево віджетів. Правильно: ValueNotifier + ValueListenableBuilder навколо тільки віджета графіка.
- Визначте максимальну кількість відображуваних точок (ковзне вікно).
- Використовуйте ValueNotifier для зберігання списку точок.
- Оновлюйте ValueNotifier при надходженні нових даних.
final chartData = ValueNotifier<List<FlSpot>>([]);
// У віджеті:
ValueListenableBuilder<List<FlSpot>>(
valueListenable: chartData,
builder: (_, spots, __) => LineChart(LineChartData(
lineBarsData: [LineChartBarData(spots: spots)],
)),
)
// При отриманні нової точки:
void addDataPoint(double x, double y) {
final current = [...chartData.value, FlSpot(x, y)];
if (current.length > maxPoints) current.removeAt(0); // sliding window
chartData.value = current;
}
Як зробити графіки доступними?
Графіки недоступні для VoiceOver / TalkBack без додаткової роботи. Мінімум: Semantics віджет з описом того, що показує графік. Для фінансових або медичних додатків — обов'язкова таблична альтернатива даних графіка, перемикається через кнопку. Це відповідає WCAG 2.1 і App Store Review Guidelines (Section 5.1).
Що входить в роботу
- Вибір бібліотеки під вимоги проекту з обґрунтуванням
- Реалізація потрібних типів графіків (line, bar, pie, candlestick тощо)
- Оптимізація продуктивності (downsampling, рендеринг)
- Анімації при завантаженні даних
- Інтерактивність: zoom, pan, tooltip при дотику
- Accessibility підтримка
- Інтеграція з real-time джерелами даних
- Гарантія якості: 30-денна підтримка після здачі та безкоштовне виправлення помилок
Строки та вартість
Один тип графіка з базовою інтерактивністю: 2–3 дні. Набір з 3–5 типів з анімаціями та real-time оновленнями: 1–2 тижні. Вартість одного типу графіка з базовою інтерактивністю становить від $500. Економія часу на оптимізацію сягає 50% (наприклад, 2 дні замість 4). Замовте реалізацію під ключ: отримайте консультацію з вибору бібліотеки та оптимізації. Наші інженери допоможуть зекономити час і бюджет.







