Gridstack.js предоставляет мощный инструмент для построения динамических сеток с поддержкой drag-and-drop и адаптивного расположения виджетов. Одной из ключевых возможностей библиотеки является интеграция сторонних компонентов, таких как графики, карты или сложные интерактивные элементы, сохраняя при этом контроль над поведением сетки.
Gridstack.js оперирует «виджетами» (widgets), каждый
из которых представляет собой DOM-элемент с определёнными атрибутами
gs-x, gs-y, gs-w,
gs-h. Для корректной интеграции стороннего компонента
необходимо:
grid-stack-item.grid-stack-item-content.Пример структуры:
<div class="grid-stack-item" gs-x="0" gs-y="0" gs-w="4" gs-h="2">
<div class="grid-stack-item-content">
<canvas id="chart1"></canvas>
</div>
</div>
Для интеграции графических библиотек, таких как Chart.js, D3.js или Highcharts, важно инициализировать их после того, как Gridstack завершил рендеринг виджета. Это предотвращает ошибки с размерами контейнера.
const grid = GridStack.init();
grid.on('added', function(event, items) {
items.forEach(item => {
const canvas = item.el.querySelector('canvas');
if(canvas) {
new Chart(canvas, {
type: 'line',
data: { /* данные графика */ },
options: { responsive: true }
});
}
});
});
Ключевой момент: использование событий
added, change и resize позволяет
поддерживать корректное отображение компонента при изменении размеров
или перемещении виджета.
Сторонние компоненты часто требуют точного контроля размеров.
Gridstack.js предоставляет событие resize:
grid.on('resize', function(event, el) {
const canvas = el.querySelector('canvas');
if(canvas && canvas.chart) {
canvas.chart.resize();
}
});
Совет: хранить экземпляр компонента как свойство
DOM-элемента (canvas.chart = chartInstance) для быстрого
доступа при событиях сетки.
Для карт (например, Leaflet или Google Maps) или редакторов кода важно правильно инициализировать компонент только один раз, избегая повторной инициализации при перемещении или ресайзе. Стратегия следующая:
Пример с Leaflet:
grid.on('added', function(event, items) {
items.forEach(item => {
const mapContainer = item.el.querySelector('.map');
if(mapContainer && !mapContainer._leafletMap) {
mapContainer._leafletMap = L.map(mapContainer).setView([51.505, -0.09], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(mapContainer._leafletMap);
}
});
});
grid.on('resize', function(event, el) {
const mapContainer = el.querySelector('.map');
if(mapContainer && mapContainer._leafletMap) {
mapContainer._leafletMap.invalidateSize();
}
});
Gridstack.js не ограничивает возможность обновления содержимого виджетов в реальном времени. Для динамических графиков или таблиц:
Пример для динамического графика:
function updateChart(chartInstance, newData) {
chartInstance.data.datasets[0].data = newData;
chartInstance.update();
}
destroy или аналогичные у стороннего
компонента.Gridstack.js сохраняет совместимость с внешними компонентами при перетаскивании и ресайзе, если:
gs-*.resize и change.grid-stack-item-content.Пример автоматической адаптации всех графиков при изменении сетки:
grid.on('change', function(event, items) {
items.forEach(item => {
const canvas = item.el.querySelector('canvas');
if(canvas && canvas.chart) {
canvas.chart.resize();
}
});
});
Интеграция сторонних компонентов с Gridstack.js обеспечивает возможность создавать сложные, интерактивные и динамически изменяемые панели, сохраняя удобство управления сеткой и адаптивность интерфейса. Контроль и правильная инициализация каждого виджета позволяет добиться высокой производительности и устойчивости интерфейса.