npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

schedule-grid-svg

v1.2.2

Published

A TypeScript library for generating schedule/timetable SVG grids with Japanese language support

Readme

Schedule Grid SVG

A TypeScript library for generating beautiful schedule/timetable SVG grids with full Japanese language support.

Features

  • 📅 Generate weekly schedule grids as SVG
  • 🎨 Customizable colors, fonts, and styling
  • 🇯🇵 Full Japanese language support with smart text wrapping
  • 📝 Multi-line titles with manual line breaks (\n)
  • 🎯 Automatic text contrast for readability
  • 📦 TypeScript support with full type definitions
  • 🌐 Works in both browser and Node.js environments

Installation

npm install schedule-grid-svg

Quick Start

import { generateScheduleSVG, TimetableData } from "schedule-grid-svg";

const scheduleData: TimetableData = {
  1: [
    // Monday
    {
      id: "1",
      title: "バレエ\nレッスン", // Line break supported
      startTime: "10:00",
      endTime: "11:30",
      color: "#3b82f6",
      dayOfWeek: 1,
    },
  ],
  2: [
    // Tuesday
    {
      id: "2",
      title: "レッスン",
      startTime: "14:00",
      endTime: "15:00",
      color: "#ef4444",
      dayOfWeek: 2,
    },
  ],
};

const svg = generateScheduleSVG(scheduleData);

// In browser - download the SVG
import { downloadSVG } from "schedule-grid-svg";
downloadSVG(svg, "my-schedule.svg");

// In Node.js - save to file
import { saveSVGToFile } from "schedule-grid-svg";
saveSVGToFile(svg, "./output/schedule.svg");

API

generateScheduleSVG(timetableData, config?)

Generates an SVG string from the timetable data.

Parameters:

  • timetableData: TimetableData - Schedule data organized by day of week
  • config?: SVGGeneratorConfig - Optional configuration for customization

Returns: string - SVG markup

Types

TimeSlot

interface TimeSlot {
  id: string;
  title: string; // Supports \n for line breaks
  startTime: string; // "HH:mm" format
  endTime: string; // "HH:mm" format
  color: string; // Hex color code
  dayOfWeek: number; // 0=Sunday, 1=Monday, ..., 6=Saturday
  description?: string;
}

TimetableData

interface TimetableData {
  [dayOfWeek: number]: TimeSlot[];
}

SVGGeneratorConfig

All configuration options are optional. Default values are provided for all settings.

interface SVGGeneratorConfig {
  // Grid settings
  width?: number; // Default: 1200 - SVG total width
  height?: number; // Default: 1800 - SVG total height
  cellWidth?: number; // Default: 140 - Width of each day column
  cellHeight?: number; // Default: 150 - Height per hour
  timeColumnWidth?: number; // Default: 80 - Width of time column
  headerHeight?: number; // Default: 50 - Height of header row

  // Time range
  startHour?: number; // Default: 10 - Start hour (0-23)
  endHour?: number; // Default: 21 - End hour (0-23)

  // Font styling
  fontFamily?: string; // Default: 'Arial, sans-serif'
  fontSize?: number; // Default: 12
  headerFontSize?: number; // Default: 14 - Font size for day headers
  timeFontSize?: number; // Default: 12 - Font size for time labels
  itemFontSize?: number; // Default: 11 - Fixed font size when autoFontSize is false
  autoFontSize?: boolean; // Default: true - Auto-adjust font size based on text length
  minItemFontSize?: number; // Default: 10 - Minimum font size for auto-sizing
  maxItemFontSize?: number; // Default: 24 - Maximum font size for auto-sizing

  // Colors
  backgroundColor?: string; // Default: '#d1d5db' - Grid background
  headerBackgroundColor?: string; // Default: '#f3f4f6' - Header row background
  timeBackgroundColor?: string; // Default: '#f9fafb' - Time column background
  cellBackgroundColor?: string; // Default: '#ffffff' - Cell background
  saturdayBackgroundColor?: string; // Default: '#dbeafe' - Saturday column background
  sundayBackgroundColor?: string; // Default: '#fee2e2' - Sunday column background
  borderColor?: string; // Default: '#9ca3af' - Border color
  textColor?: string; // Default: '#1f2937' - General text color
  headerTextColor?: string; // Default: '#374151' - Header text color

  // Other
  borderWidth?: number; // Default: 1 - Border thickness
  itemBorderRadius?: number; // Default: 4 - Border radius for schedule items
  itemPadding?: number; // Default: 2 - Padding inside schedule items
  dayOfWeekLanguage?: 'ja' | 'en'; // Default: 'ja' - Language for day headers (Mon/Tue vs 月/火)
}

Key Configuration Options:

  • autoFontSize: When true (default), text size automatically adjusts based on the longest line in the title or time. Set to false to use a fixed itemFontSize.
  • minItemFontSize / maxItemFontSize: Control the range of font sizes when autoFontSize is enabled.
  • dayOfWeekLanguage: Set to 'en' for English day names (Sun, Mon, Tue, ...) or 'ja' for Japanese (日, 月, 火, ...).
  • cellHeight: Controls the height for each hour. Larger values provide more space for schedule items.

Utility Functions

downloadSVG(svg, filename?)

Downloads the SVG in the browser.

downloadSVG(svg, "my-schedule.svg");

saveSVGToFile(svg, filename)

Saves the SVG to a file (Node.js only).

saveSVGToFile(svg, "./output/schedule.svg");

svgToDataURL(svg)

Converts SVG to a data URL.

const dataUrl = svgToDataURL(svg);

Customization Examples

Basic Customization

const customConfig: SVGGeneratorConfig = {
  startHour: 9,
  endHour: 18,
  cellWidth: 160,
  cellHeight: 100,
  fontFamily: "Arial, sans-serif",
  saturdayBackgroundColor: "#e0f2fe",
  sundayBackgroundColor: "#fee2e2",
};

const svg = generateScheduleSVG(scheduleData, customConfig);

English Day Names

const svg = generateScheduleSVG(scheduleData, {
  dayOfWeekLanguage: "en", // Mon, Tue, Wed, ...
});

Fixed Font Size

const svg = generateScheduleSVG(scheduleData, {
  autoFontSize: false, // Disable auto-sizing
  itemFontSize: 14, // Use fixed 14px font
});

Custom Font Size Range

const svg = generateScheduleSVG(scheduleData, {
  autoFontSize: true,
  minItemFontSize: 12, // Minimum 12px
  maxItemFontSize: 20, // Maximum 20px
});

Custom Color Scheme

const svg = generateScheduleSVG(scheduleData, {
  backgroundColor: "#f0f0f0",
  cellBackgroundColor: "#ffffff",
  saturdayBackgroundColor: "#e3f2fd",
  sundayBackgroundColor: "#ffebee",
  borderColor: "#cccccc",
  headerBackgroundColor: "#e0e0e0",
  headerTextColor: "#333333",
});

Multi-line Titles

You can use \n in the title to create manual line breaks (up to 3 lines recommended):

{
  title: "大人\n(入門)",  // Will display on 2 lines
  startTime: "10:00",
  endTime: "11:00",
  // ...
}

Interactive Features (Browser Only)

Automatic Modal Display

Use renderScheduleWithModal to automatically display a modal when clicking schedule items:

import { generateScheduleSVG, renderScheduleWithModal } from 'schedule-grid-svg';

const scheduleData = {
  1: [{
    id: '1',
    title: 'バレエ\nレッスン',
    startTime: '10:00',
    endTime: '11:30',
    color: '#3b82f6',
    dayOfWeek: 1,
    description: 'バレエの基礎から学べるクラスです。' // Optional description
  }]
};

const svg = generateScheduleSVG(scheduleData);
const container = document.getElementById('schedule-container');

// Render SVG with automatic modal on click
renderScheduleWithModal(svg, container, scheduleData);

Custom Click Handler

You can provide a custom click handler instead of using the default modal:

renderScheduleWithModal(
  svg,
  container,
  scheduleData,
  (item) => {
    console.log('Clicked:', item);
    // Your custom logic here
    alert(`You clicked: ${item.title}`);
  }
);

Manual Modal Control

Use showModal to manually display a modal:

import { showModal } from 'schedule-grid-svg';

const item = {
  id: '1',
  title: 'バレエレッスン',
  startTime: '10:00',
  endTime: '11:30',
  color: '#3b82f6',
  dayOfWeek: 1,
  description: 'バレエの基礎から学べるクラスです。'
};

showModal(item);

Attach Click Handlers to Existing SVG

If you've already inserted the SVG into the DOM:

import { attachScheduleClickHandlers } from 'schedule-grid-svg';

const svgElement = document.querySelector('svg');
attachScheduleClickHandlers(svgElement, scheduleData);

Customize Modal Appearance

const modalConfig = {
  backgroundColor: '#ffffff',
  overlayColor: 'rgba(0, 0, 0, 0.7)',
  borderRadius: '12px',
  padding: '32px',
  titleFontSize: '24px',
  contentFontSize: '16px',
  closeButtonSize: '28px'
};

renderScheduleWithModal(svg, container, scheduleData, undefined, modalConfig);

License

MIT

Author

itashin0501

Repository

https://github.com/itashin0501/schedule-grid-svg