Skip to content

[BUG] PDF takeoff: changing a measurement's color in Properties has no effect on the canvas or exports #299

Description

@arvildev

Observed on 9.7.0.

Repro: select a measurement (distance, polyline, area, volume, or count), open the Properties tab, click its color swatch, pick a different color. The picker's selected ring moves, but the measurement on the canvas keeps its group color. The annotated-PDF export keeps it too.

Root cause: the swatch writes color onto the measurement (frontend/src/modules/pdf-takeoff/TakeoffViewerModule.tsx:6205, via updateSelectedMeasurement at :3026), and the field even round-trips persistence (frontend/src/modules/pdf-takeoff/useMeasurementPersistence.ts:264, :324, :398). But the draw loop derives every measurement's color from its group only:

const color = GROUP_COLOR_MAP[m.group] || '#3B82F6';   // :1104

m.color is only consulted for annotation markup types (cloud, arrow, text, rectangle, highlight) via const annoColor = m.color || color; at :1229. The renderer behind the annotated-PDF export has the same split (frontend/src/features/takeoff/lib/takeoff-export.ts:250 group-only for measurements, :347 honors m.color for annotations). So the value is written, persisted, shown as selected in the picker, and never read by either measurement renderer (canvas or export).

Suggested fix: let the per-measurement color win over the group default in both renderers:

const color = m.color || GROUP_COLOR_MAP[m.group] || '#3B82F6';

One caveat: the persistence write path currently injects a default when no color was chosen (group_color: m.color || '#3B82F6' at frontend/src/modules/pdf-takeoff/useMeasurementPersistence.ts:264, same at :324), and hydration reads it back as color: r.group_color || undefined (:398). So after a save/reload cycle every measurement carries color even if the user never picked one. With the one-liner above, a reloaded measurement in a non-blue group would then paint in the injected default blue instead of its group color. The write path should stop injecting the default (persist the color only when the user set one) as part of the same fix, or the renderers will need to treat the stored default as unset.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions