Skip to content

Add conditional styling for vertex and edge types - #1915

Open
jkemmererupgrade wants to merge 4 commits into
aws:mainfrom
jkemmererupgrade:conditional-styling-v2
Open

Add conditional styling for vertex and edge types#1915
jkemmererupgrade wants to merge 4 commits into
aws:mainfrom
jkemmererupgrade:conditional-styling-v2

Conversation

@jkemmererupgrade

@jkemmererupgrade jkemmererupgrade commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Description

Adds an optional conditional style per vertex and edge type. When a rendered entity's attribute satisfies a condition, an alternate style is layered on top of the base style — useful for flagging states (e.g. a Person node with known_bad = true) without defining a separate type.

  • One condition per type. The conditional pane in each style dialog reuses the base style controls and overrides only the fields you change; type-level fields (display name/description) stay in the base pane.
  • Condition = attribute + operator + value. Operators: =, !=, >, <, >=, <=, and matches — a *-wildcard text pattern (e.g. Jo*), where every other character is matched literally so regex metacharacters carry no special meaning. The text operators (=, !=, matches) have a case-sensitivity toggle, case-sensitive by default (conditions saved before the flag existed keep the original case-sensitive behavior). Comparison is otherwise type-aware and evaluated in JavaScript at render time: numeric when both sides are numbers, chronological when both parse as dates (handles ISO and non-ISO formats like M/D/YYYY), lexicographic otherwise. Matching is surfaced to Cytoscape via a conditionMet flag rather than Cytoscape's value-selector operators, which compare lexicographically / via parseFloat and mishandle dates.
  • Precedence. Selection, focus dimming, and hidden states always take visual priority over a conditional style (Cytoscape's order-based cascade).
  • Import / export / reset. Conditional styles ride the existing shared-file-envelope format and the styling storage, so they are saved, imported, and reset with no file-format version bump. In the selective import modal, a type that carries a condition shows a separate, independently selectable "conditional" tile right after its base tile (Base → When-met previews + the condition), so you can import a base style with or without its condition.

Reintegrated onto the current styling architecture after the node/edge styling sidebar was combined (#1914) and the styles cascade collapsed to a single user layer (#1981).

Validation

  • pnpm checks passes with no errors; pnpm test passes (2385 tests); pnpm coverage clears all thresholds without changing them.
  • A full headless-Cytoscape pipeline test drives condition evaluation + selector generation + the applied stylesheet and asserts only the matching entity receives the conditional color — covering numeric, ISO date, non-ISO (M/D/YYYY) date, boolean, and wildcard (matches) conditions.
  • Manually validated in a locally built Docker image against a live graph: styling only matching entities, correct non-ISO date comparison, wildcard matching, dialogs, and the selective import tiles.

Related Issues

Related to #1785 (property-based node styling). This is a partial step: it covers the single-condition case — differentiating entities that meet one condition (e.g. known_bad = true, or risk_score > 90 → red) — which handles the fraud use case the issue leads with. It does not yet cover the issue's other examples: mapping one property to several distinct icons (e.g. gender → distinct icons) or mapping a numeric property to a color gradient. Those would be follow-on work.

Check List

  • I confirm that my contribution is made under the terms of the Apache 2.0 license.
  • I have verified pnpm checks passes with no errors.
  • I have verified pnpm test passes with no failures.
  • I have covered new added functionality with unit tests if necessary.
  • I have updated documentation if necessary.

🤖 Generated with Claude Code

@jkemmererupgrade

Copy link
Copy Markdown
Contributor Author

Hey @kmcginnes, Thank you for merging the node-styling! I refactored the simple conditional styling PR I had to use the latest and put it up as a direct PR and closed mine. Style import and Export as you have it works and brings along the conditional styling as well.

@jkemmererupgrade

Copy link
Copy Markdown
Contributor Author

Applying conditional styling to a node:
Screenshot 2026-07-09 at 2 29 16 PM

Adds an optional per-type condition that layers an alternate style on matching vertices and edges. The condition is type-aware (numeric/string/boolean comparisons) and evaluated in JS at render time. Conditional styles are included in styling import, export, and reset. Updates docs/features/graph-view.md accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jkemmererupgrade
jkemmererupgrade force-pushed the conditional-styling-v2 branch from 123ab1f to b9c9658 Compare July 23, 2026 14:17
# Conflicts:
#	packages/graph-explorer/src/modules/StyleImport/EdgeStyleImportCard.tsx
#	packages/graph-explorer/src/modules/StyleImport/VertexStyleImportCard.tsx
…o conditional styling

Folds starts-with/ends-with/contains into a single *-wildcard "matches"
operator, plus an explicit case-sensitivity checkbox shared by =, !=, and
matches. Case sensitivity is a separate flag rather than a doubled operator
set or a symbol prefix, matching how regex/SQL/CSS keep it orthogonal to the
comparison itself.
…pdate

Cytoscape's data() setter merges by key and never clears a key a later
update simply omits. conditionMetData() returned {} whenever a condition
did not match, so once a node was stamped conditionMet: true, editing the
condition to no longer match it left the stale true in place until the
node was removed and re-added. Now the flag is always explicit (true or
false), never omitted, for every entity and every transition (condition
added, removed, or changed).
@jkemmererupgrade

jkemmererupgrade commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Updated to include the conditional styling as tiles in the import panel, fixed conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant