Skip to content

Secondary Manager Relationships

Overview

Secondary manager relationships represent non-primary reporting lines between people in an org chart. These include dotted-line managers, advisory roles, committee memberships, project-based reporting, and mentorship connections.

Unlike primary manager relationships (stored as managerId on each person), secondary relationships are stored in a separate org_chart_relationships table and rendered visually as dashed lines or text sections depending on the template.

Database Schema

org_chart_relationships table

ColumnTypeDescription
idUUIDPrimary key
org_chart_idUUIDFK to org_charts
person_idUUIDFK to org_chart_people (from)
related_person_idUUIDFK to org_chart_people (to)
relationship_typeTEXTOne of: dotted_line, advisory, committee, project, mentor
labelTEXTOptional human-readable label (e.g., β€œBudget Oversight”)
created_atTIMESTAMPTZAuto-set

API Endpoints

Relationships are fetched and passed to templates automatically when generating org charts:

  • GET /api/orgcharts/:id/people - Returns people and relationships
  • POST /api/orgcharts/:id/relationships - Create a relationship
  • DELETE /api/orgcharts/:id/relationships/:relId - Remove a relationship

The API transforms snake_case DB fields to camelCase at the boundary:

  • person_id -> personId
  • related_person_id -> relatedPersonId
  • relationship_type -> relationshipType

Template Support Matrix

TemplateRendering StrategysupportsDottedLines
top-down-treeSVG overlaytrue
horizontal-treeSVG overlaytrue
photo-cardsSVG overlaytrue
detailed-cardsSVG overlaytrue
indented-listText sectiontrue
interactive-collapsibleText sectiontrue
compact-cardsText sectiontrue
condensed-textText sectiontrue
executive-profileText sectiontrue
department-groupedText section (existing)true
civic-accessibleN/A (redirect)false
radialN/A (redirect)false

Rendering Approaches

SVG Overlay (Tree/Visual Templates)

Used by templates that render nodes in a visual hierarchy layout.

How it works:

  1. Each person node in the HTML gets a data-person-id attribute
  2. After page load, client-side JavaScript finds matching nodes and draws dashed SVG paths between them
  3. Paths are quadratic bezier curves with arrow markers at the endpoints
  4. A visual legend shows which line colors map to which relationship types
  5. A visually-hidden (sr-only) summary provides the same data for screen readers

Components:

  • RELATIONSHIP_OVERLAY_CSS - Styles for the SVG overlay, legend, and screen-reader summary
  • buildRelationshipOverlayJs() - Client JS that draws the dashed lines
  • buildRelationshipLegendHtml() - Color-coded legend
  • buildScreenReaderRelationshipSummary() - Accessible text alternative

Behavior:

  • Lines redraw on window resize
  • Lines redraw on toggle events (for collapsible templates)
  • Hidden nodes (collapsed sections) are skipped
  • Lines have 70% opacity to avoid obscuring content

Text Section (Card/Grid/Text Templates)

Used by templates where nodes aren’t positioned in a spatial hierarchy.

How it works:

  1. A β€œSecondary Relationships” <section> is appended to the main content
  2. Each relationship is listed with names, direction arrows, and a colored type badge
  3. Fully accessible without JavaScript

Components:

  • buildRelationshipTextSection() - Generates the HTML section

Relationship Types and Colors

TypeColorHexUse Case
dotted_lineViolet#7c3aedSecondary reporting line
advisoryBlue#2563ebAdvisory/consulting role
committeeOrange#ea580cCommittee membership
projectPink#db2777Project-based reporting
mentorAmber#d97706Mentorship relationship

Controlling Visibility

Relationships are only rendered when both conditions are met:

  1. options.showDottedLines is true (set by user in chart options)
  2. relationships.length > 0 (there are actual relationships to show)

When showDottedLines is false, no relationship rendering occurs regardless of data.

Shared Utilities

All relationship rendering utilities live in workers/api/src/utils/html.ts:

  • RELATIONSHIP_OVERLAY_CSS - CSS constant
  • serializeRelationshipsJson() - Converts relationships to JSON for client JS
  • buildRelationshipOverlayJs() - SVG overlay JavaScript
  • buildRelationshipTextSection() - Text section HTML
  • buildRelationshipLegendHtml() - Visual legend HTML
  • buildScreenReaderRelationshipSummary() - Screen reader HTML
  • buildPersonById() - Helper to create person lookup map

Known Limitations

  1. SVG overlay positioning - Lines connect to node centers and use edge detection, but complex overlapping layouts may produce crossing lines
  2. Zoom interaction - SVG overlay redraws on resize but may briefly misalign during zoom animation
  3. Print - SVG overlay is hidden in print mode (@media print); only screen reader summary persists
  4. Performance - For charts with many relationships (50+), SVG rendering may cause brief layout shifts on load

Troubleshooting

Lines not appearing

  • Verify showDottedLines is true in the chart options
  • Check that relationships exist in the database for this org chart
  • Confirm both personId and relatedPersonId reference valid people in the chart
  • Check browser console for JavaScript errors

Lines pointing to wrong positions

  • Ensure data-person-id attributes are present on node elements
  • Check for duplicate person IDs in the data

Screen reader not announcing relationships

  • The sr-only section should contain relationship data
  • Verify role="complementary" is present on the hidden section