Skip to main content

Overview

The main application functions handle data loading, tooth information retrieval, treatment management, and export functionality for the dental charting system.

loadDentalData()

Asynchronously loads FDI tooth data from the JSON database file.

Signature

async function loadDentalData()

Description

Fetches tooth information from dientes_fdi_completo.json and stores it in the global dentalData variable. This data includes tooth types, names, surfaces, and anatomical information for all FDI tooth numbers.

Returns

void
Promise<void>
Returns a promise that resolves when data is loaded successfully

Example

// Load dental data on app initialization
await loadDentalData()
console.log('Dental data loaded successfully')

Error Handling

try {
  const response = await fetch('./dientes_fdi_completo.json')
  dentalData = await response.json()
  console.log('Dental data loaded successfully')
} catch (error) {
  console.error('Error loading dental data:', error)
}

getToothInfo(fdi)

Retrieves detailed information for a specific tooth by its FDI number.

Signature

function getToothInfo(fdi)

Parameters

fdi
number | string
required
The FDI tooth number (e.g., 11, 21, 36). Can be provided as string or number.

Returns

toothInfo
object | null
Returns tooth information object or null if not foundProperties:
  • fdi (number): FDI tooth number
  • tipo (string): Tooth type (e.g., “incisivo”, “molar”)
  • nombre (string): Tooth name/location
  • arco (string): Jaw arch (superior/inferior)
  • lado (string): Side (derecha/izquierda)
  • caras (array): Available tooth surfaces

Example

const toothInfo = getToothInfo(21)
if (toothInfo) {
  console.log(`Tooth ${toothInfo.fdi}: ${toothInfo.nombre}`)
  console.log(`Type: ${toothInfo.tipo}`)
  console.log(`Surfaces: ${toothInfo.caras.join(', ')}`)
}
// Output:
// Tooth 21: Incisivo Central Superior Izquierdo
// Type: incisivo
// Surfaces: vestibular, palatina, mesial, distal, incisal

Implementation

function getToothInfo(fdi) {
  if (!dentalData || !dentalData.dientes) return null
  
  // Ensure FDI is treated as number for proper matching
  const fdiNumber = parseInt(fdi)
  return dentalData.dientes.find((tooth) => tooth.fdi === fdiNumber)
}

displayToothInfo(fdi)

Displays detailed tooth information in the UI info panel.

Signature

function displayToothInfo(fdi)

Parameters

fdi
number | string
required
The FDI tooth number to display information for

Returns

void
void
Updates the DOM element with id ‘toothInfo’

Description

Generates and displays a formatted card showing tooth details including type, location, arch/side, and available surfaces. If tooth information is not available, displays a “not available” message.

Example

// Display info for tooth 16
displayToothInfo(16)

// Renders HTML:
// <div class="tooth-details-card">
//   <h4>Diente 16</h4>
//   <div class="tooth-detail-row">
//     <span class="label">Tipo:</span>
//     <span class="value">molar</span>
//   </div>
//   ...
// </div>

Surface Name Mapping

const surfaceNames = {
  vestibular: 'Vestibular',
  palatina: 'Palatina',
  lingual: 'Lingual',
  mesial: 'Mesial',
  distal: 'Distal',
  incisal: 'Incisal',
  oclusal: 'Oclusal'
}

getTreatmentName(code)

Converts a treatment code to its human-readable Spanish name.

Signature

function getTreatmentName(code)

Parameters

code
string
required
Treatment code (e.g., “CARIES”, “AMF”, “RCT”)

Returns

name
string
Spanish treatment name, or the original code if not found

Treatment Codes

CodeSpanish NameEnglish Description
CARIESCariesCaries
CFRExtracciónExtraction
AMFObturación AmalgamaAmalgam Filling
COFObturaciónComposite Filling
POCCoronaCrown
INCIncrustaciónInlay
FMCPrótesis RemovibleRemovable Prosthesis
IPXImplanteImplant
NVTSurco ProfundoDeep Groove
UNEPieza No ErupcionadaUnerupted Tooth
RCTTratamiento de ConductoRoot Canal Treatment
CARIES_UNTREATABLECaries IncurableUntreatable Caries
MISDiente AusenteMissing Tooth
SILObturación SilicatoSilicate Filling
PREParadentosisPeriodontitis
FRM_ACRPivotPivot
BRIDGEPuenteBridge
ORTOrtodonciaOrthodontics
RESRestauraciónRestoration
REFRestauración FiltradaLeaked Restoration

