# Column Virtualization Plugin

> Improve performance for grids with many columns by only rendering visible columns.

The Column Virtualization plugin improves performance for grids with many columns.

## Installation

```ts
import '@toolbox-web/grid/features/column-virtualization';
```

## Basic Usage

#### TypeScript

```ts
import { queryGrid } from '@toolbox-web/grid';
import '@toolbox-web/grid/features/column-virtualization';

const grid = queryGrid('tbw-grid');
grid.gridConfig = {
  columns: generateManyColumns(100), // Your column generator
  fitMode: 'fixed', // Required for column virtualization
  features: { columnVirtualization: true },
};
grid.rows = data;
```

#### React

```tsx
import '@toolbox-web/grid-react/features/column-virtualization';
import { DataGrid } from '@toolbox-web/grid-react';

function WideGrid({ data }) {
  return (
    <DataGrid
      rows={data}
      columns={generateManyColumns(100)}
      fitMode="fixed"
      columnVirtualization
      style={{ height: '400px' }}
    />
  );
}
```

#### Vue

```html
<script setup>
import '@toolbox-web/grid-vue/features/column-virtualization';
import { TbwGrid } from '@toolbox-web/grid-vue';

const data = [{ col0: 'Row 1', col1: 'Value 1' }, { col0: 'Row 2', col1: 'Value 2' }];

const columns = Array.from({ length: 100 }, (_, i) => ({
  field: `col${i}`,
  header: `Column ${i + 1}`,
  width: 120,
}));
</script>

<template>
  <TbwGrid :rows="data" :columns="columns" fit-mode="fixed" column-virtualization style="height: 400px">
  </TbwGrid>
</template>
```

#### Angular

```typescript
// Feature import - enables the [columnVirtualization] input
import { GridColumnVirtualizationDirective } from '@toolbox-web/grid-angular/features/column-virtualization';
import { Component } from '@angular/core';
import { Grid } from '@toolbox-web/grid-angular';
import type { ColumnConfig } from '@toolbox-web/grid';

@Component({
  selector: 'app-wide-grid',
  imports: [Grid, GridColumnVirtualizationDirective],
  template: `
    <tbw-grid
      [rows]="rows"
      [columns]="columns"
      [columnVirtualization]="true"
      fitMode="fixed"
      style="height: 400px; display: block;">
    </tbw-grid>
  `,
})
export class WideGridComponent {
  rows = [...];
  columns: ColumnConfig[] = this.generateManyColumns(100);

  generateManyColumns(count: number): ColumnConfig[] {
    return Array.from({ length: count }, (_, i) => ({
      field: `col${i}`,
      header: `Column ${i + 1}`,
      width: 120,
    }));
  }
}
```

## Demos

### Default Column Virtualization

```ts
// ColumnVirtualizationDefaultDemo.astro
import '@toolbox-web/grid';
import { queryGrid } from '@toolbox-web/grid';
import '@toolbox-web/grid/features/column-virtualization';

const container = document.getElementById('column-virtualization-default-demo');
if (container) {
  const grid = queryGrid('tbw-grid', container)!;

  function generateColumns(count: number) {
    const columns = [{ field: 'id', header: 'ID', type: 'number' as const, width: 60 }];
    for (let i = 1; i < count; i++) {
      columns.push({ field: `col${i}`, header: `Column ${i}`, type: 'number' as const, width: 100 });
    }
    return columns;
  }

  function generateRows(rowCount: number, colCount: number) {
    const rows = [];
    for (let r = 0; r < rowCount; r++) {
      const row: Record<string, number> = { id: r + 1 };
      for (let c = 1; c < colCount; c++) {
        row[`col${c}`] = Math.floor(Math.random() * 1000);
      }
      rows.push(row);
    }
    return rows;
  }

  function rebuild(columnCount = 50, threshold = 30, overscan = 3, autoEnable = true) {
    const columns = generateColumns(columnCount);
    const rows = generateRows(100, columnCount);
    grid.gridConfig = {
      columns,
      fitMode: 'fixed',
      features: { columnVirtualization: { autoEnable, threshold, overscan } },
    };
    grid.rows = rows;
  }

  rebuild();

  container.addEventListener('control-change', ((e: CustomEvent) => {
    const v = e.detail.allValues;
    rebuild(v.columnCount as number, v.threshold as number, v.overscan as number, v.autoEnable as boolean);
  }) as EventListener);
}
```

Use the **Column Count** slider to add up to 1000 columns, and toggle **Auto Enable** to compare performance with and without virtualization.

## Configuration Options

| Option       | Type      | Default | Description                 |
| ------------ | --------- | ------- | --------------------------- |
| `autoEnable` | `boolean` | `true`  | Auto-enable above threshold |
| `threshold`  | `number`  | `30`    | Column count threshold      |
| `overscan`   | `number`  | `3`     | Extra columns to render     |

## Requirements

- `fitMode: 'fixed'` — the plugin is designed for fixed-width column layouts
- Columns should have explicit widths (columns without widths default to 100px)

## Programmatic API

```ts
const plugin = grid.getPluginByName('columnVirtualization');

// Check if virtualization is currently active
const active = plugin.getIsVirtualized();

// Get the visible column index range
const { start, end } = plugin.getVisibleColumnRange();

// Scroll a specific column into view
plugin.scrollToColumn(42);
```

## See Also

- **[Performance](/grid/guides/performance.md)** — Performance optimization tips
- **[Pinned Columns](/grid/plugins/pinned-columns.md)** — Sticky columns (excluded from virtualization)
