Waffle chart в Nivo опирается на дискретное распределение значений, которое преобразуется в сетку одинаковых ячеек. Каждая ячейка представляет фиксированную долю от общего значения, а входные данные задают относительные веса категорий.
Ключевая особенность формата заключается в том, что исходные данные не требуют нормализации: библиотека самостоятельно вычисляет пропорции на основе суммы значений.
Основной формат представляет собой массив объектов:
const data = [
{ id: 'A', label: 'Category A', value: 40 },
{ id: 'B', label: 'Category B', value: 25 },
{ id: 'C', label: 'Category C', value: 15 },
{ id: 'D', label: 'Category D', value: 20 }
]
id
value
label
Waffle chart преобразует одномерный массив значений в двумерную матрицу фиксированного размера.
Параметры:
Пример конфигурации:
const total = 100
const rows = 10
const columns = 10
Каждая категория получает количество ячеек пропорционально своему значению.
Формула распределения:
value = SПри преобразовании значений в ячейки возникает необходимость округления.
const data = [
{ id: 'A', value: 33 },
{ id: 'B', value: 33 },
{ id: 'C', value: 34 }
]
При total = 100 каждая категория должна получить 33.33 / 33.33 / 33.34 ячеек, что невозможно без округления.
floor-распределение
proportional fill
Помимо базового массива объектов, Waffle поддерживает расширенные структуры с дополнительными параметрами визуализации.
const data = [
{
id: 'react',
label: 'React',
value: 50,
color: '#61dafb'
},
{
id: 'vue',
label: 'Vue',
value: 30,
color: '#42b883'
},
{
id: 'svelte',
label: 'Svelte',
value: 20,
color: '#ff3e00'
}
]
color
data
{
id: 'A',
value: 40,
data: {
description: 'Frontend usage',
region: 'Europe'
}
}
Если поле color не задано, используется цветовая схема
Nivo.
Варианты поведения:
nivo palette)idПример:
<ResponsiveWaffle
data={data}
colors={{ scheme: 'set3' }}
/>
При наличии color в данных:
{
id: 'A',
value: 40,
color: 'hsl(210, 70%, 50%)'
}
цветовая схема игнорируется для данного элемента.
В некоторых конфигурациях используется концепция слоёв (layers), где каждая категория может иметь подкатегории.
const data = [
{
id: 'frontend',
value: 70,
sub: [
{ id: 'react', value: 40 },
{ id: 'vue', value: 30 }
]
},
{
id: 'backend',
value: 30,
sub: [
{ id: 'node', value: 20 },
{ id: 'go', value: 10 }
]
}
]
В таком формате:
Waffle chart чувствителен к изменениям входного массива.
Изменение структуры данных может происходить:
Пример динамического обновления:
const [data, setData] = useState(initialData)
useEffect(() => {
const updated = initialData.map(d => ({
...d,
value: d.value * Math.random()
}))
setData(updated)
}, [])
При изменении данных происходит полная перерасчёт сетки.
Категория исключается из визуального распределения, но может сохраняться в легенде при соответствующей настройке.
{ id: 'A', value: 0 }
{ id: 'B' }
Параметр total не изменяет входные данные, но влияет на
плотность визуализации.
total = 100
total = 25
При этом распределение пропорций остаётся неизменным.
Legend и tooltip используют те же поля id,
label, value.
Пример структуры tooltip:
{
id: 'react',
label: 'React',
value: 50,
formattedValue: '50%'
}
Если label отсутствует, используется
id.
Часто данные поступают из API в несогласованной форме:
[
{ "name": "A", "count": 10 },
{ "name": "B", "count": 20 }
]
Преобразование:
const formatted = apiData.map(item => ({
id: item.name,
label: item.name,
value: item.count
}))
{ id: 'A', value: '40' } // строка вместо числа
Последствия:
{ id: 'A', value: 10 }
{ id: 'A', value: 20 }
Последствия:
{ id: 'A', value: -10 }
Для тестирования часто применяются генераторы:
const generateData = (n) =>
Array.from({ length: n }).map((_, i) => ({
id: `cat-${i}`,
label: `Category ${i}`,
value: Math.floor(Math.random() * 100)
}))
Такие данные позволяют оценивать поведение распределения при изменяющихся значениях.
При большом количестве категорий (>20) возникает проблема читаемости.
Рекомендуемые подходы:
const processed = data
.filter(d => d.value > 0)
.sort((a, b) => b.value - a.value)
Формат данных напрямую влияет на:
Каждая ячейка наследует:
что позволяет строить интерактивную модель поверх статической сетки.