@alisaitteke/seatmap-canvas

Seatmap Canvas is an advanced, open-source library for interactive seat selection in various settings such as stadiums, theaters, and event spaces. Designed with d3.js, this code version is optimized for developers looking for a customizable and efficient
11,900 162
Install
npm install @alisaitteke/seatmap-canvas
Latest Version:2.7.6
Vue:3
License:MIT
Last Updated:Oct 19, 2026
Links: GitHub  ·  npm
Maintainer: axee

Seatmap Canvas

Seatmap Canvas is an advanced, open-source library for interactive seat selection in various settings such as stadiums, theaters, and event spaces. Designed with d3.js, this code version is optimized for developers looking for a customizable and efficient solution to handle seat arrangements and user interactions.

LIVE DEMO

📖 Documentation | 🎯 Live Demo

Features

  • Framework Agnostic - Core library works with vanilla JS, plus official React and Vue 3 wrappers
  • Dynamic Seat Selection - Interactive selection, categorization, and location of seats
  • Custom Background Images - Global and per-block background images with positioning control
  • Customizable Styles - Extensive styling options for seats, blocks, and labels
  • Interactive Seat Models - Define properties like salability, notes, colors, and custom data
  • Block Organization - Organize seats into blocks with titles, colors, and labels
  • Event System - Simplified event listeners for seat interactions

Screenshot

LIVE DEMO

🚀 Framework Plugins & Integrations

🌐 Web Frameworks

Vue.js 3    React    Next.js    Svelte    Angular    Nuxt    Solid.js    Astro

📱 Mobile Frameworks

React Native    Flutter    Expo    Ionic    Capacitor    .NET MAUI


🌐 Web Framework Integrations

Framework Status Package Documentation Example
Vanilla JS ✅ Available @alisaitteke/seatmap-canvas 📖 Documentation 🎯 Example
Vue.js 3 ⚠️ Testing @alisaitteke/seatmap-canvas/vue 📖 Documentation 🎯 Example
React ⚠️ Testing @alisaitteke/seatmap-canvas/react 📖 Documentation 🎯 Example
Next.js ⚠️ Testing @alisaitteke/seatmap-canvas/nextjs 📖 Documentation 🎯 App Router • Pages Router
Svelte 🔜 Coming Soon - - -
Angular 🔜 Coming Soon - - -
Nuxt 🔜 Coming Soon - - -
Solid.js 🔜 Coming Soon - - -
Astro 🔜 Coming Soon - - -

📱 Mobile Framework Integrations

Framework Platform Status Package Documentation Example
React Native iOS • Android 🔜 Coming Soon - - -
Flutter iOS • Android 🔜 Coming Soon - - -
Expo iOS • Android 🔜 Coming Soon - - -
Ionic iOS • Android • Web 🔜 Coming Soon - - -
Capacitor iOS • Android • Web 🔜 Coming Soon - - -
.NET MAUI iOS • Android • Windows • macOS 🔜 Coming Soon - - -

LIVE DEMO

What does it do?

In any organization
  • Seat selection
  • Seat categorizing
  • Locating
  • Turnstile and Gate information

Installation

npm install @alisaitteke/seatmap-canvas

Quick Start


Vue.js  Vue.js 3

Installation

npm install @alisaitteke/seatmap-canvas

Setup (main.ts)

import { createApp } from 'vue';
import App from './App.vue';
import SeatmapCanvasPlugin from '@alisaitteke/seatmap-canvas/vue';
import '@alisaitteke/seatmap-canvas/dist/seatmap.canvas.css';

const app = createApp(App);
app.use(SeatmapCanvasPlugin);
app.mount('#app');

Component Usage

<template>
  <SeatmapCanvas
    :options="seatmapOptions"
    :data="blocks"
    @seat-click="onSeatClick"
  />
</template>

<script setup lang="ts">
const seatmapOptions = {
  legend: true,
  style: {
    seat: {
      hover: '#8fe100',
      selected: '#8fe100',
    }
  }
};

