Skip to main content
The Dental Odontogram can generate professional A4-style PNG reports that include the odontogram visualization, treatment details, and clinical notes.

Report format

Reports are generated as PNG images with:
  • Dimensions: 1600px × 2000px (A4 aspect ratio at ~190 DPI)
  • Layout: Professional clinical document format
  • Sections: Header, patient info, odontogram, treatment details, notes
  • Font sizes: 18px-28px for readability
  • Two-column design: Up to 4 teeth per column for treatment details

Generating reports

Reports are generated using the generateProfessionalPNG() function from dental-app.js:
async function generateProfessionalPNG() {
  // Get current odontogram canvas
  const $canvas = $('#odontogram')
  const odontogram = $canvas.data('odontogram')
  
  if (!odontogram) {
    alert('No se puede generar el reporte. Odontograma no inicializado.')
    return
  }

  // Get geometry data
  const geometry = odontogram.geometry || {}
  
  // Create A4-sized canvas
  const reportCanvas = document.createElement('canvas')
  reportCanvas.width = 1600
  reportCanvas.height = 2000
  const ctx = reportCanvas.getContext('2d')
  
  // White background
  ctx.fillStyle = '#FFFFFF'
  ctx.fillRect(0, 0, reportCanvas.width, reportCanvas.height)
  
  // ... rest of rendering logic
}

Report sections

1. Header

// Header with title
ctx.fillStyle = '#0066CC'
ctx.fillRect(0, 0, reportCanvas.width, 80)
ctx.fillStyle = '#FFFFFF'
ctx.font = 'bold 32px Arial'
ctx.textAlign = 'center'
ctx.fillText('ODONTOGRAMA DENTAL', reportCanvas.width / 2, 50)

2. Patient information

// Patient info section
const patientName = document.getElementById('patientName')?.textContent || 'Paciente'
const currentDate = new Date().toLocaleDateString('es-AR')

ctx.fillStyle = '#333333'
ctx.font = 'bold 24px Arial'
ctx.textAlign = 'left'
ctx.fillText(`Paciente: ${patientName}`, 40, 120)
ctx.fillText(`Fecha: ${currentDate}`, 40, 150)

3. Odontogram visualization

// Draw the odontogram at scale
const odontogramScale = 1.5
const odontogramY = 180

ctx.save()
ctx.translate(100, odontogramY)
ctx.scale(odontogramScale, odontogramScale)

// Draw odontogram from original canvas
const odontogramDataURL = odontogram.getDataURL()
const odontogramImage = new Image()
odontogramImage.onload = function () {
  ctx.drawImage(odontogramImage, 0, 0)
  ctx.restore()
  
  // Continue with treatment details...
}
odontogramImage.src = odontogramDataURL

4. Treatment details

Treatment details are rendered in a two-column layout:
const detailsY = odontogramY + 700 // Below odontogram
const columnWidth = 700
const leftColumnX = 50
const rightColumnX = 850
const lineHeight = 30

let currentY = detailsY
let currentColumn = 'left'
let teethInColumn = 0
const MAX_TEETH_PER_COLUMN = 4

ctx.font = 'bold 22px Arial'
ctx.fillStyle = '#0066CC'
ctx.fillText('DETALLE DE TRATAMIENTOS', leftColumnX, currentY)
currentY += 40

// Iterate through teeth with treatments
Object.keys(geometry).forEach((toothKey) => {
  const toothNum = toothKey.split('-')[0]
  const treatments = geometry[toothKey] || []
  
  if (treatments.length === 0) return
  
  // Switch columns if needed
  if (teethInColumn >= MAX_TEETH_PER_COLUMN) {
    currentColumn = 'right'
    currentY = detailsY + 40 // Reset Y for right column
    teethInColumn = 0
  }
  
  const x = currentColumn === 'left' ? leftColumnX : rightColumnX
  
  // Tooth number
  ctx.font = 'bold 24px Arial'
  ctx.fillStyle = '#0066CC'
  ctx.fillText(`Pieza ${toothNum}:`, x, currentY)
  currentY += lineHeight
  
  // Treatment list
  ctx.font = '18px Arial'
  ctx.fillStyle = '#333333'
  treatments.forEach((treatment) => {
    const name = getTreatmentName(treatment.name)
    const icon = getTreatmentIcon(treatment.name)
    const layer = getLayerInfo(treatment.layer || 'pre')
    
    ctx.fillText(`  ${icon} ${name} [${layer.badge}]`, x, currentY)
    currentY += lineHeight
  })
  
  teethInColumn++
  currentY += 10 // Space between teeth
})

5. Notes section

// Notes at bottom
const notesY = 1800
ctx.font = 'bold 22px Arial'
ctx.fillStyle = '#0066CC'
ctx.fillText('NOTAS CLÍNICAS', leftColumnX, notesY)

let noteY = notesY + 35
ctx.font = '18px Arial'
ctx.fillStyle = '#333333'

Object.keys(toothNotes).forEach((toothNum) => {
  if (toothNotes[toothNum]) {
    ctx.fillText(`Pieza ${toothNum}: ${toothNotes[toothNum]}`, leftColumnX, noteY)
    noteY += 25
  }
})

Configuration options

You can customize the report by modifying constants in generateProfessionalPNG():
reportCanvas.width
number
default:1600
Canvas width in pixels (A4 width at ~190 DPI)
reportCanvas.height
number
default:2000
Canvas height in pixels (A4 height at ~190 DPI)
odontogramScale
number
Scale factor for the odontogram visualization
MAX_TEETH_PER_COLUMN
number
default:4
Maximum number of teeth to show per column before switching to the second column
lineHeight
number
default:30
Vertical spacing between treatment lines in pixels

Font sizes

The report uses different font sizes for hierarchy:
  • 32px: Main title
  • 24-28px: Section headers and patient info
  • 22px: Tooth numbers and section titles
  • 18px: Treatment details and notes

Downloading the report

After generation, the report is automatically downloaded:
// Convert canvas to blob and download
reportCanvas.toBlob((blob) => {
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')
  const patientName = document.getElementById('patientName')?.textContent || 'Paciente'
  const dateStr = new Date().toISOString().split('T')[0]
  
  link.href = url
  link.download = `Odontograma_${patientName}_${dateStr}.png`
  link.click()
  
  URL.revokeObjectURL(url)
}, 'image/png')

Report usage workflow

1

Complete the odontogram

Mark all treatments on both pre-existing and required layers.
2

Add clinical notes

Document any additional information in the notes section for relevant teeth.
3

Generate report

Click the Descargar button with the 💾 icon to generate the PNG report.
4

Review the output

The report will download automatically with filename Odontograma_[Patient]_[Date].png.
5

Print or attach to records

The A4-sized PNG can be printed directly or attached to electronic health records.

Report features

Professional layout

Clean, clinical document format suitable for patient records

Complete information

Includes odontogram, treatments, layers, and notes

Layer identification

Each treatment shows [PRE] or [REQ] badge for clarity

Printable format

A4 dimensions for direct printing without scaling

Best practices

Generate reports after completing both annotation layers for a complete treatment plan overview.
The report generation happens entirely in the browser - no data is sent to a server.
If you have more than 8 teeth with treatments, some may be truncated. Consider using JSON export for complete data in those cases.

JSON export

Export complete data in JSON format

Upload endpoint

Send PNG reports to backend storage

Build docs developers (and LLMs) love