-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/session colors #400
Conversation
…nges from that data
…into feature/session-colors
…into feature/session-colors
jest coverage report 🧪Total coverage
Show files with reduced coverage 🔻Reduced coverage
|
…ettings from front end
…ting type from setInitialAgentColors
src/index.ts
Outdated
@@ -28,6 +28,6 @@ export { | |||
} from "./simularium"; | |||
export { compareTimes, loadSimulariumFile } from "./util"; | |||
export { DEFAULT_CAMERA_SPEC } from "./constants"; | |||
export { AgentData } from "./simularium/types"; | |||
export type { AgentData } from "./simularium/types"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small bug fix folded in here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be included in the types imports up above and should be exported directly from "./simularium" like the rest of them are. probably should be it's own PR because currently it breaks running the viewer on main
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you, PR here.
examples/src/ColorPicker.tsx
Outdated
const appliedColors = uiDisplayData.map((agent) => { | ||
const newAgent = { ...agent }; | ||
if (agent.name === selectedAgent) { | ||
if (subAgent.includes("")) { | ||
newAgent.color = selectedColor; | ||
} | ||
const newDisplayStates = agent.displayStates.map( | ||
(state: any) => { | ||
if (subAgent.includes(state.id)) { | ||
return { | ||
...state, | ||
color: selectedColor, | ||
}; | ||
} | ||
return state; | ||
} | ||
); | ||
newAgent.displayStates = newDisplayStates; | ||
} | ||
return newAgent; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preview of front end work here in the test bed. Instead of passing in a colorChange
we send in a uiDisplayData
In pairing w @meganrm we decided to make the front end responsible for generating and storing this state, viewer just renders
src/viewport/index.tsx
Outdated
public changeAgentsColor(appliedColors: UIDisplayData): void { | ||
const colorSettings = | ||
this.selectionInterface.getIdsAndColorsFromUIData(appliedColors); | ||
colorSettings.forEach((setting) => { | ||
this.visGeometry.applyColorToAgents( | ||
setting.agentIds, | ||
setting.color | ||
); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function now takes in a snapshot of all the colors currently applied, rather than processing individual changes one at a time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good, I would pull out the AgentData fix into it's own PR and make sure the exports are consistent with how we're exporting all the other types from the system
…into feature/session-colors
For context for other reviewers, this is done, the fix has been merged into both main and this branch. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of concerns, none of which I have enough context on to be sure how concerned I should be. Approving to let you merge at your discretion.
examples/src/Viewer.tsx
Outdated
public setColorSelectionInfo = (appliedColors) => { | ||
this.setState({ | ||
...this.state, | ||
uiDisplayData: appliedColors, | ||
selectionStateInfo: { | ||
hiddenAgents: this.state.selectionStateInfo.hiddenAgents, | ||
highlightedAgents: | ||
this.state.selectionStateInfo.highlightedAgents, | ||
colorChange: colorChange, | ||
appliedColors: appliedColors, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting that state is now duplicated here. I don't have quite enough context on why this would be necessary, or whether this change would imply a similar duplication in the actual simularium-website code. But, particularly if it does, I'd ask a couple questions:
- If these two values got out of sync with each other, would that represent a meaningful UI state or be some sort of error?
- If it would be an error, could you get by with just one copy? e.g. could everything that's currently being driven by
uiDisplayData
instead be driven byappliedColors
? - It looks like both these state fields are related to props on
SimulariumViewer
(onUiDisplayDataChanged
,selectionStateInfo
). If the type of one now contains the other, could/should those paths be merged in the viewer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently no error will throw, but display will be incorrect if these two are out of sync after more than one color selection.
In the website we will be storing two possibilities for color state (so that we can toggle between default and user selections). The onUiDisplayDataChanged
callback will set the default value, and the user selections will be stored separately. The UI components and the redux selector for the selectionStateInfo
prop will grab the appropriate one without duplicating the state.
Here we could apply the suggestion from your second bullet, removing the uiDisplayData
property from viewerState
and driving everything with selectionStateInfo.appliedColors
, because we only ever track the current state and never re-apply the default. Not duplicating state = good. But we will be slightly less in sync with naming/conventions of website.
In regards to merging the paths related to onUiDisplayDataChanged
and selectionStateInfo
:
I did this initially, but it created issues. Essentially now onUiDisplayDataChanged
is for parsing new trajectories, whereas selectionStateInfo
is about for responding to user changes. Unlikely to merge the paths although open to feedback and also maybe in need of renaming/documenting?
src/test/SelectionInterface.test.ts
Outdated
@@ -232,7 +232,7 @@ describe("SelectionInterface module", () => { | |||
{ name: "D", tags: [] }, | |||
], | |||
hiddenAgents: [], | |||
colorChange: initialColorChanges, | |||
appliedColors: initialAppliedColors, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't appear to matter to these tests currently, but be careful: these tests are now taking the same copy of initialAppliedColors
by reference, and modifications made by one test could be visible to all the others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated to use spread operator
src/viewport/index.tsx
Outdated
appliedColors.forEach((agent) => { | ||
const agentIds = this.selectionInterface.getAgentIdsByNamesAndTags([ | ||
{ name: agent.name, tags: [] }, | ||
]); | ||
this.visGeometry.applyColorToAgents( | ||
agentIds, | ||
agent.color | ||
); | ||
|
||
agent.displayStates.forEach((state) => { | ||
const stateIds = | ||
this.selectionInterface.getAgentIdsByNamesAndTags([ | ||
{ name: agent.name, tags: [state.name] }, | ||
]); | ||
this.visGeometry.applyColorToAgents(stateIds, state.color); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Under the hood, applyColorToAgents
is calling VisGeometry.updateScene
, which looks like it may be expensive. Now that this call is happening in a loop, is there a way to ensure that the update just happens once, at the end of this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes and why not, its cleaner! Also even if updateScene
is relatively cheap (cheap enough to get called in every animate loop at least), it might get more expensive in some upcoming work on caching, so I like the idea of minimizing calls where we can.
colorAssignments.forEach((color) => { | ||
const newColorData = this.colorHandler.setColorForAgentTypes( | ||
color.agentIds, | ||
color.color | ||
); | ||
this.renderer.updateColors( | ||
newColorData.numberOfColors, | ||
newColorData.colorArray | ||
); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Time Estimate or Size
medium
related website branchs:
fix/update-ssi
-> a patch to bring website into alignment with this changesetfeature/color-session
-> the end goal for the feature in developmentAdvances #510 and #511
Problem
On the front end we need to be storing and applying sets of color changes (browser sessions, or re-applying default). Current code assumes one-color-change-at-a-time.
Solution
UIDisplayData
is a good existing data structure that conveys a snapshot of agent tree and its colors.In
SelectionStateInfo
colorChanges
have been replaced byappliedColors
of typeUIDisplayData
This is more consistent with the other parts of the selection object which serves as a snapshot of the selection state, rather than as a pass-through for a series of changes.
Keeping this change set small. Possible further changes would keep the
SelectionInterface
entries
object in sync with "rendered state"... Might be useful for writing changes out to new files, not needed right now for MVP.Type of change