Skip to content

About

Vue 3 + AG Grid Enterprise Tree Data implementation with a highly performant TreeStore

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

10 Commits

Folders and files

Repository files navigation

Vue 3 + AG Grid TreeStore

Vue 3 TypeScript AG Grid Vite Vitest

Иерархическая таблица на базе Vue 3, TypeScript и AG Grid Enterprise (Tree Data).

Запуск

npm install
npm run dev

Тестирование:

npm test          # Unit и компонентные тесты
npm run test:perf # Замеры производительности

Структура

  • src/domain/TreeStore.ts - хранилище дерева.
  • src/composables/useTreeGrid.ts - слой реактивности. Выполняет загрузку JSON, формирует пути для дерева и передает данные в компонент.
  • src/components/TreeGrid.vue - настройка и рендеринг AG Grid.
  • public/items.json - данные, имитирующие ответ сервера.
  • tests/ - тесты хранилища, компонентов и производительности.

Архитектура TreeStore

Требование ТЗ о "минимальном количестве обходов массива" напрямую влияет на выбор структур данных. Если использовать обычные массивы, каждая операция поиска, получения детей или родителей будет требовать перебора всех элементов (сложность O(N)).

Для обеспечения O(1) при чтении в TreeStore при инициализации (setItems) строятся индексы за один проход по массиву. Используются четыре Map:

  1. byId - для мгновенного поиска элемента.
  2. parentById - для построения цепочки родителей.
  3. childrenByParentId - вложенные Map для хранения детей. Сохраняют insertion order, что соответствует порядку в исходном массиве.
  4. indexById - для точечного обновления элемента в исходном массиве без повторного поиска.

Мутации (addItem, removeItem, updateItem) обновляют индексы инкрементально, не пересчитывая структуру с нуля.

AG Grid требует от строки массив путей (path) от корня до узла. Метод getAllParents за счет parentById строит этот путь за O(depth), избегая рекурсивного перебора всего дерева.

Реализация UI (AG Grid)

  • Колонка дерева: Текст "Группа/Элемент" и иконки разворачивания выводятся в колонке "Категория" через innerRenderer в autoGroupColumnDef.
  • Нумерация: Колонка "№ п/п" использует params.node.rowIndex + 1. Это обеспечивает динамическую нумерацию видимых строк: при сворачивании групп номера пересчитываются, не оставляя пустот.
  • Загрузка данных: Состояние загрузки управляется через проп :loading="loading". Дерево разворачивается автоматически при поступлении данных благодаря :group-default-expanded="-1".

Производительность

Тесты (tests/performance.spec.ts) генерируют дерево из 50 000 элементов и замеряют время операций.

Метрики (Node.js 20):

  • Построение индексов (setItems): ~23 мс
  • 2000 операций чтения: ~1.1 мс

Лимиты в тестах (100 мс на запись, 20 мс на чтение) заданы с запасом на слабое железо. При этом они отсекают любые попытки заменить Map на линейный поиск - деградация до O(N) мгновенно превысит эти пороги на 50 000 элементах.

Краевые случаи

  • Порядок детей: Соответствует порядку в исходном массиве.
  • getAllChildren: Возвращает узлы в порядке DFS (pre-order), не включая сам родительский элемент.
  • getAllParents: Возвращает цепочку от текущего элемента до корня (включая сам элемент).
  • Отсутствие ID: getItem возвращает undefined, методы получения списков - [], мутации игнорируются (no-op).
  • Отсутствие label: В качестве наименования выводится String(id).
  • Смена родителя: Элемент перемещается в конец списка детей нового родителя. Встроена защита от создания циклов (попытка сделать элемент потомком самого себя игнорируется).

About

Vue 3 + AG Grid Enterprise Tree Data implementation with a highly performant TreeStore

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages