/** Interface for the options used to export a dashboard or map as a PDF */ export interface PdfExportOptions { page_size: "Letter" | "A4" | "A3" orientation: "portrait" | "landscape" /** The margins to use for the PDF in inches. Usually 0.5 inch by default. */ margins: number /** * Scaling factor for the viewport width. Higher values will render the content at a larger size. */ scale: number } export const defaultOptions: PdfExportOptions = { page_size: "Letter", orientation: "portrait", margins: 0.5, scale: 1 } // Chrome default DPI for printing const DPI = 144 const PAGE_DIMENSIONS_INCHES = { Letter: { width: 8.5, height: 11 }, A4: { width: 8.27, height: 11.69 }, // 210mm x 297mm A3: { width: 11.69, height: 16.54 } // 297mm x 420mm } /** * Calculates the viewport width for a given page size and orientation * @param options The options to use for the calculation * @returns The viewport width in pixels */ export function calculateViewportWidth(options: PdfExportOptions): number { const { page_size, orientation, margins, scale } = options const dimensions = PAGE_DIMENSIONS_INCHES[page_size] if (!dimensions) { throw new Error(`Unknown page size: ${page_size}`) } let actualPageWidth: number if (orientation === "portrait") { actualPageWidth = dimensions.width } else { actualPageWidth = dimensions.height // In landscape, the page height becomes the effective width } const printableWidthInches = actualPageWidth - (2 * margins) const printableWidthPixels = printableWidthInches * DPI const finalWidth = printableWidthPixels return Math.round(finalWidth) // Return an integer value for pixels } /** * Calculates the viewport height for a given page size and orientation * @param options The options to use for the calculation * @returns The viewport height in pixels */ export function calculateViewportHeight(options: PdfExportOptions): number { const { page_size, orientation, margins, scale } = options const dimensions = PAGE_DIMENSIONS_INCHES[page_size] if (!dimensions) { throw new Error(`Unknown page size: ${page_size}`) } let actualPageHeight: number if (orientation === "portrait") { actualPageHeight = dimensions.height } else { actualPageHeight = dimensions.width // In landscape, the page width becomes the effective height } const printableHeightInches = actualPageHeight - (2 * margins) const printableHeightPixels = printableHeightInches * DPI const finalHeight = printableHeightPixels return Math.round(finalHeight) // Return an integer value for pixels }