Зауважте: коли React-додатку потрібно візуалізувати десятки тисяч точок даних, вибір бібліотеки для графіків стає критичним. D3.js дає повний контроль, але вимагає написання сотень рядків коду. Chart.js і Recharts простіші, але обмежені в кастомізації. Nivo — золота середина: компонентний підхід React, підтримка SVG і Canvas, десятки готових типів графіків, які можна кастомізувати під будь-яке завдання. Наші інженери використовують Nivo в продакшені понад 5 років, реалізували 50+ проєктів з візуалізаціями даних для фінтеху, e-commerce та аналітики. Економія на розробці візуалізації становить до 30% порівняно з D3, а час інтеграції скорочується в 2-3 рази. Джерело: офіційна документація Nivo
Типова проблема — неправильний формат даних. Nivo очікує масив об'єктів з полями id і data. Помилка hydration mismatch при SSR виникає, коли дані на клієнті та сервері відрізняються. Nivo коректно рендериться на сервері за умови, що дані передаються однаково. Ми гарантуємо стабільну роботу на всіх етапах.
Чому Nivo кращий за D3 для React-додатків?
D3 — низькорівнева робота з DOM, а Nivo — готові React-компоненти. При використанні D3 потрібно самостійно керувати життєвим циклом, оновленнями та знищенням графіків. Nivo бере це на себе: при зміні даних достатньо передати нові пропси, і компонент перемалюється з анімацією. D3 вимагає ручного виклику update та exit. Nivo також рендериться на сервері (SSR) за допомогою React, тоді як D3 зазвичай працює тільки на клієнті. Це критично для SEO та LCP. Крім того, Nivo дозволяє легко перемикатися між SVG і Canvas: для великих даних (10 000+ точок) використовуйте Canvas — продуктивність 60 fps проти 30 fps у D3.
Як підвищити продуктивність графіків?
При роботі з великими датасетами (понад 5000 точок) рекомендуємо:
- Використовувати
useCanvasзамість SVG. - Мемоізувати дані за допомогою
React.memoабоuseMemo. - Обмежити кількість точок на екрані через агрегацію.
- Налаштувати
motionConfigдля відключення анімацій.
Ці техніки прискорюють відмальовку в 2-3 рази та зменшують навантаження на CPU.
Порівняння Nivo з D3
| Характеристика | Nivo | D3.js |
|---|---|---|
| Рівень абстракції | Високий (React-компоненти) | Низький (DOM + SVG) |
| Час розробки типового графіка | 1-2 дні | 3-5 днів |
| Підтримка SSR | Так (з коробки) | Ні (потрібен custom) |
| Продуктивність на 10k точок | 60 fps (Canvas) | 30-40 fps |
| Обсяг коду для кастомного тултіпа | 5-10 рядків | 30+ рядків |
| Характеристика | Nivo | Recharts | Chart.js |
|---|---|---|---|
| Тип рендерингу | SVG/Canvas | SVG | Canvas |
| Кастомізація тултіпів | Повна (React компоненти) | Обмежена | Обмежена |
| Підтримка SSR | Так | Так | Ні |
| Продуктивність (10k точок) | 60fps (Canvas) | 30fps | 45fps |
| Типи графіків | 20+ | 8 | 8 |
При розробці ми враховуємо адаптивність: графіки автоматично підлаштовуються під розмір контейнера через Responsive-компоненти Nivo. Це особливо важливо для дашбордів, які переглядають на різних пристроях. Ми також налаштовуємо тултіпи так, щоб вони коректно відображалися на мобільних екранах.
Що входить в роботу
- Вихідний код компонентів графіків з кастомними тултіпами.
- Документація щодо формату даних і пропсів.
- Інтеграція з існуючим API.
- Адаптивність під мобільні пристрої.
- Навчання команди (до 1 години).
- Гарантія 3 місяці.
Типові помилки та як їх уникнути
- Неправильна структура даних: перевір, що масив містить об'єкти з
id(рядок) таdata(масив точок). - Відсутність ключів при мапінгу: використовуй
React.memoта унікальний key. - Ігнорування responsive: обгорни в контейнер з фіксованою висотою (
min-height). - Забув про
useMesh: без нього тултіпи не працюють. - Не встановлені залежності:
@nivo/coreобов'язковий.
Процес роботи
- Аналіз даних та вимог до візуалізації.
- Вибір типів графіків та прототипування.
- Налаштування бекенду для віддачі даних у потрібному форматі.
- Інтеграція Nivo компонентів, кастомізація тултіпів, легенд.
- Оптимізація продуктивності (мемоізація, Canvas для великих даних).
- Тестування на мобільних пристроях та різних екранах.
- Деплой та моніторинг.
Строки
Від 3 до 10 днів залежно від складності. Вартість розраховується індивідуально.
Приклади коду (розгорнути)
Встановлення
npm install @nivo/line @nivo/bar @nivo/pie @nivo/heatmap @nivo/core
Line Chart
import { ResponsiveLine } from '@nivo/line';
function NivoLineChart({ data }) {
// Nivo очікує формат: [{ id: 'series', data: [{ x, y }] }]
const nivoData = [
{
id: 'Виручка',
color: '#3b82f6',
data: data.map(d => ({ x: d.date, y: d.revenue }))
},
{
id: 'Ціль',
color: '#f59e0b',
data: data.map(d => ({ x: d.date, y: d.target }))
}
];
return (
<div style={{ height: 350 }}>
<ResponsiveLine
data={nivoData}
margin={{ top: 20, right: 120, bottom: 50, left: 70 }}
xScale={{ type: 'time', format: '%Y-%m-%d', precision: 'day' }}
xFormat="time:%d.%m.%Y"
yScale={{ type: 'linear', stacked: false }}
yFormat=" >-.0f"
curve="monotoneX"
axisLeft={{
format: v => `${(v / 1000).toFixed(0)}k`,
legend: 'Виручка (₽)',
legendOffset: -60,
legendPosition: 'middle'
}}
axisBottom={{
format: '%d %b',
tickValues: 'every 2 weeks'
}}
colors={{ scheme: 'paired' }}
lineWidth={2}
pointSize={4}
enableArea
areaOpacity={0.1}
useMesh
legends={[{
anchor: 'bottom-right',
direction: 'column',
itemWidth: 100,
itemHeight: 20
}]}
tooltip={({ point }) => (
<div className="chart-tooltip">
<strong>{point.data.xFormatted}</strong>
<br />
{point.serieId}: {Number(point.data.y).toLocaleString('uk')} ₴
</div>
)}
/>
</div>
);
}
Bar Chart з кастомними кольорами за значенням
import { ResponsiveBar } from '@nivo/bar';
function ConversionBarChart({ data }) {
return (
<div style={{ height: 300 }}>
<ResponsiveBar
data={data}
keys={['conversion']}
indexBy="page"
margin={{ top: 10, right: 20, bottom: 60, left: 60 }}
padding={0.4}
valueScale={{ type: 'linear' }}
colors={({ data }) => {
if (data.conversion >= 5) return '#22c55e';
if (data.conversion >= 2) return '#f59e0b';
return '#ef4444';
}}
axisBottom={{ tickRotation: -45 }}
axisLeft={{ format: v => `${v}%` }}
label={d => `${d.value}%`}
tooltip={({ data, value }) => (
<div className="chart-tooltip">
<strong>{data.page}</strong>: {value}% конверсія
</div>
)}
/>
</div>
);
}
Calendar Heatmap
import { ResponsiveCalendar } from '@nivo/calendar';
function ActivityCalendar({ data }) {
// data: [{ day: '2024-03-28', value: 42 }]
return (
<div style={{ height: 200 }}>
<ResponsiveCalendar
data={data}
from="2024-01-01"
to="2024-12-31"
emptyColor="#f3f4f6"
colors={['#dbeafe', '#93c5fd', '#3b82f6', '#1d4ed8']}
margin={{ top: 20, right: 20, bottom: 20, left: 20 }}
yearSpacing={40}
monthBorderColor="#ffffff"
dayBorderWidth={2}
dayBorderColor="#ffffff"
tooltip={({ day, value }) => (
<div className="chart-tooltip">{day}: {value} подій</div>
)}
/>
</div>
);
}
Замовте розробку під ключ — отримайте консультацію та прототип за 2 дні. Зв'яжіться з нами, щоб обговорити ваш проєкт. Наші інженери з досвідом 5+ років допоможуть реалізувати візуалізацію даних будь-якої складності.