const onSeatClick = (seat) => {
  seat.isSelected() ? seat.unSelect() : seat.select();
};
</script>

Documentation   Examples


React  React

Installation

npm install @alisaitteke/seatmap-canvas

Component Usage

import { SeatmapCanvas } from '@alisaitteke/seatmap-canvas/react';
import '@alisaitteke/seatmap-canvas/dist/seatmap.canvas.css';

function App() {
  const handleSeatClick = (seat) => {
    seat.isSelected() ? seat.unSelect() : seat.select();
  };

  return (
    <SeatmapCanvas
      options={{
        legend: true,
        style: {
          seat: { hover: '#8fe100', selected: '#8fe100' }
        }
      }}
      data={blocks}
      onSeatClick={handleSeatClick}
    />
  );
}

Documentation   Examples


Next.js  Next.js

Installation

npm install @alisaitteke/seatmap-canvas next react react-dom

App Router (Client Component)

'use client';

import { SeatmapCanvas } from '@alisaitteke/seatmap-canvas/nextjs';
import '@alisaitteke/seatmap-canvas/dist/seatmap.canvas.css';

export default function VenuePage() {
  const handleSeatClick = (seat) => {
    seat.isSelected() ? seat.unSelect() : seat.select();
  };

  return (
    <SeatmapCanvas
      data={blocks}
      options={{ legend: true }}
      onSeatClick={handleSeatClick}
    />
  );
}

Server Component + Data Fetching

import { SeatmapServerWrapper } from '@alisaitteke/seatmap-canvas/nextjs/app-router';
import '@alisaitteke/seatmap-canvas/dist/seatmap.canvas.css';

export default async function VenuePage({ params }) {
  return (
    <SeatmapServerWrapper
      dataSource={`/api/venues/${params.id}/seatmap`}
      options={{ legend: true }}
      revalidate={3600}
    />
  );
}

Pages Router (Dynamic Import)

import { SeatmapCanvas } from '@alisaitteke/seatmap-canvas/nextjs/pages-router';

export default function VenuePage({ data }) {
  return <SeatmapCanvas data={data} />;
}

Documentation   App Router   Pages Router


JavaScript  Vanilla JavaScript

Quick Setup

const config = {
  resizable: true,
  seat_style: {
    radius: 12,
    color: "#6796ff",
    hover: "#5671ff",
    selected: "#56aa45"
  }
};

const seatmap = new SeatmapCanvas(".container", config);
seatmap.setData(data);

Event Handling

seatmap.addEventListener("seat_click", (seat) => {
  if (seat.selected) {
    seatmap.seatUnselect(seat);
  } else {
    seatmap.seatSelect(seat);
  }
});

// Get selected seats
const selected = seatmap.getSelectedSeats();
📋 Data Models Reference
Seat Model
{
  "id": 1,
  "title": "49",
  "x": 0,
  "y": 0,
  "salable": true,
  "note": "note test",
  "color":"#ffffff",
  "custom_data": {
    "any": "things"
  }
}
Block Model
{
  "blocks": [{
    "id": 1,
    "title": "Test Block 1",
    "color": "#2c2828",
    "labels": [{ "title": "A", "x": -30, "y": 0 }],
    "seats": [
      { "id": 1, "x": 0, "y": 0, "salable": true, "title": "49" },
      { "id": 2, "x": 30, "y": 0, "salable": true, "title": "47" }
    ]
  }]
}
Configuration Options
{
  click_enable_sold_seats: true,  // Enable clicking on unavailable seats (default: false)
  
  // Global Background Image
  background_image: "assets/stadium.jpg",      // Image URL (PNG, JPG, SVG, WebP, GIF)
  background_opacity: 0.3,                     // 0-1 (default: 0.3)
  background_fit: "cover",                     // "cover" | "contain" | "fill" | "none"
  background_x: 0,                            // Manual X position (optional, auto-detect if null)
  background_y: 0,                            // Manual Y position (optional)
  background_width: 1500,                     // Manual width (optional)
  background_height: 1000                     // Manual height (optional)
}
🖼️ Custom Background Images
Global Background