Example

const name = getTreatmentName('AMF')
console.log(name) // "Obturación Amalgama"

const unknown = getTreatmentName('UNKNOWN')
console.log(unknown) // "UNKNOWN" (returns code if not found)

generateProfessionalPNG()

Generates a professional clinical PNG report and uploads it to the backend.

Signature

async function generateProfessionalPNG()

Description

Creates an A4-sized (1600x2000px) professional dental report with:
  • Patient name and timestamp header
  • Odontogram diagram
  • Treatment details (up to 8 teeth in 2-column layout)
  • Notes for each tooth
  • Professional footer
The generated image is uploaded to the backend along with JSON data.

Returns

void
Promise<void>
Uploads PNG and JSON to backend via API

Canvas Specifications

// A4 proportions at high resolution
canvas.width = 1600
canvas.height = 2000

// Clinical white background
ctx.fillStyle = '#FFFFFF'
ctx.fillRect(0, 0, canvas.width, canvas.height)

Report Sections

  1. Header
    • Title: “ODONTOGRAMA”
    • Patient name (truncated if too long)
    • Date and time
  2. Odontogram Diagram
    • Scaled to fit 700px height max
    • Centered horizontally
  3. Treatments (2-column layout)
    • Left column: Teeth 1-4
    • Right column: Teeth 5-8
    • Conditions, pre-existing treatments, required treatments
    • Clinical notes
  4. Footer
    • System attribution
    • Generation timestamp

Example

// Generate and upload report
$('#download').click(function () {
  generateProfessionalPNG()
})

// Inside function:
const filename = `Odontograma_${sanitizedName}_${timestamp}.png`
// Uploads to backend with patient record ID

Font Sizes

// Bigger fonts for readability
ctx.font = 'bold 48px Arial' // Title
ctx.font = '28px Arial'      // Patient info
ctx.font = 'bold 24px Arial' // Tooth headers
ctx.font = 'bold 28px Arial' // Notes label
ctx.font = '24px Arial'      // Notes text

exportOdontogramData()

Exports complete odontogram data as a JSON file download.

Signature

function exportOdontogramData()

Description

Generates a structured JSON export containing all tooth treatments, conditions, and notes. Automatically downloads as a file named odontograma_YYYY-MM-DD.json.

Returns

exportData
object
The exported data object before downloadStructure:
  • fecha (string): Export date in ISO format
  • nombre (string): Patient name
  • piezas (array): Array of tooth data objects

Tooth Data Structure

{
  "pieza": 21,
  "condiciones": [
    "Caries Incurable - Cara/s: Vestibular, Mesial"
  ],
  "prestacion_requerida": [
    "Obturación - Cara/s: Distal"
  ],
  "prestacion_preexistente": [
    "Obturación Amalgama - Cara/s: Oclusal"
  ],
  "notas": "Patient reports sensitivity to cold"
}

Surface Mapping

The export uses anatomically correct surface names based on FDI tooth position:
const canvasPositionMap = {
  T: 'top',
  B: 'bottom',
  L: 'left',
  R: 'right',
  M: 'middle'
}

// Then mapped to anatomical names:
const correctMapping = getCorrectSurfaceMapping(toothNum)
const anatomical = correctMapping[fullCanvasPosition]
// e.g., "top" → "vestibular" (upper tooth) or "lingual" (lower tooth)

Example Export

const data = exportOdontogramData()

// Returns and downloads:
{
  "fecha": "2024-03-15",
  "nombre": "PACIENTE - [A obtener de Airtable]",
  "piezas": [
    {
      "pieza": 16,
      "condiciones": [],
      "prestacion_requerida": ["Corona"],
      "prestacion_preexistente": ["Tratamiento de Conducto"],
      "notas": ""
    },
    {
      "pieza": 21,
      "condiciones": ["Caries Incurable - Cara/s: Vestibular"],
      "prestacion_requerida": ["Extracción"],
      "prestacion_preexistente": [],
      "notas": "Urgente: dolor agudo"
    }
  ]
}

Validation

// Only exports teeth with data
if (
  toothData.condiciones.length > 0 ||
  toothData.prestacion_requerida.length > 0 ||
  toothData.prestacion_preexistente.length > 0 ||
  toothData.notas.trim() !== ''
) {
  exportData.piezas.push(toothData)
}

// Sorts teeth by FDI number
exportData.piezas.sort((a, b) => parseInt(a.pieza) - parseInt(b.pieza))

Download Trigger

const blob = new Blob([JSON.stringify(exportData, null, 2)], {
  type: 'application/json'
})
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `odontograma_${exportData.fecha}.json`
a.click()
URL.revokeObjectURL(url)

Helper functions

getTreatmentIcon(code)

Returns the visual symbol/icon for a given treatment code.

Signature

function getTreatmentIcon(code)

Parameters

code
string
required
Treatment code (e.g., ‘CARIES’, ‘COF’, ‘MIS’)

Returns

icon
string
Unicode character or text representing the treatment visually

Example

const icon = getTreatmentIcon('CARIES')
console.log(icon)  // '●'

const bridgeIcon = getTreatmentIcon('BRIDGE')
console.log(bridgeIcon)  // 'Π'

Icon mapping

const icons = {
  CARIES: '●',
  CARIES_UNTREATABLE: '●',
  CFR: '=',
  AMF: '/A',
  COF: '/Ob',
  SIL: '/S',
  POC: '○',
  INC: 'I',
  FMC: '□',
  IPX: 'IM',
  NVT: '/Sp',
  UNE: 'X',
  RCT: '▼',
  MIS: 'X',
  PRE: 'Pd',
  FRM_ACR: 'P',
  BRIDGE: 'Π',
  ORT: '~',
  RES: 'Δ',
  REF: '/Rf'
}
return icons[code] || '•'

getLayerInfo(layer)

Returns display information for an annotation layer.

Signature

function getLayerInfo(layer)

Parameters

layer
string
required
Layer identifier (‘pre’ or ‘req’)

Returns

layerInfo
object
Object containing layer display informationProperties:
  • name (string): Human-readable layer name
  • color (string): Hex color code for the layer
  • badge (string): Short badge text (e.g., ‘PRE’, ‘REQ’)

Example

const layerInfo = getLayerInfo('pre')
console.log(layerInfo)
// {
//   name: 'Pre-existente',
//   color: '#FF0000',
//   badge: 'PRE'
// }

const reqLayer = getLayerInfo('req')
console.log(reqLayer)
// {
//   name: 'Requerido',
//   color: '#0066FF',
//   badge: 'REQ'
// }

Implementation

function getLayerInfo(layer) {
  const layerInfo = {
    pre: { name: 'Pre-existente', color: '#FF0000', badge: 'PRE' },
    req: { name: 'Requerido', color: '#0066FF', badge: 'REQ' }
  }
  return layerInfo[layer] || { name: 'Desconocido', color: '#000', badge: '???' }
}

getPatientNameFromDOM()

Extracts the patient name from the DOM element or URL parameters.

Signature

function getPatientNameFromDOM()

Returns

patientName
string
Patient name string, or ‘Paciente’ if not found

Example

const patientName = getPatientNameFromDOM()
console.log(patientName)  // 'JUAN PÉREZ'

Implementation

function getPatientNameFromDOM() {
  // First try to get from DOM element
  const nameElement = document.getElementById('patientName')
  if (nameElement && nameElement.textContent.trim()) {
    return nameElement.textContent.trim()
  }
  
  // Fall back to URL parameter
  const urlParams = new URLSearchParams(window.location.search)
  const nameFromUrl = urlParams.get('nombre') || urlParams.get('name')
  if (nameFromUrl) {
    return nameFromUrl
  }
  
  // Default fallback
  return 'Paciente'
}

getCurrentPatientName()

Retrieves the current patient name from global storage or DOM.

Signature

function getCurrentPatientName()

Returns

patientName
string
Patient name from window.currentPatientName, localStorage, or DOM

Example

const currentName = getCurrentPatientName()
console.log(currentName)  // 'MARÍA GONZÁLEZ'

Implementation

function getCurrentPatientName() {
  // Try global variable first (set by patient-display.js)
  if (window.currentPatientName) {
    return window.currentPatientName
  }
  
  // Try localStorage
  const storedName = localStorage.getItem('currentPatientName')
  if (storedName) {
    return storedName
  }
  
  // Fall back to DOM extraction
  return getPatientNameFromDOM()
}
This function is used by export and upload functions to ensure consistent patient identification across all operations.

Build docs developers (and LLMs) love