OBE Dashboard — Site Architecture Reference
Repo: haiderejaz6/ChE_Department
Live as: GitHub Pages, single-page static app (no build step, no bundler)
Directory structure
ChE_Department/
├── index.html # shell only: <head>, body markup, script/link tags
├── css/
│ ├── base.css # tokens, header, tabbar, shared layout/components
│ ├── dashboard.css # OBE Dashboard tab styles
│ ├── graph.css # Curriculum Graph tab styles
│ ├── ontology.css # ChE Ontology tab styles
│ └── responsive.css # the one @media(max-width:720px) block — MUST load
│ # last so its overrides win at narrow widths
├── js/
│ ├── data.js # pure data: PLOS_DEF, COURSES_EMBEDDED, Bloom's
│ │ # level defs, prereq edges — no logic
│ ├── shared.js # init(), switchTab(), semester filters, tooltip,
│ │ # markdown-viewer modal (used by graph panel)
│ ├── dashboard.js # Course Explorer, PLO Coverage Matrix, Bloom's charts
│ ├── graph.js # Curriculum Graph tab (cg* functions, prereq
│ │ # arrows, course detail panel)
│ └── ontology.js # ChE Ontology tab (cm*/kc* functions: curriculum
│ # view, knowledge graph, compare, knowledge-area
│ # overlap cloud)
├── courses/ # per-course outline markdown files (referenced by
│ # path pointer from data.json, not embedded)
├── data.json # generated by excel_to_json.py from Qalam_CLOs.xlsx
└── excel_to_json.py # pipeline script (lives outside this repo dir
# structure notes if applicable — confirm path)
Key architectural facts (don't relitigate these)
-
This is still one single-page app, not multiple pages.
css/andjs/
are just source-file organization for editing — they are not routes and
there is no navigation between them. Clicking a tab (Curriculum Graph /
OBE Dashboard / ChE Ontology) never changes the URL; it toggles the
hiddenclass on#tab-graph/#tab-dash/#tab-conceptsvia
switchTab()inshared.js. -
Deliberately NOT split into separate HTML pages per tab. Considered
and rejected: it would break shared state (the semester filter updates
all three tabs from one click viasetFilter()inshared.js), force
full page reloads instead of instant tab switches, reset D3 force-sim/
zoom state in the ontology view on every visit, and refetchdata.json
three times. Revisit only if tabs need to be independently linkable/
bookmarkable, or the app outgrows loading all JS upfront — not the case
currently. -
Plain
<script src>/<link>tags, no bundler. All JS files share
one global scope, exactly like the original single-file version — a
function indashboard.jscan freely call a function defined in
graph.jsorontology.js. This means:- Load order in
index.htmlmatters for anything that reassigns the
same global identifier at load time (rare — only happened once, see
below). It generally does NOT matter for normal function calls, since
those resolve at call time, long after all scripts have loaded. - Current
<script>order inindex.html:
data.js → shared.js → dashboard.js → graph.js → ontology.js,
followed by an inline<script>init();</script>as the very last tag
(soinit()can safely call functions defined in any of the other
files).
- Load order in
-
CSS load order matters for one reason:
responsive.cssmust load
last. It contains the single@media(max-width:720px)block from the
original file, which touches selectors across all four other CSS files.
It has to come afterbase.css/dashboard.css/graph.css/ontology.css
inindex.htmlfor its overrides to win on narrow viewports. -
data.jsonandcourses/stay exactly where they were. Fetch paths
(fetch("./data.json"), course markdown paths) are relative to
index.html's location, which hasn't moved — only the CSS/JS got pulled
into subfolders. -
One piece of dead code was removed during the split, on purpose: the
original file had two conflictingshowTipdefinitions (a 5-arg version
and a 2-arg version) where the second silently overwrote the first at
load time. Only the live 2-arg version was kept inshared.js. Zero
behavior change — just removed a shadowed, unreachable definition.
Where to add new code
- New chart/section in the OBE Dashboard tab →
js/dashboard.js+
css/dashboard.css, wire into the markup inside#tab-dashin
index.html. - New feature on the Curriculum Graph (e.g. new edge type, new panel
section) →js/graph.js+css/graph.css, inside#tab-graph. - New view/mode in ChE Ontology (currently: Curriculum View, Knowledge
Graph, Compare Courses, Knowledge Area Overlap) →js/ontology.js+
css/ontology.css, inside#tab-concepts, following the existing
cmSetView()pattern. - New embedded dataset (e.g. a new PLO taxonomy, new static list) →
js/data.js. - Anything that needs to run on every tab or affect cross-tab state (like
the semester filter did) →js/shared.js.
Known open items (carried over, unrelated to the split)
- Data quality issues flagged but unresolved: PHY-102 duplicate CLO array;
filename/course-code mismatches (HI-114, CHE-555/CHE-455, MGT-442/422);
CHE-103/CHE-222 near-duplicate content; MSE-226 reference list anomaly. - Prerequisites column not yet in the source Excel — being sourced from the
PEC 2023 Obsidian vault as a possibly-faster path.