Add a background image to the entire stage:

const seatmap = new SeatmapCanvas(".container", {
  background_image: "assets/concert-hall.jpg",
  background_opacity: 0.3,
  background_fit: "cover"
});

With Manual Positioning:

const seatmap = new SeatmapCanvas(".container", {
  background_image: "assets/stadium.jpg",
  background_x: -500,        // Position X
  background_y: -500,        // Position Y
  background_width: 3000,    // Width
  background_height: 2500,   // Height
  background_opacity: 0.4,
  background_fit: "contain"  // Preserve aspect ratio
});
Block-Level Background

Add custom backgrounds to individual blocks:

{
  blocks: [{
    id: "vip-section",
    title: "VIP Area",
    background_image: "assets/vip-lounge.jpg",
    background_opacity: 0.6,
    background_fit: "cover",
    seats: [...]
  }, {
    id: "general",
    title: "General Admission",
    background_image: "assets/general-area.jpg",
    background_opacity: 0.5,
    seats: [...]
  }]
}

With Manual Positioning:

{
  blocks: [{
    id: "block-a",
    background_image: "section-a.jpg",
    background_x: 100,         // Exact X coordinate
    background_y: 200,         // Exact Y coordinate
    background_width: 500,     // Exact width
    background_height: 400,    // Exact height
    background_opacity: 0.7,
    background_fit: "cover",
    seats: [...]
  }]
}
Fit Modes
  • cover (default) - Image covers entire area, may crop
  • contain - Image fits inside area, preserves aspect ratio
  • fill - Image stretches to fill area
  • none - Image keeps original size, centered
Features
  • ✅ Auto-Detection: X, Y, Width, Height auto-calculated from bounds if not specified
  • ✅ Clip-Path Masking: Block backgrounds clipped to exact block shape
  • ✅ Opacity Control: Adjustable transparency (0-1)
  • ✅ Auto-Hide Bounds: Block borders/fills hidden when background exists
  • ✅ Zoom Preserved: Bounds calculations still work for zoom levels
  • ✅ Format Support: PNG, JPG, SVG, WebP, GIF, all web-compatible formats
  • ✅ Performance: Browser-native image loading and caching
Use Cases

Stadium/Arena:

// Stadium overview as background
background_image: "stadium-aerial.jpg"

Theater:

// Stage photo per seating section
blocks: [
  { id: "orchestra", background_image: "orchestra-view.jpg" },
  { id: "balcony", background_image: "balcony-view.jpg" }
]

Restaurant:

// Floor plan as background
background_image: "floor-plan.png",
background_opacity: 0.5,
background_fit: "contain"

Event Space:

// Custom venue layout
background_image: "venue-layout.svg",
background_fit: "contain"
Important Notes
  • Background images don't affect zoom calculations (bounds preserved)
  • Block borders/fills automatically hidden when background assigned
  • CORS: Images must be same-origin or CORS-enabled
  • Performance: Use optimized images (< 500KB recommended)

Documentation   Examples


Links

Author

Ali Sait Teke

Ali Sait Teke

GitHub   LinkedIn   Twitter

Contributors

Contributions are welcome! Feel free to submit issues and pull requests.

Related Packages

ag-charts-types

Advanced Charting / Charts supporting Javascript / Typescript / React / Angular...

119,182,953 485
ag-charts-core

Advanced Charting / Charts supporting Javascript / Typescript / React / Angular...

45,092,916 485
@ag-grid-community/client-side-row-model

Advanced Data Grid / Data Table supporting Javascript / Typescript / React / Ang...

16,583,465 15,648
@ag-grid-enterprise/core

Advanced Data Grid / Data Table supporting Javascript / Typescript / React / Ang...

15,227,706 15,648

Version History

Version Released Vue License
2.7.6 ^3.3.0 MIT
2.7.5 ^3.3.0 MIT
2.7.1 ^3.3.0 MIT
2.7.0 ^3.3.0 MIT
2.6.1 ^3.3.0 MIT
Pre-releases (1)
Version Released License
2.0.1-0 MIT