-
Notifications
You must be signed in to change notification settings - Fork 110
Spike: Resolve per-type graph styling off both selectors and element data #2111
Copy link
Copy link
Open
Labels
explorationIssues related to graph exploration, node & edge details, neighbor expansion, etcIssues related to graph exploration, node & edge details, neighbor expansion, etcinternalSignals that the team will work on this issue internally.Signals that the team will work on this issue internally.performanceIssues relating to performanceIssues relating to performanceready-for-humanNeeds human implementationNeeds human implementationtech debtIssues, typically tasks, that are mainly about cleaning up code that is problematic in some wayIssues, typically tasks, that are mainly about cleaning up code that is problematic in some way
Description
Activity
Metadata
Metadata
Assignees
Labels
explorationIssues related to graph exploration, node & edge details, neighbor expansion, etcIssues related to graph exploration, node & edge details, neighbor expansion, etcinternalSignals that the team will work on this issue internally.Signals that the team will work on this issue internally.performanceIssues relating to performanceIssues relating to performanceready-for-humanNeeds human implementationNeeds human implementationtech debtIssues, typically tasks, that are mainly about cleaning up code that is problematic in some wayIssues, typically tasks, that are mainly about cleaning up code that is problematic in some way
Goal
Validate an architecture that resolves per-type vertex/edge styling neither through per-type Cytoscape selectors nor through per-element
data()— so the canvas can be O(1) in style-context count (the #2104 win) and free of per-element display state (the #1887 reconciler's requirement), while making restyles explicit and cheap. This must be settled before the reconciler or further style work commits to an implementation, because #2104 (landed) and #1887 (planned) currently hold contradictory models of what an element carries.Background / why now
node[type="X"]) with a singlenode/edgerule reading precomputedge_*values offele.data(). Style-context count O(elements × selectors) → O(1); Cytoscape STYLE self-time ~88% → ~0% at 10k types. It is a deliberate stepping stone, not the durable end state.ge_*fields whose values are per-type yet copied per-element; the currentcy.json(cloneDeep(...))full-replace copies them all on every change.ge_*-on-elements reintroduces exactly the baked-in display state that defeats reference diffing — a color edit changes every element'sge_*→ new references → the reconciler sees "everything changed." Reconcile the graph canvas — stop rebuilding on every change #1887's body also still assumesnode[type="X"]selector-driven styles (pre-Schema view lockup from per-type Cytoscape style selectors in useGraphStyles #2104).The three-way constraint
A durable answer must satisfy all three at once:
Cytoscape natively offers only per-type selectors (fails #1) or per-element data (fails #2). The spike finds and validates the escape.
Hypothesis to validate (the "unifying bet")
Combine three moves so styling stops being smuggled through the element pipeline:
iconRegistry+useSyncExternalStorepattern) owns type→style; a thin bridge patches the stylesheet /ele.data()imperatively on change, outside React render, decoupled from element identity.cloneDeepfull-replace) so element data is diffed/patched, not rebuilt + cloned.Result: element data ≈ 1 class ref; style values live once per distinct style; restyle = patch one rule / the registry, no element rebuild. Both downsides dissolve.
Open questions the spike must answer
data(): a Cytoscape style function mapper (ele => typeStyleMap.get(ele.data('type'))) gives O(1) selectors + a shared type→style map + no per-element style data — and Reconcile the graph canvas — stop rebuilding on every change #1887 already proposes exactly this for edge labels. Why did Push node background-color to Cytoscape ele.data() with styled type atoms #1725 deliberately choosedata()string mappers over function mappers? Resolve this (function-mapper caching / perf cost?) — it decides between the function-mapper and class approaches.Expected Outcome
Out of Scope
Related Issues
data()conversion)Important
Internal only — this issue is maintained by the core team and is not accepting external contributions.