Explain me about the latest guidelines on management of diabetic ketoacidosis.
"diabetic ketoacidosis" AND management
diabetic ketoacidosis management guidelines 2024 2025 ADA
PMID: 40032308
https://emottawablog.com/2026/01/insulin-on-the-run-manageme…
PMID: 39090718
| Feature | Diagnostic Threshold |
|---|---|
| Blood glucose | >11 mmol/L (>200 mg/dL) OR known diabetes |
| Serum/blood ketones | ≥3.0 mmol/L OR urine ketones ≥2+ |
| Venous/arterial pH | <7.3 OR serum bicarbonate <18 mmol/L |
| Severity | pH | Serum HCO₃ | β-OHB |
|---|---|---|---|
| Mild | 7.25-7.30 | 15-18 mEq/L | 3-6 mmol/L |
| Moderate | 7.00-7.24 | 10-14 mEq/L | 6-10 mmol/L |
| Severe | <7.00 | <10 mEq/L | >10 mmol/L |
| Serum K+ | Action |
|---|---|
| <3.3 mEq/L | Hold insulin; replace K+ at 40 mEq/hour IV until K+ ≥3.3, then start insulin |
| 3.3-5.3 mEq/L | Replace K+ at 20-40 mEq/L in IV fluids; target 4-5 mEq/L |
| >5.3 mEq/L | Hold K+; check frequently; ECG monitoring; K+ will fall with insulin |
| Topic | Old approach | New 2024/2025 |
|---|---|---|
| Preferred ketone monitoring | Urine dipstick | Blood β-OHB preferred |
| IV fluids | Normal saline throughout | Balanced crystalloids acceptable after initial resuscitation |
| Insulin route | IV only | SC insulin valid for mild-moderate DKA |
| Basal insulin | Hold home insulin | Continue/add basal with IV infusion |
| DKA resolution marker | Anion gap/HCO₃/pH | + Blood β-OHB <0.6 mmol/L |
| SGLT2-DKA awareness | Limited | Explicitly flagged; euDKA recognition required |
Capillary blood glucose + blood/urine ketones Venous blood gas, serum electrolytes, BUN/creatinine, osmolality, CBC, LFTs ECG (detect arrhythmias from K+ shifts), chest X-ray Identify and treat the precipitating cause - the most common are infection, insulin non-adherence/omission, new-onset T1DM, and acute coronary syndrome. SGLT2 inhibitors are a now-recognized drug trigger (euglycemic DKA) Urinary catheter if oliguric or comatose explain in detail why these tests are done. what is the pathophysiology concept of doing these tests
DKA initial investigations pathophysiology rationale VBG electrolytes osmolality ECG
Insulin deficiency + counter-regulatory hormone excess → hyperglycemia + uncontrolled lipolysis → ketogenesis → metabolic acidosis + osmotic diuresis → dehydration + electrolyte depletion
H⁺ + HCO₃⁻ → H₂CO₃ → H₂O + CO₂
CO₂ + H₂O → H₂CO₃ → H⁺ + HCO₃⁻ (this reaction is reversed by blowing off CO₂)
Corrected Na⁺ = Measured Na⁺ + 2.4 × [(glucose mg/dL - 100) / 100]
Insulin deficiency
|
├── Hyperglycemia ──────────── Capillary glucose, serum glucose
| |
| └── Osmotic diuresis ─ BUN/Cr (prerenal AKI)
| | Na⁺ (corrected), osmolality
| └────────── K⁺, Mg²⁺, PO₄³⁻ depletion
|
├── Uncontrolled lipolysis
| |
| └── Free fatty acids → Ketogenesis (β-OHB, AcAc)
| |
| ├── Blood/urine ketones
| └── High anion gap metabolic acidosis
| |
| ├── VBG (pH, HCO₃⁻, pCO₂)
| └── Serum electrolytes (anion gap)
|
├── K⁺ paradox (high serum, depleted body stores) ── ECG (arrhythmia)
|
├── Stress/infection (precipitant) ──────────────── CBC, CXR, cultures
|
└── Hepatic steatosis ──────────────────────────── LFTs
Create a diagnostic flowchart PDF for DKA workup and decision points
mkdir -p /tmp/workspace/dka-flowchart && ls /tmp/workspace/dka-flowchart/
~/dka-flowchart/dka_flowchart.py
"""
DKA Diagnostic Flowchart PDF Generator
Uses ReportLab to create a multi-page clinical decision flowchart
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import Paragraph
from reportlab.lib.enums import TA_CENTER, TA_LEFT
import math
# ─── Colour palette ───────────────────────────────────────────────────────────
C_RED = colors.HexColor("#C0392B")
C_RED_LIGHT = colors.HexColor("#FADBD8")
C_ORANGE = colors.HexColor("#E67E22")
C_ORANGE_LT = colors.HexColor("#FDEBD0")
C_BLUE = colors.HexColor("#1A5276")
C_BLUE_LT = colors.HexColor("#D6EAF8")
C_BLUE_MED = colors.HexColor("#2980B9")
C_GREEN = colors.HexColor("#1E8449")
C_GREEN_LT = colors.HexColor("#D5F5E3")
C_YELLOW = colors.HexColor("#B7950B")
C_YELLOW_LT = colors.HexColor("#FEF9E7")
C_PURPLE = colors.HexColor("#6C3483")
C_PURPLE_LT = colors.HexColor("#E8DAEF")
C_DARK = colors.HexColor("#1C2833")
C_GREY = colors.HexColor("#717D7E")
C_GREY_LT = colors.HexColor("#F2F3F4")
C_WHITE = colors.white
W, H = A4 # 595 x 842 pts
def pt(x): return x # passthrough – already in points
def mm2pt(x): return x * mm # mm to points
# ─── Drawing helpers ──────────────────────────────────────────────────────────
def draw_rounded_rect(c, x, y, w, h, r=6, fill_color=C_WHITE, stroke_color=C_DARK, lw=1):
c.setFillColor(fill_color)
c.setStrokeColor(stroke_color)
c.setLineWidth(lw)
c.roundRect(x, y, w, h, r, stroke=1, fill=1)
def draw_diamond(c, cx, cy, w, h, fill_color=C_YELLOW_LT, stroke_color=C_YELLOW, lw=1.5):
hw, hh = w/2, h/2
path = c.beginPath()
path.moveTo(cx, cy + hh)
path.lineTo(cx + hw, cy)
path.lineTo(cx, cy - hh)
path.lineTo(cx - hw, cy)
path.close()
c.setFillColor(fill_color)
c.setStrokeColor(stroke_color)
c.setLineWidth(lw)
c.drawPath(path, stroke=1, fill=1)
def draw_arrow(c, x1, y1, x2, y2, color=C_DARK, lw=1.2, label=None, label_color=None):
c.setStrokeColor(color)
c.setLineWidth(lw)
c.line(x1, y1, x2, y2)
# arrowhead
angle = math.atan2(y2 - y1, x2 - x1)
size = 7
ax1 = x2 - size * math.cos(angle - 0.4)
ay1 = y2 - size * math.sin(angle - 0.4)
ax2 = x2 - size * math.cos(angle + 0.4)
ay2 = y2 - size * math.sin(angle + 0.4)
path = c.beginPath()
path.moveTo(x2, y2)
path.lineTo(ax1, ay1)
path.lineTo(ax2, ay2)
path.close()
c.setFillColor(color)
c.drawPath(path, stroke=0, fill=1)
if label:
mx, my = (x1+x2)/2, (y1+y2)/2
c.setFont("Helvetica-Bold", 7)
c.setFillColor(label_color or color)
c.drawCentredString(mx + 8, my + 3, label)
def draw_text_in_box(c, x, y, w, h, lines, font="Helvetica", size=8, color=C_DARK,
valign="middle", bold_first=False):
"""Draw multi-line text centred inside a box."""
line_h = size * 1.35
total_h = len(lines) * line_h
if valign == "middle":
start_y = y + h/2 + total_h/2 - line_h * 0.7
else:
start_y = y + h - 6
c.setFillColor(color)
for i, line in enumerate(lines):
f = "Helvetica-Bold" if (bold_first and i == 0) else font
c.setFont(f, size)
c.drawCentredString(x + w/2, start_y - i * line_h, line)
def draw_box(c, x, y, w, h, lines, fill=C_BLUE_LT, stroke=C_BLUE_MED,
font_size=8, bold_first=False, lw=1.2, r=5):
draw_rounded_rect(c, x, y, w, h, r=r, fill_color=fill, stroke_color=stroke, lw=lw)
draw_text_in_box(c, x, y, w, h, lines, size=font_size, bold_first=bold_first)
def section_header(c, x, y, w, h, text, fill=C_BLUE, text_color=C_WHITE, size=11):
draw_rounded_rect(c, x, y, w, h, r=4, fill_color=fill, stroke_color=fill, lw=0)
c.setFont("Helvetica-Bold", size)
c.setFillColor(text_color)
c.drawCentredString(x + w/2, y + h/2 - size*0.35, text)
# ─── Page 1: Diagnosis & Severity ─────────────────────────────────────────────
def page1(c):
c.setPageSize(A4)
# ── Background
c.setFillColor(C_GREY_LT)
c.rect(0, 0, W, H, fill=1, stroke=0)
# ── Header bar
c.setFillColor(C_BLUE)
c.rect(0, H - 52, W, 52, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 17)
c.setFillColor(C_WHITE)
c.drawCentredString(W/2, H - 30, "DIABETIC KETOACIDOSIS (DKA) — DIAGNOSTIC FLOWCHART")
c.setFont("Helvetica", 9)
c.drawCentredString(W/2, H - 44, "Based on ADA/EASD/JBDS 2024 Consensus & ADA Standards of Care 2025 | Page 1 of 3: Diagnosis & Severity")
# ── Footer
c.setFillColor(C_BLUE)
c.rect(0, 0, W, 18, fill=1, stroke=0)
c.setFont("Helvetica", 7)
c.setFillColor(C_WHITE)
c.drawCentredString(W/2, 5, "For clinical use — always apply individual patient judgment | ADA/EASD/JBDS 2024")
# ── START node
draw_rounded_rect(c, W/2-70, H-100, 140, 28, r=14,
fill_color=C_BLUE, stroke_color=C_BLUE, lw=0)
c.setFont("Helvetica-Bold", 10)
c.setFillColor(C_WHITE)
c.drawCentredString(W/2, H-83, "PATIENT PRESENTS")
draw_arrow(c, W/2, H-100, W/2, H-118)
# ── Suspicion box
draw_box(c, W/2-135, H-158, 270, 38,
["Symptoms suggesting DKA?",
"Polyuria, polydipsia, nausea/vomiting, abdominal pain,",
"Kussmaul breathing, fruity breath, altered consciousness"],
fill=C_BLUE_LT, stroke=C_BLUE_MED, font_size=8, bold_first=True, r=5)
draw_arrow(c, W/2, H-158, W/2, H-178)
# ── Bedside tests box
draw_box(c, W/2-150, H-232, 300, 52,
["IMMEDIATE BEDSIDE TESTS",
"Capillary blood glucose (CBG)",
"Blood beta-hydroxybutyrate (beta-OHB) — preferred over urine ketones",
"Venous blood gas (VBG) — pH, HCO3-, pCO2, K+"],
fill=C_ORANGE_LT, stroke=C_ORANGE, font_size=8, bold_first=True, lw=1.5, r=5)
draw_arrow(c, W/2, H-232, W/2, H-252)
# ── DKA criteria diamond
diamond_y = H - 292
draw_diamond(c, W/2, diamond_y, 260, 58,
fill_color=C_YELLOW_LT, stroke_color=C_YELLOW, lw=1.8)
c.setFont("Helvetica-Bold", 8.5)
c.setFillColor(C_DARK)
c.drawCentredString(W/2, diamond_y + 14, "DKA Criteria Met? (ALL 3 required)")
c.setFont("Helvetica", 7.5)
c.drawCentredString(W/2, diamond_y + 2, "Glucose > 11 mmol/L (200 mg/dL) OR known DM")
c.drawCentredString(W/2, diamond_y - 10, "Beta-OHB >= 3.0 mmol/L OR Urine ketones >= 2+")
c.drawCentredString(W/2, diamond_y - 22, "pH < 7.3 OR HCO3- < 18 mEq/L")
# NO branch → right
draw_arrow(c, W/2 + 130, diamond_y, W/2 + 210, diamond_y, color=C_RED, lw=1.5, label="NO")
draw_box(c, W/2 + 120, diamond_y - 26, 110, 52,
["CONSIDER", "Euglycemic DKA?",
"(SGLT2i use?)", "HHS? Other cause?",
"Refer / reassess"],
fill=C_RED_LIGHT, stroke=C_RED, font_size=7.5, r=5)
# YES branch → down
draw_arrow(c, W/2, diamond_y - 29, W/2, diamond_y - 49, color=C_GREEN, lw=1.5, label="YES")
# ── Full workup box
fy = H - 400
draw_box(c, 30, fy, W - 60, 68,
["FULL DIAGNOSTIC WORKUP",
"VBG: pH, HCO3-, pCO2, K+ (IMMEDIATE — before starting insulin)",
"Serum electrolytes: Na+, K+, Cl-, HCO3-, corrected Na+ [= measured Na + 2.4 x (glucose-100)/100]",
"BUN / Creatinine | Serum Osmolality | Phosphate, Magnesium",
"CBC (WBC >25k or bands >10k = infection) | LFTs | Serum amylase/lipase",
"12-lead ECG (K+ arrhythmia? Silent MI?) | Chest X-ray | Blood + urine cultures",
"Urinary catheter if oliguric or comatose"],
fill=C_BLUE_LT, stroke=C_BLUE, font_size=8, bold_first=True, lw=1.5, r=5)
draw_arrow(c, W/2, fy, W/2, fy - 18)
# ── Severity box
sy = fy - 130
section_header(c, 30, fy - 26, W-60, 22, "SEVERITY CLASSIFICATION (ADA/EASD 2024)")
# Table
col_w = (W - 60) / 4
headers = ["Parameter", "MILD", "MODERATE", "SEVERE"]
rows = [
["Venous pH", "7.25 – 7.30", "7.00 – 7.24", "< 7.00"],
["Serum HCO3-", "15 – 18 mEq/L", "10 – 14 mEq/L", "< 10 mEq/L"],
["Blood beta-OHB", "3 – 6 mmol/L", "6 – 10 mmol/L", "> 10 mmol/L"],
["Mental status", "Alert", "Alert/Drowsy", "Stupor/Coma"],
["Anion gap", "> 12 mEq/L", "> 12 mEq/L", "> 12 mEq/L"],
]
row_h = 17
table_x = 30
table_y = fy - 28
# Header row
header_colors = [C_BLUE, C_GREEN, C_ORANGE, C_RED]
for ci, hdr in enumerate(headers):
fc = header_colors[ci]
c.setFillColor(fc)
c.rect(table_x + ci*col_w, table_y - row_h, col_w, row_h, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 8.5)
c.setFillColor(C_WHITE)
c.drawCentredString(table_x + ci*col_w + col_w/2, table_y - row_h + 5, hdr)
row_fills = [C_GREEN_LT, C_ORANGE_LT, C_RED_LIGHT]
for ri, row in enumerate(rows):
ty = table_y - row_h*(ri+2)
for ci, cell in enumerate(row):
if ci == 0:
fc = C_GREY_LT
else:
fc = row_fills[ci-1]
c.setFillColor(fc)
c.setStrokeColor(C_GREY)
c.setLineWidth(0.4)
c.rect(table_x + ci*col_w, ty, col_w, row_h, fill=1, stroke=1)
fnt = "Helvetica-Bold" if ci == 0 else "Helvetica"
c.setFont(fnt, 8)
c.setFillColor(C_DARK)
c.drawCentredString(table_x + ci*col_w + col_w/2, ty + 5, cell)
# ── Precipitants box
py = sy - 60
prec_y = table_y - row_h * 7 - 12
section_header(c, 30, prec_y, W-60, 20, "IDENTIFY & TREAT PRECIPITATING CAUSE", fill=C_RED, size=10)
prec_items = [
("Infection", "Fever, WBC >25k, bands, CXR, cultures", C_RED_LIGHT, C_RED),
("Insulin omission/non-adherence", "History, home medication review", C_ORANGE_LT, C_ORANGE),
("New-onset diabetes", "No prior Dx, young patient, HbA1c", C_BLUE_LT, C_BLUE_MED),
("Acute MI", "ECG, troponin (may be silent in DKA)", C_PURPLE_LT, C_PURPLE),
("SGLT2-inhibitor use", "Euglycemic DKA — glucose may be normal!", C_YELLOW_LT, C_YELLOW),
("Other", "PE, pancreatitis, CVA, alcohol, drugs", C_GREY_LT, C_GREY),
]
pw = (W - 72) / 3
ph = 34
for i, (title, detail, fc, sc) in enumerate(prec_items):
col = i % 3
row = i // 3
px = 36 + col * pw
py2 = prec_y - 22 - row * (ph + 4)
draw_rounded_rect(c, px, py2, pw - 4, ph, r=4, fill_color=fc, stroke_color=sc, lw=1)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(C_DARK)
c.drawCentredString(px + (pw-4)/2, py2 + ph - 11, title)
c.setFont("Helvetica", 7)
c.drawCentredString(px + (pw-4)/2, py2 + 6, detail)
# ── Arrow to page 2
draw_arrow(c, W/2, prec_y - 22 - 2*(ph+4) + 2, W/2, 24, color=C_BLUE, lw=1.5)
draw_rounded_rect(c, W/2 - 90, 20, 180, 20, r=10,
fill_color=C_BLUE, stroke_color=C_BLUE, lw=0)
c.setFont("Helvetica-Bold", 8.5)
c.setFillColor(C_WHITE)
c.drawCentredString(W/2, 28, "→ CONTINUE TO PAGE 2: MANAGEMENT (Fluids, Insulin, Electrolytes)")
c.showPage()
# ─── Page 2: Fluid & Potassium & Insulin Management ───────────────────────────
def page2(c):
c.setPageSize(A4)
c.setFillColor(C_GREY_LT)
c.rect(0, 0, W, H, fill=1, stroke=0)
# Header
c.setFillColor(C_BLUE)
c.rect(0, H-52, W, 52, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 17)
c.setFillColor(C_WHITE)
c.drawCentredString(W/2, H-30, "DKA MANAGEMENT FLOWCHART")
c.setFont("Helvetica", 9)
c.drawCentredString(W/2, H-44, "ADA/EASD/JBDS 2024 Consensus | Page 2 of 3: Fluids · Potassium · Insulin")
# Footer
c.setFillColor(C_BLUE)
c.rect(0, 0, W, 18, fill=1, stroke=0)
c.setFont("Helvetica", 7)
c.setFillColor(C_WHITE)
c.drawCentredString(W/2, 5, "For clinical use — always apply individual patient judgment | ADA/EASD/JBDS 2024")
cy = H - 65
# ── Step 1: IV access + monitoring
section_header(c, 30, cy, W-60, 20, "STEP 1 — IMMEDIATE RESUSCITATION & MONITORING", fill=C_BLUE)
cy -= 22
draw_box(c, 30, cy - 38, W-60, 38,
["IV access x2 large-bore | Continuous cardiac monitor | Strict I&O | Urinary catheter if oliguric/comatose",
"Vitals q1h | CBG q1h | Electrolytes + VBG q2-4h | Blood beta-OHB q2-4h",
"DO NOT delay fluids waiting for labs — begin 0.9% NaCl IMMEDIATELY"],
fill=C_BLUE_LT, stroke=C_BLUE_MED, font_size=8.5, r=5)
cy -= 48
draw_arrow(c, W/2, cy, W/2, cy - 12)
cy -= 12
# ── Step 2: Fluid resuscitation
section_header(c, 30, cy, W-60, 20, "STEP 2 — IV FLUID RESUSCITATION", fill=C_GREEN)
cy -= 22
# 3 column panels
col_w3 = (W - 68) / 3
panels_f = [
("HOUR 1 — Resuscitation",
["0.9% NaCl 1000 mL/hr",
"(or 10-20 mL/kg bolus if",
"haemodynamically unstable)",
"Repeat bolus until SBP > 90"],
C_GREEN_LT, C_GREEN),
("HOURS 2-8 — Replacement",
["0.9% NaCl OR balanced",
"crystalloid (Ringer's Lactate)",
"at 250-500 mL/hr",
"Adjust by urine output + vitals"],
C_ORANGE_LT, C_ORANGE),
("GLUCOSE < 250 mg/dL",
["Switch to D5-10% +",
"0.45% NaCl",
"Maintain glucose 140-200",
"Continue insulin infusion!"],
C_BLUE_LT, C_BLUE_MED),
]
ph3 = 62
for i, (title, lines, fc, sc) in enumerate(panels_f):
px = 34 + i*(col_w3 + 5)
draw_rounded_rect(c, px, cy - ph3, col_w3, ph3, r=5, fill_color=fc, stroke_color=sc, lw=1.5)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(C_DARK)
c.drawCentredString(px + col_w3/2, cy - 12, title)
c.setFont("Helvetica", 7.5)
for j, ln in enumerate(lines):
c.drawCentredString(px + col_w3/2, cy - 24 - j*11, ln)
cy -= (ph3 + 10)
draw_arrow(c, W/2, cy, W/2, cy - 12)
cy -= 12
# ── Step 3: POTASSIUM — the critical gate
section_header(c, 30, cy, W-60, 20, "STEP 3 — POTASSIUM CHECK (CRITICAL GATE — CHECK BEFORE INSULIN)", fill=C_RED)
cy -= 22
# Diamond
d_cy = cy - 30
draw_diamond(c, W/2, d_cy, 220, 52, fill_color=C_YELLOW_LT, stroke_color=C_YELLOW, lw=1.8)
c.setFont("Helvetica-Bold", 9)
c.setFillColor(C_DARK)
c.drawCentredString(W/2, d_cy + 10, "Serum K+ level?")
c.setFont("Helvetica", 8)
c.drawCentredString(W/2, d_cy - 4, "(from VBG or formal labs)")
# 3 branches
bw = 130
bh = 60
# K < 3.3 — left
draw_arrow(c, W/2 - 110, d_cy, 34 + bw/2, d_cy - 30, color=C_RED, lw=1.5)
c.setFont("Helvetica-Bold", 7); c.setFillColor(C_RED)
c.drawString(70, d_cy + 5, "< 3.3")
draw_rounded_rect(c, 34, d_cy - 30 - bh, bw, bh, r=5, fill_color=C_RED_LIGHT, stroke_color=C_RED, lw=1.5)
c.setFont("Helvetica-Bold", 8); c.setFillColor(C_RED)
c.drawCentredString(34 + bw/2, d_cy - 30 - 12, "HOLD INSULIN")
c.setFont("Helvetica", 7.5); c.setFillColor(C_DARK)
for j, ln in enumerate(["Give KCl 40 mEq/hr IV", "Recheck K+ in 1 hr", "Start insulin only", "when K+ >= 3.3"]):
c.drawCentredString(34 + bw/2, d_cy - 30 - 25 - j*10, ln)
# K 3.3–5.3 — centre
draw_arrow(c, W/2, d_cy - 26, W/2, d_cy - 30 - bh + bh/2 + 5, color=C_GREEN, lw=1.5)
c.setFont("Helvetica-Bold", 7); c.setFillColor(C_GREEN)
c.drawCentredString(W/2, d_cy - 18, "3.3 – 5.3")
draw_rounded_rect(c, W/2 - bw/2, d_cy - 30 - bh, bw, bh, r=5, fill_color=C_GREEN_LT, stroke_color=C_GREEN, lw=1.5)
c.setFont("Helvetica-Bold", 8); c.setFillColor(C_GREEN)
c.drawCentredString(W/2, d_cy - 30 - 12, "START INSULIN")
c.setFont("Helvetica", 7.5); c.setFillColor(C_DARK)
for j, ln in enumerate(["Add KCl 20-40 mEq/L", "to IV fluids", "Target K+ 4.0-5.0", "Check K+ q2h"]):
c.drawCentredString(W/2, d_cy - 30 - 25 - j*10, ln)
# K > 5.3 — right
draw_arrow(c, W/2 + 110, d_cy, W - 34 - bw/2, d_cy - 30, color=C_ORANGE, lw=1.5)
c.setFont("Helvetica-Bold", 7); c.setFillColor(C_ORANGE)
c.drawString(W/2 + 115, d_cy + 5, "> 5.3")
draw_rounded_rect(c, W - 34 - bw, d_cy - 30 - bh, bw, bh, r=5, fill_color=C_ORANGE_LT, stroke_color=C_ORANGE, lw=1.5)
c.setFont("Helvetica-Bold", 8); c.setFillColor(C_ORANGE)
c.drawCentredString(W - 34 - bw/2, d_cy - 30 - 12, "HOLD POTASSIUM")
c.setFont("Helvetica", 7.5); c.setFillColor(C_DARK)
for j, ln in enumerate(["Start insulin (K+ will fall)", "ECG monitoring", "Recheck K+ q2h", "Add K+ when < 5.3"]):
c.drawCentredString(W - 34 - bw/2, d_cy - 30 - 25 - j*10, ln)
cy = d_cy - 30 - bh - 15
draw_arrow(c, W/2, cy, W/2, cy - 12)
cy -= 12
# ── Step 4: Insulin
section_header(c, 30, cy, W-60, 20, "STEP 4 — INSULIN THERAPY", fill=C_PURPLE)
cy -= 22
col_w2 = (W - 68) / 2
panels_i = [
("IV INSULIN (Standard / Moderate-Severe DKA)",
["Fixed-rate infusion: 0.1 units/kg/hr Regular insulin",
"Optional bolus 0.1 u/kg ONLY if delay in starting infusion",
"Target glucose fall: 2-3 mmol/L/hr (36-54 mg/dL/hr)",
"When glucose < 250 mg/dL: reduce to 0.05 units/kg/hr",
"+ switch IV fluid to dextrose-containing (see Step 2)",
"Maintain glucose 140-200 mg/dL until DKA resolved"],
C_PURPLE_LT, C_PURPLE),
("SC INSULIN (NEW — Mild-Moderate DKA only)",
["Rapid-acting analogue (lispro/aspart) SC",
"Valid alternative to IV insulin per ADA 2024/2025",
"Only if: haemodynamically stable + alert + not vomiting",
"Evidence: no difference in DKA resolution time,",
"hypoglycemia, or mortality vs IV insulin (meta-analysis 2024)",
"Allows step-down unit care; may reduce costs"],
C_GREEN_LT, C_GREEN),
]
pi_h = 72
for i, (title, lines, fc, sc) in enumerate(panels_i):
px = 34 + i*(col_w2 + 5)
draw_rounded_rect(c, px, cy - pi_h, col_w2, pi_h, r=5, fill_color=fc, stroke_color=sc, lw=1.5)
c.setFont("Helvetica-Bold", 8); c.setFillColor(C_DARK)
c.drawCentredString(px + col_w2/2, cy - 11, title)
c.setFont("Helvetica", 7.5)
for j, ln in enumerate(lines):
c.drawCentredString(px + col_w2/2, cy - 23 - j*9.5, ln)
cy -= (pi_h + 6)
# Basal insulin note
draw_box(c, 30, cy - 22, W-60, 22,
["BASAL INSULIN: Continue home long-acting insulin OR add basal insulin alongside IV infusion to prevent rebound hyperglycemia (ADA 2025 / JBDS 2013)"],
fill=C_YELLOW_LT, stroke=C_YELLOW, font_size=8, r=4)
cy -= 32
# Arrow to page 3
draw_arrow(c, W/2, cy, W/2, 24, color=C_BLUE, lw=1.5)
draw_rounded_rect(c, W/2 - 90, 20, 180, 20, r=10, fill_color=C_BLUE, stroke_color=C_BLUE, lw=0)
c.setFont("Helvetica-Bold", 8.5); c.setFillColor(C_WHITE)
c.drawCentredString(W/2, 28, "→ CONTINUE TO PAGE 3: Monitoring · Resolution · Transition · Discharge")
c.showPage()
# ─── Page 3: Monitoring, Resolution, Transition, Special Situations ───────────
def page3(c):
c.setPageSize(A4)
c.setFillColor(C_GREY_LT)
c.rect(0, 0, W, H, fill=1, stroke=0)
# Header
c.setFillColor(C_BLUE)
c.rect(0, H-52, W, 52, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 17)
c.setFillColor(C_WHITE)
c.drawCentredString(W/2, H-30, "DKA: MONITORING · RESOLUTION · TRANSITION")
c.setFont("Helvetica", 9)
c.drawCentredString(W/2, H-44, "ADA/EASD/JBDS 2024 Consensus | Page 3 of 3")
# Footer
c.setFillColor(C_BLUE)
c.rect(0, 0, W, 18, fill=1, stroke=0)
c.setFont("Helvetica", 7)
c.setFillColor(C_WHITE)
c.drawCentredString(W/2, 5, "For clinical use — always apply individual patient judgment | ADA/EASD/JBDS 2024")
cy = H - 65
# ── Monitoring table
section_header(c, 30, cy, W-60, 20, "MONITORING DURING TREATMENT", fill=C_BLUE)
cy -= 22
mon_rows = [
("Capillary blood glucose", "Every 1 hour", "Target: 2-3 mmol/L/hr fall; 140-200 mg/dL once stable"),
("Serum electrolytes (K+, Na+, HCO3-)", "Every 2-4 hours", "Adjust K+ replacement in fluids based on result"),
("Venous blood gas (pH, HCO3-)", "Every 2-4 hours", "Track acidosis resolution; calculate anion gap each time"),
("Blood beta-OHB", "Every 2-4 hours", "Resolution target: < 0.6 mmol/L (preferred over urine ketones)"),
("BUN / Creatinine", "Every 4-6 hours", "Monitor renal function; confirm adequate urine output before K+ supplements"),
("Urine output", "Continuous (catheter)", "Target >= 0.5 mL/kg/hr; critical before giving K+ supplementation"),
("Cardiac monitor (ECG)", "Continuous", "Detect hypo/hyperkalemia arrhythmia; K+ changes are rapid"),
("Neurological status", "Every 1 hour", "Altered consciousness, headache, bradycardia = suspect cerebral edema"),
]
row_h = 16
col_ws = [160, 105, W-60-160-105-6]
header_row = ["Parameter", "Frequency", "Action / Target"]
header_cs = [C_BLUE, C_BLUE_MED, C_BLUE]
for ci, (hdr, cw) in enumerate(zip(header_row, col_ws)):
cx2 = 30 + sum(col_ws[:ci]) + ci
c.setFillColor(C_BLUE)
c.rect(cx2, cy - row_h, cw, row_h, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 8); c.setFillColor(C_WHITE)
c.drawCentredString(cx2 + cw/2, cy - row_h + 5, hdr)
for ri, (p, f, a) in enumerate(mon_rows):
ty = cy - row_h*(ri+2)
row_fc = C_GREY_LT if ri % 2 == 0 else C_WHITE
row_data = [p, f, a]
for ci, (cell, cw) in enumerate(zip(row_data, col_ws)):
cx2 = 30 + sum(col_ws[:ci]) + ci
c.setFillColor(row_fc)
c.setStrokeColor(C_GREY)
c.setLineWidth(0.3)
c.rect(cx2, ty, cw, row_h, fill=1, stroke=1)
font = "Helvetica-Bold" if ci == 0 else "Helvetica"
c.setFont(font, 7.5); c.setFillColor(C_DARK)
c.drawCentredString(cx2 + cw/2, ty + 5, cell)
cy -= row_h * 10 + 10
draw_arrow(c, W/2, cy, W/2, cy - 12)
cy -= 12
# ── Resolution criteria diamond
section_header(c, 30, cy, W-60, 20, "STEP 5 — RESOLUTION CRITERIA CHECK (ALL 4 must be met)", fill=C_GREEN)
cy -= 22
d_cy = cy - 38
draw_diamond(c, W/2, d_cy, 280, 64, fill_color=C_YELLOW_LT, stroke_color=C_YELLOW, lw=1.8)
c.setFont("Helvetica-Bold", 9); c.setFillColor(C_DARK)
c.drawCentredString(W/2, d_cy + 16, "DKA RESOLVED? (All 4 met)")
c.setFont("Helvetica", 8)
c.drawCentredString(W/2, d_cy + 4, "1. Blood glucose < 200 mg/dL (11.1 mmol/L)")
c.drawCentredString(W/2, d_cy - 8, "2. Serum HCO3- >= 18 mEq/L")
c.drawCentredString(W/2, d_cy - 20, "3. Venous pH > 7.3")
c.drawCentredString(W/2, d_cy - 32, "4. Blood beta-OHB < 0.6 mmol/L OR Anion gap <= 12")
# NO → loop back
draw_arrow(c, W/2 + 140, d_cy, W - 30, d_cy, color=C_RED, lw=1.5, label="NO")
c.setFont("Helvetica-Bold", 7.5); c.setFillColor(C_RED)
c.drawRightString(W - 32, d_cy + 8, "Continue insulin + fluids")
c.setFont("Helvetica", 7); c.setFillColor(C_DARK)
c.drawRightString(W - 32, d_cy - 2, "Add dextrose if glucose < 250")
c.drawRightString(W - 32, d_cy - 12, "Never stop insulin while acidotic")
# YES → down
draw_arrow(c, W/2, d_cy - 32, W/2, d_cy - 52, color=C_GREEN, lw=1.5, label="YES")
cy = d_cy - 52
draw_arrow(c, W/2, cy, W/2, cy - 10); cy -= 10
# ── Transition
section_header(c, 30, cy, W-60, 20, "STEP 6 — TRANSITION TO SUBCUTANEOUS INSULIN", fill=C_GREEN)
cy -= 22
draw_box(c, 30, cy - 36, W-60, 36,
["Patient MUST be: eating, alert, clinically stable, and DKA resolved",
"Give first SC dose (rapid-acting + basal) — then wait 1-2 HOURS before stopping IV insulin infusion",
"Calculate SC dose based on prior home regimen OR total daily insulin used in last 24h (typically 70-80% as basal + bolus split)"],
fill=C_GREEN_LT, stroke=C_GREEN, font_size=8.5, bold_first=False, r=5)
cy -= 46
draw_arrow(c, W/2, cy, W/2, cy - 10); cy -= 10
# ── Special situations
section_header(c, 30, cy, W-60, 20, "SPECIAL SITUATIONS & COMPLICATIONS", fill=C_RED)
cy -= 22
sp_items = [
("Cerebral Edema", ["Headache, falling HR,", "altered GCS in treatment",
"RX: Mannitol 0.5-1 g/kg IV", "OR 3% NaCl 2.5-5 mL/kg",
"Restrict fluids, raise HOB"], C_RED_LIGHT, C_RED),
("Euglycemic DKA (SGLT2i)", ["Glucose may be normal", "High index of suspicion",
"Same management but", "start dextrose early",
"Withhold SGLT2i"], C_ORANGE_LT, C_ORANGE),
("Severe Hypokalemia (K <3.0)", ["Hold insulin", "Replace at 40 mEq/hr",
"Continuous ECG monitor", "Recheck q1h",
"Risk: fatal arrhythmia"], C_PURPLE_LT, C_PURPLE),
("DKA in Pregnancy", ["Target glucose 100-140", "Fetal monitoring",
"Lower glucose threshold", "for dextrose switch",
"Urgent OB consult"], C_BLUE_LT, C_BLUE_MED),
("Bicarbonate use", ["ONLY if pH < 6.9", "100 mEq NaHCO3 in 400 mL",
"+ 20 mEq KCl over 2 hrs", "Reassess after",
"Risks: paradox CNS acidosis"], C_YELLOW_LT, C_YELLOW),
("HHS overlap", ["Glucose often >600", "Minimal ketosis", "Aggressive rehydration",
"Slower glucose correction", "(<90-120 mg/dL/hr)"], C_GREY_LT, C_GREY),
]
sp_w = (W - 72) / 3
sp_h = 72
for i, (title, lines, fc, sc) in enumerate(sp_items):
col = i % 3
row = i // 3
px = 36 + col * (sp_w + 3)
py2 = cy - 4 - row * (sp_h + 5)
draw_rounded_rect(c, px, py2 - sp_h, sp_w, sp_h, r=5, fill_color=fc, stroke_color=sc, lw=1.3)
c.setFont("Helvetica-Bold", 8); c.setFillColor(C_DARK)
c.drawCentredString(px + sp_w/2, py2 - 12, title)
c.setFont("Helvetica", 7.5)
for j, ln in enumerate(lines):
c.drawCentredString(px + sp_w/2, py2 - 24 - j*10, ln)
cy = cy - 4 - 2*(sp_h + 5) - sp_h - 10
draw_arrow(c, W/2, cy, W/2, cy - 10); cy -= 10
# ── Discharge box
draw_box(c, 30, cy - 36, W-60, 36,
["DISCHARGE PLANNING",
"Identify outpatient diabetes provider | Medication reconciliation (correct insulin dose, stop SGLT2i if implicated)",
"Education: sick-day rules, when to call / return to ED, importance of insulin adherence, recognise early DKA signs",
"Follow-up within 1-2 weeks"],
fill=C_BLUE_LT, stroke=C_BLUE, font_size=8, bold_first=True, r=5, lw=1.5)
cy -= 46
c.showPage()
# ─── Main ─────────────────────────────────────────────────────────────────────
def build():
out = "/tmp/workspace/dka-flowchart/DKA_Diagnostic_Flowchart.pdf"
c = canvas.Canvas(out, pagesize=A4)
c.setTitle("DKA Diagnostic & Management Flowchart — ADA/EASD/JBDS 2024")
c.setAuthor("Orris Medical AI")
c.setSubject("Diabetic Ketoacidosis Clinical Flowchart")
page1(c)
page2(c)
page3(c)
c.save()
print(f"PDF saved: {out}")
build()
cd /tmp/workspace/dka-flowchart && python dka_flowchart.py 2>&1
ls -lh /tmp/workspace/dka-flowchart/DKA_Diagnostic_Flowchart.pdf
DKA Diagnostic Flowchart
PDF Document · PDF
Create a bedside quick reference card PDF (1-page pocket guide) with key DKA thresholds and decision trees
ls /tmp/workspace/dka-flowchart/
~/dka-flowchart/dka_pocket_card.py
"""
DKA Bedside Quick Reference Card — 1 Page A5 landscape (pocket-card size)
Dense, colour-coded, print-and-laminate format.
ADA/EASD/JBDS 2024 | ADA Standards of Care 2025
"""
from reportlab.lib.pagesizes import A5, landscape
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
import math
# ── Canvas size: A5 landscape = 210 x 148 mm ──────────────────────────────────
W, H = landscape(A5) # 595 x 420 pts (≈ 210 x 148 mm)
# ── Palette ───────────────────────────────────────────────────────────────────
C_NAVY = colors.HexColor("#0B2C5F")
C_BLUE = colors.HexColor("#1A6DA8")
C_BLUE_LT = colors.HexColor("#DAEAF7")
C_BLUE_MED = colors.HexColor("#2980B9")
C_TEAL = colors.HexColor("#0E7C6C")
C_TEAL_LT = colors.HexColor("#D0EDE8")
C_GREEN = colors.HexColor("#1A7A3C")
C_GREEN_LT = colors.HexColor("#D5F0E0")
C_ORANGE = colors.HexColor("#C0570A")
C_ORANGE_LT = colors.HexColor("#FDEBD0")
C_RED = colors.HexColor("#B22222")
C_RED_LT = colors.HexColor("#FADADD")
C_PURPLE = colors.HexColor("#5B2C8D")
C_PURPLE_LT = colors.HexColor("#EAD9F7")
C_YELLOW = colors.HexColor("#8B6914")
C_YELLOW_LT = colors.HexColor("#FEF9E3")
C_DARK = colors.HexColor("#1C1C1C")
C_MGREY = colors.HexColor("#5D6D7E")
C_LGREY = colors.HexColor("#EEF0F2")
C_WHITE = colors.white
# ── Helpers ───────────────────────────────────────────────────────────────────
def rr(c, x, y, w, h, r=4, fc=C_WHITE, sc=C_DARK, lw=0.8):
c.setFillColor(fc); c.setStrokeColor(sc); c.setLineWidth(lw)
c.roundRect(x, y, w, h, r, stroke=1, fill=1)
def filled_rect(c, x, y, w, h, fc, sc=None, lw=0):
c.setFillColor(fc)
if sc:
c.setStrokeColor(sc); c.setLineWidth(lw); c.rect(x, y, w, h, fill=1, stroke=1)
else:
c.rect(x, y, w, h, fill=1, stroke=0)
def txt(c, x, y, text, font="Helvetica", size=7, color=C_DARK, align="left"):
c.setFont(font, size); c.setFillColor(color)
if align == "center":
c.drawCentredString(x, y, text)
elif align == "right":
c.drawRightString(x, y, text)
else:
c.drawString(x, y, text)
def hdr(c, x, y, w, h, text, fc=C_NAVY, tc=C_WHITE, size=7.5):
filled_rect(c, x, y, w, h, fc)
txt(c, x + w/2, y + h/2 - size*0.38, text, "Helvetica-Bold", size, tc, "center")
def arrow(c, x1, y1, x2, y2, col=C_DARK, lw=0.9):
c.setStrokeColor(col); c.setLineWidth(lw); c.line(x1, y1, x2, y2)
angle = math.atan2(y2-y1, x2-x1)
sz = 5
ax1 = x2 - sz*math.cos(angle-0.4); ay1 = y2 - sz*math.sin(angle-0.4)
ax2 = x2 - sz*math.cos(angle+0.4); ay2 = y2 - sz*math.sin(angle+0.4)
p = c.beginPath(); p.moveTo(x2,y2); p.lineTo(ax1,ay1); p.lineTo(ax2,ay2); p.close()
c.setFillColor(col); c.drawPath(p, stroke=0, fill=1)
def diamond(c, cx, cy, hw, hh, fc=C_YELLOW_LT, sc=C_YELLOW, lw=1.1):
p = c.beginPath()
p.moveTo(cx, cy+hh); p.lineTo(cx+hw, cy); p.lineTo(cx, cy-hh); p.lineTo(cx-hw, cy); p.close()
c.setFillColor(fc); c.setStrokeColor(sc); c.setLineWidth(lw); c.drawPath(p, stroke=1, fill=1)
def bullet_block(c, x, y, w, items, size=6.5, leading=8.5, color=C_DARK, bold=False):
font = "Helvetica-Bold" if bold else "Helvetica"
for i, item in enumerate(items):
c.setFont(font, size); c.setFillColor(color)
c.drawString(x, y - i*leading, item)
# ─────────────────────────────────────────────────────────────────────────────
# LAYOUT PLAN (A5 landscape 595 x 420 pt)
#
# [ HEADER BAR — full width, 22 pt tall ]
#
# Col A (x=6..188, w=182) | Col B (x=196..388, w=192) | Col C (x=394..589, w=195)
#
# A: Dx Criteria + Severity table
# B: K+ decision tree + Insulin
# C: Fluids + Resolution + Discharge
#
# [ FOOTER BAR — full width, 12 pt tall ]
# ─────────────────────────────────────────────────────────────────────────────
def build():
out = "/tmp/workspace/dka-flowchart/DKA_Pocket_Reference_Card.pdf"
cv = canvas.Canvas(out, pagesize=landscape(A5))
cv.setTitle("DKA Bedside Quick Reference Card — ADA/EASD/JBDS 2024")
cv.setAuthor("Orris Medical AI")
cv.setSubject("DKA Pocket Guide")
# ── Background
filled_rect(cv, 0, 0, W, H, colors.HexColor("#F5F7FA"))
# ═══════════════════════════════════════════════════════════════
# HEADER
# ═══════════════════════════════════════════════════════════════
filled_rect(cv, 0, H-24, W, 24, C_NAVY)
txt(cv, W/2, H-15, "DKA BEDSIDE QUICK REFERENCE — ADA/EASD/JBDS 2024 | ADA Standards of Care 2025",
"Helvetica-Bold", 8.5, C_WHITE, "center")
# thin accent line
filled_rect(cv, 0, H-26, W, 2, C_BLUE)
# ═══════════════════════════════════════════════════════════════
# COLUMN GEOMETRY
# ═══════════════════════════════════════════════════════════════
TOP = H - 30 # content starts here
BOT = 14 # above footer
USABLE = TOP - BOT # usable height
cA_x, cA_w = 6, 184
cB_x, cB_w = 196, 192
cC_x, cC_w = 394, 195
div_x1 = cB_x - 4
div_x2 = cC_x - 4
cv.setStrokeColor(colors.HexColor("#CBD0D8")); cv.setLineWidth(0.6)
cv.line(div_x1, BOT+2, div_x1, TOP)
cv.line(div_x2, BOT+2, div_x2, TOP)
# ═══════════════════════════════════════════════════════════════
# COLUMN A — Diagnosis & Severity
# ═══════════════════════════════════════════════════════════════
y = TOP
# Section: DX CRITERIA
hdr(cv, cA_x, y-13, cA_w, 13, "▶ DIAGNOSTIC CRITERIA (all 3 required)", fc=C_NAVY, size=7.5)
y -= 14
rr(cv, cA_x, y-42, cA_w, 42, r=3, fc=C_LGREY, sc=colors.HexColor("#BDC3C7"), lw=0.5)
rows_dx = [
("D", "Glucose", "> 11 mmol/L (200 mg/dL) OR known DM", C_BLUE_LT, C_BLUE),
("K", "Ketones", "Beta-OHB ≥ 3.0 mmol/L OR Urine 2+", C_ORANGE_LT, C_ORANGE),
("A", "Acidosis", "pH < 7.3 OR HCO3- < 18 mEq/L", C_RED_LT, C_RED),
]
for i, (letter, label, val, fc, sc) in enumerate(rows_dx):
ry = y - 5 - i*13
filled_rect(cv, cA_x+2, ry-9, 12, 11, fc, sc, 0.6)
txt(cv, cA_x+8, ry-6, letter, "Helvetica-Bold", 8, sc, "center")
txt(cv, cA_x+17, ry-6, label+":", "Helvetica-Bold", 6.8, C_DARK)
txt(cv, cA_x+45, ry-6, val, "Helvetica", 6.5, C_DARK)
y -= 44
# Note: blood beta-OHB preferred over urine
rr(cv, cA_x, y-11, cA_w, 11, r=2, fc=C_YELLOW_LT, sc=C_YELLOW, lw=0.6)
txt(cv, cA_x+4, y-8, "★ Blood beta-OHB preferred over urine ketone dipstick (more accurate)", "Helvetica-Oblique", 6, C_YELLOW, "left")
y -= 13
# Section: SEVERITY TABLE
hdr(cv, cA_x, y-13, cA_w, 13, "▶ SEVERITY CLASSIFICATION", fc=C_BLUE, size=7.5)
y -= 14
col_labels = ["Parameter", "MILD", "MODERATE", "SEVERE"]
col_fc = [C_LGREY, C_GREEN_LT, C_ORANGE_LT, C_RED_LT]
col_hc = [C_MGREY, C_GREEN, C_ORANGE, C_RED]
sev_cw = [58, 38, 44, 40]
sev_rows = [
["pH", "7.25–7.30", "7.00–7.24", "< 7.00"],
["HCO3- (mEq/L)", "15–18", "10–14", "< 10"],
["Beta-OHB", "3–6 mmol/L", "6–10 mmol/L", "> 10 mmol/L"],
["Mental status", "Alert", "Alert/Drowsy", "Stupor/Coma"],
]
row_h_s = 11
# header row
cx_acc = cA_x
for ci, (cl, cw, fc, hc) in enumerate(zip(col_labels, sev_cw, col_fc, col_hc)):
filled_rect(cv, cx_acc, y-row_h_s, cw, row_h_s, hc)
txt(cv, cx_acc+cw/2, y-row_h_s+3, cl, "Helvetica-Bold", 6, C_WHITE, "center")
cx_acc += cw
y -= row_h_s
for ri, row in enumerate(sev_rows):
cx_acc = cA_x
for ci, (cell, cw, fc) in enumerate(zip(row, sev_cw, col_fc)):
bg = C_LGREY if ri%2==0 else C_WHITE
if ci > 0: bg = col_fc[ci]
cv.setFillColor(bg); cv.setStrokeColor(colors.HexColor("#CBD0D8")); cv.setLineWidth(0.3)
cv.rect(cx_acc, y-row_h_s, cw, row_h_s, fill=1, stroke=1)
fnt = "Helvetica-Bold" if ci==0 else "Helvetica"
txt(cv, cx_acc+cw/2, y-row_h_s+3, cell, fnt, 6, C_DARK, "center")
cx_acc += cw
y -= row_h_s
y -= 3
# Section: PRECIPITANTS
hdr(cv, cA_x, y-13, cA_w, 13, "▶ COMMON PRECIPITANTS", fc=C_RED, size=7.5)
y -= 14
prec = [
("🔴", "Infection (most common) — cultures, CXR, WBC"),
("🟠", "Insulin omission / non-adherence"),
("🟡", "New-onset T1DM"),
("🟣", "Acute MI (may be silent — get ECG)"),
("🔵", "SGLT2-inhibitor → euglycemic DKA (glucose can be normal!)"),
("⚫", "PE, pancreatitis, CVA, alcohol, steroids"),
]
rr(cv, cA_x, y-len(prec)*9-2, cA_w, len(prec)*9+2, r=3, fc=C_LGREY, sc=colors.HexColor("#BDC3C7"), lw=0.5)
for i, (icon, line) in enumerate(prec):
txt(cv, cA_x+4, y-7-i*9, icon+" "+line, "Helvetica", 6.2, C_DARK)
y -= len(prec)*9 + 5
# ═══════════════════════════════════════════════════════════════
# COLUMN B — Potassium Decision Tree + Insulin
# ═══════════════════════════════════════════════════════════════
y = TOP
hdr(cv, cB_x, y-13, cB_w, 13, "▶ POTASSIUM — CRITICAL GATE BEFORE INSULIN", fc=C_RED, size=7.5)
y -= 14
# Mini potassium flow
rr(cv, cB_x, y-12, cB_w, 12, r=3, fc=C_YELLOW_LT, sc=C_YELLOW, lw=1)
txt(cv, cB_x+cB_w/2, y-8.5, "CHECK SERUM K+ (from VBG or labs) — before starting insulin",
"Helvetica-Bold", 6.5, C_DARK, "center")
y -= 14
arrow(cv, cB_x+cB_w/2, y, cB_x+cB_w/2, y-7, C_DARK)
y -= 7
# Three K branches side by side
bw = 58; bh = 58; gap = 3
b_xs = [cB_x+1, cB_x+1+bw+gap, cB_x+1+2*(bw+gap)]
b_fcs= [C_RED_LT, C_GREEN_LT, C_ORANGE_LT]
b_scs= [C_RED, C_GREEN, C_ORANGE]
b_titles = ["K+ < 3.3", "K+ 3.3 – 5.3", "K+ > 5.3"]
b_actions = [
["HOLD INSULIN",
"Give KCl 40 mEq/hr IV",
"Recheck q1h",
"Start insulin only",
"when K+ ≥ 3.3"],
["START INSULIN",
"Add KCl 20-40 mEq/L",
"to IV fluids",
"Target K+ 4.0-5.0",
"Recheck q2h"],
["HOLD POTASSIUM",
"Start insulin",
"K+ will fall with Rx",
"ECG monitor",
"Add K+ when < 5.3"],
]
for i, (bx, fc, sc, title, acts) in enumerate(zip(b_xs, b_fcs, b_scs, b_titles, b_actions)):
rr(cv, bx, y-bh, bw, bh, r=3, fc=fc, sc=sc, lw=1)
txt(cv, bx+bw/2, y-9, title, "Helvetica-Bold", 7, sc, "center")
for j, act in enumerate(acts):
fnt = "Helvetica-Bold" if j==0 else "Helvetica"
txt(cv, bx+bw/2, y-18-j*8, act, fnt, 6, C_DARK, "center")
y -= bh + 5
# ECG reminder
rr(cv, cB_x, y-10, cB_w, 10, r=2, fc=C_PURPLE_LT, sc=C_PURPLE, lw=0.7)
txt(cv, cB_x+4, y-7.5, "⚡ ECG: hyperK → peaked T, wide QRS | hypoK → flat T, U waves, long QT → arrhythmia!",
"Helvetica-Bold", 6, C_PURPLE)
y -= 12
# Section: INSULIN
hdr(cv, cB_x, y-13, cB_w, 13, "▶ INSULIN THERAPY", fc=C_PURPLE, size=7.5)
y -= 14
iv_lines = [
"IV Regular insulin: 0.1 u/kg/hr fixed infusion",
"Target fall: 2-3 mmol/L/hr (36-54 mg/dL/hr)",
"Glucose < 250: reduce to 0.05 u/kg/hr",
" + switch fluids to D5-10% + 0.45% NaCl",
"Target glucose: 140-200 mg/dL until resolved",
]
sc_lines = [
"SC rapid-acting (lispro/aspart) — NEW option",
"Mild-moderate DKA only if: alert +",
" haemodynamically stable + not vomiting",
"Evidence: equivalent to IV (meta-analysis 2024)",
]
# IV box
rr(cv, cB_x, y-len(iv_lines)*8-5, cB_w//2-2, len(iv_lines)*8+5, r=3, fc=C_PURPLE_LT, sc=C_PURPLE, lw=0.8)
txt(cv, cB_x+cB_w//4, y-6, "IV INSULIN (standard)", "Helvetica-Bold", 6.5, C_PURPLE, "center")
for i, ln in enumerate(iv_lines):
txt(cv, cB_x+3, y-14-i*8, ln, "Helvetica", 6, C_DARK)
# SC box
sc_x = cB_x + cB_w//2 + 2
sc_w = cB_w - cB_w//2 - 2
rr(cv, sc_x, y-len(iv_lines)*8-5, sc_w, len(iv_lines)*8+5, r=3, fc=C_GREEN_LT, sc=C_GREEN, lw=0.8)
txt(cv, sc_x+sc_w/2, y-6, "SC INSULIN (new 2024)", "Helvetica-Bold", 6.5, C_GREEN, "center")
for i, ln in enumerate(sc_lines):
txt(cv, sc_x+3, y-14-i*8, ln, "Helvetica", 6, C_DARK)
y -= len(iv_lines)*8 + 8
# Basal note
rr(cv, cB_x, y-10, cB_w, 10, r=2, fc=C_YELLOW_LT, sc=C_YELLOW, lw=0.7)
txt(cv, cB_x+4, y-7.5,
"★ Continue / add basal insulin alongside IV infusion (ADA 2025 / JBDS)",
"Helvetica-Oblique", 6, C_YELLOW)
y -= 13
# Section: TRANSITION
hdr(cv, cB_x, y-12, cB_w, 12, "▶ TRANSITION TO SC INSULIN", fc=C_TEAL, size=7)
y -= 13
trans = [
"Patient eating + alert + DKA resolved",
"Give SC rapid-acting + basal FIRST",
"Wait 1-2 hrs THEN stop IV infusion",
"Dose: 70-80% of 24-hr IV total as basal+bolus",
]
rr(cv, cB_x, y-len(trans)*8-3, cB_w, len(trans)*8+3, r=3, fc=C_TEAL_LT, sc=C_TEAL, lw=0.8)
for i, ln in enumerate(trans):
txt(cv, cB_x+4, y-8-i*8, "• "+ln, "Helvetica", 6.2, C_DARK)
y -= len(trans)*8 + 6
# ═══════════════════════════════════════════════════════════════
# COLUMN C — Fluids, Monitoring, Resolution, Special Situations
# ═══════════════════════════════════════════════════════════════
y = TOP
# FLUIDS
hdr(cv, cC_x, y-13, cC_w, 13, "▶ IV FLUID RESUSCITATION", fc=C_TEAL, size=7.5)
y -= 14
fluid_rows = [
("Hour 1", "0.9% NaCl 1000 mL/hr", "Bolus 10-20 mL/kg if shock", C_BLUE_LT),
("Hours 2-8", "0.9% NaCl or balanced crystal", "250-500 mL/hr; adjust by UO", C_TEAL_LT),
("Glu<250", "D5-10% + 0.45% NaCl", "Never stop insulin! Add dextrose", C_ORANGE_LT),
]
fh = 12
fl_cw = [36, 70, 85]
fl_hdrs = ["Phase", "Fluid", "Notes"]
# header
fxacc = cC_x
for flh, flcw, fcc in zip(fl_hdrs, fl_cw, [C_TEAL, C_TEAL, C_TEAL]):
filled_rect(cv, fxacc, y-fh, flcw, fh, C_TEAL)
txt(cv, fxacc+flcw/2, y-fh+3.5, flh, "Helvetica-Bold", 6, C_WHITE, "center")
fxacc += flcw
y -= fh
for phase, fluid, note, fc in fluid_rows:
fxacc = cC_x
for cell, flcw in zip([phase, fluid, note], fl_cw):
cv.setFillColor(fc if fl_cw.index(flcw)>0 else C_LGREY)
cv.setStrokeColor(colors.HexColor("#CBD0D8")); cv.setLineWidth(0.3)
cv.rect(fxacc, y-fh, flcw, fh, fill=1, stroke=1)
txt(cv, fxacc+flcw/2, y-fh+3.5, cell, "Helvetica", 5.8, C_DARK, "center")
fxacc += flcw
y -= fh
y -= 4
# MONITORING
hdr(cv, cC_x, y-12, cC_w, 12, "▶ MONITORING FREQUENCY", fc=C_BLUE, size=7.5)
y -= 13
mon_items = [
("CBG", "q1h", "Target 140-200 mg/dL when stable"),
("Electrolytes/VBG", "q2-4h", "K+, HCO3-, anion gap each time"),
("Blood beta-OHB", "q2-4h", "Resolution: < 0.6 mmol/L"),
("Urine output", "Continuous","≥ 0.5 mL/kg/hr before giving K+"),
("ECG/cardiac mon.", "Continuous","Arrhythmia from K+ shifts"),
("Neuro status", "q1h", "Headache/bradycardia = cerebral edema?"),
]
mon_cw = [55, 35, 100]
rr(cv, cC_x, y-len(mon_items)*9-2, cC_w, len(mon_items)*9+2, r=3, fc=C_LGREY, sc=colors.HexColor("#BDC3C7"), lw=0.4)
for i, (param, freq, note) in enumerate(mon_items):
my = y - 8 - i*9
txt(cv, cC_x+3, my, param, "Helvetica-Bold", 6, C_DARK)
txt(cv, cC_x+58, my, freq, "Helvetica-Bold", 6, C_BLUE_MED)
txt(cv, cC_x+92, my, note, "Helvetica", 5.8, C_MGREY)
y -= len(mon_items)*9 + 5
# RESOLUTION CRITERIA
hdr(cv, cC_x, y-13, cC_w, 13, "▶ RESOLUTION CRITERIA (ALL 4 required)", fc=C_GREEN, size=7.5)
y -= 14
res_items = [
("1.", "Blood glucose", "< 200 mg/dL (11.1 mmol/L)"),
("2.", "Serum HCO3-", "≥ 18 mEq/L"),
("3.", "Venous pH", "> 7.3"),
("4.", "Blood beta-OHB", "< 0.6 mmol/L ★ preferred criterion"),
]
rr(cv, cC_x, y-len(res_items)*9-4, cC_w, len(res_items)*9+4, r=3, fc=C_GREEN_LT, sc=C_GREEN, lw=0.8)
for i, (num, param, val) in enumerate(res_items):
ry2 = y - 8 - i*9
txt(cv, cC_x+4, ry2, num, "Helvetica-Bold", 7, C_GREEN)
txt(cv, cC_x+14, ry2, param, "Helvetica-Bold", 6.5, C_DARK)
txt(cv, cC_x+14, ry2-8, " → "+val, "Helvetica", 6, C_DARK)
y -= len(res_items)*9 + 7
# SPECIAL ALERTS
hdr(cv, cC_x, y-13, cC_w, 13, "▶ SPECIAL ALERTS", fc=C_RED, size=7.5)
y -= 14
alerts = [
("⚠", "CEREBRAL EDEMA", C_RED_LT, C_RED,
"Headache+slow HR in Rx → mannitol 0.5-1g/kg OR 3% NaCl"),
("⚠", "EUGLYCEMIC DKA", C_ORANGE_LT, C_ORANGE,
"SGLT2i use → normal glucose, high AG acidosis → start D5 early"),
("⚠", "BICARB USE", C_PURPLE_LT, C_PURPLE,
"Only if pH < 6.9 → 100 mEq NaHCO3 + 20 mEq KCl over 2 hrs"),
("⚠", "PREGNANCY", C_BLUE_LT, C_BLUE,
"Target glucose 100-140 mg/dL; fetal monitoring; OB consult"),
]
for i, (icon, title, fc, sc, detail) in enumerate(alerts):
ay = y - 3 - i*20
rr(cv, cC_x, ay-16, cC_w, 16, r=3, fc=fc, sc=sc, lw=0.8)
txt(cv, cC_x+4, ay-8, icon+" "+title+":", "Helvetica-Bold", 6.5, sc)
txt(cv, cC_x+4, ay-15, " "+detail, "Helvetica", 5.8, C_DARK)
y -= len(alerts)*20 + 5
# ═══════════════════════════════════════════════════════════════
# FOOTER
# ═══════════════════════════════════════════════════════════════
filled_rect(cv, 0, 0, W, 13, C_NAVY)
txt(cv, W/2, 4, "ADA/EASD/JBDS 2024 Consensus | ADA Standards of Care 2025 | For clinical reference — apply individual patient judgement | Orris Medical AI",
"Helvetica", 5.5, C_WHITE, "center")
cv.save()
print(f"Pocket card saved: {out}")
build()
cd /tmp/workspace/dka-flowchart && python dka_pocket_card.py 2>&1
ls -lh /tmp/workspace/dka-flowchart/
DKA Pocket Reference Card
PDF Document · PDF