From e5bc44347b09fa1b66556965d095c044462fc432 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 23 May 2024 09:27:51 -0700 Subject: [PATCH 01/27] add util for comparing new and old ui data to get color changes --- src/util.ts | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/util.ts b/src/util.ts index ac7d0140..ca04886f 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,6 +1,7 @@ import type { ISimulariumFile } from "./simularium/ISimulariumFile"; import JsonFileReader from "./simularium/JsonFileReader"; import BinaryFileReader from "./simularium/BinaryFileReader"; +import { ColorChange, UIDisplayData } from "./simularium"; export const compareTimes = ( time1: number, @@ -74,3 +75,40 @@ export function loadSimulariumFile(file: Blob): Promise { } }); } + +export const compareUIDataAndCreateColorChanges = ( + oldData: UIDisplayData, + newData: UIDisplayData +): ColorChange[] => { + const changes: ColorChange[] = []; + + newData.forEach((agent) => { + const oldAgent = oldData.find( + (oldAgent) => oldAgent.name === agent.name + ); + if (!oldAgent) return; + + if (oldAgent.color !== agent.color) { + changes.push({ + agent: { name: agent.name, tags: [] }, + color: agent.color, + }); + } + + agent.displayStates.forEach((newState) => { + const oldState = oldAgent.displayStates.find( + (state) => state.name === newState.name + ); + if (!oldState) return; + + if (newState.color !== oldState.color) { + changes.push({ + agent: { name: agent.name, tags: [newState.name] }, + color: newState.color, + }); + } + }); + }); + + return changes; +}; From 65985e3c44ce513c60e4f4b8865b01ef050c7e05 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 23 May 2024 09:32:55 -0700 Subject: [PATCH 02/27] take sessionUIData prop in viewport and add method to apply color changes from that data --- src/viewport/index.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 8169cf25..63208883 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -19,6 +19,7 @@ import { RenderStyle, VisGeometry, NO_AGENT } from "../visGeometry"; import { ColorChange } from "../simularium/SelectionInterface"; import FrameRecorder from "../simularium/FrameRecorder"; import { DEFAULT_FRAME_RATE } from "../constants"; +import { compareUIDataAndCreateColorChanges } from "../util"; export type PropColor = string | number | [number, number, number]; @@ -46,6 +47,7 @@ type ViewportProps = { lockedCamera?: boolean; onRecordedMovie?: (blob: Blob) => void; // providing this callback enables movie recording disableCache?: boolean; + sessionUIData?: UIDisplayData; } & Partial; const defaultProps = { @@ -313,6 +315,7 @@ class Viewport extends React.Component< showBounds, selectionStateInfo, lockedCamera, + sessionUIData, } = this.props; if (selectionStateInfo) { @@ -382,6 +385,9 @@ class Viewport extends React.Component< this.visGeometry.destroyGui(); } } + if (sessionUIData && prevProps.sessionUIData !== sessionUIData) { + this.receiveSessionUIData(sessionUIData); + } } public isClick = (thisClick: Click): boolean => { @@ -596,6 +602,16 @@ class Viewport extends React.Component< } } + private receiveSessionUIData(newData: UIDisplayData): void { + const oldData = this.selectionInterface.getUIDisplayData(); + if (isEqual(oldData, newData)) return; + + const colorChanges = compareUIDataAndCreateColorChanges(oldData, newData); + colorChanges.forEach((change) => { + this.changeAgentsColor(change); + }); + } + public animate(): void { const { simulariumController } = this.props; const { visData } = simulariumController; From 1b04d38c425f99cef6793dd4822683857cb78fb8 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Tue, 28 May 2024 10:20:39 -0700 Subject: [PATCH 03/27] throw error if ui data don't match --- src/util.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/util.ts b/src/util.ts index ca04886f..377cb426 100644 --- a/src/util.ts +++ b/src/util.ts @@ -86,7 +86,10 @@ export const compareUIDataAndCreateColorChanges = ( const oldAgent = oldData.find( (oldAgent) => oldAgent.name === agent.name ); - if (!oldAgent) return; + + if (!oldAgent) { + throw new Error(`Agent ${agent.name} not found in old data`); + } if (oldAgent.color !== agent.color) { changes.push({ @@ -99,7 +102,10 @@ export const compareUIDataAndCreateColorChanges = ( const oldState = oldAgent.displayStates.find( (state) => state.name === newState.name ); - if (!oldState) return; + + if (!oldState) { + throw new Error(`Agent ${newState.name} not found in old data`); + } if (newState.color !== oldState.color) { changes.push({ From 130044bfdea6d252a73adc499efb07faaf3f7e02 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Wed, 5 Jun 2024 09:27:23 -0700 Subject: [PATCH 04/27] don't throw errors when ui data doesn't match session data --- src/util.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/util.ts b/src/util.ts index 377cb426..25193bfe 100644 --- a/src/util.ts +++ b/src/util.ts @@ -88,7 +88,8 @@ export const compareUIDataAndCreateColorChanges = ( ); if (!oldAgent) { - throw new Error(`Agent ${agent.name} not found in old data`); + console.log(`Agent ${agent.name} not found in old data`); + return []; } if (oldAgent.color !== agent.color) { @@ -104,7 +105,10 @@ export const compareUIDataAndCreateColorChanges = ( ); if (!oldState) { - throw new Error(`Agent ${newState.name} not found in old data`); + console.log( + `Agent state ${newState.name} not found in old data` + ); + return []; } if (newState.color !== oldState.color) { From 687e4f31749f6c2d304c4cec4629b8383728a2a9 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Wed, 5 Jun 2024 09:27:42 -0700 Subject: [PATCH 05/27] call receiveSessionUIData in onTrajectoryFileInfo --- src/viewport/index.tsx | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 7024afad..fe6a3e8f 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -176,6 +176,7 @@ class Viewport extends React.Component< onUIDisplayDataChanged, onError, agentColors, + sessionUIData, } = this.props; // Update TrajectoryFileInfo format to latest version @@ -234,6 +235,9 @@ class Viewport extends React.Component< } onUIDisplayDataChanged(this.selectionInterface.getUIDisplayData()); + if (sessionUIData) { + this.receiveSessionUIData(sessionUIData); + } } public componentDidMount(): void { @@ -391,9 +395,6 @@ class Viewport extends React.Component< this.visGeometry.destroyGui(); } } - if (sessionUIData && prevProps.sessionUIData !== sessionUIData) { - this.receiveSessionUIData(sessionUIData); - } } public isClick = (thisClick: Click): boolean => { @@ -610,9 +611,13 @@ class Viewport extends React.Component< private receiveSessionUIData(newData: UIDisplayData): void { const oldData = this.selectionInterface.getUIDisplayData(); - if (isEqual(oldData, newData)) return; - - const colorChanges = compareUIDataAndCreateColorChanges(oldData, newData); + // possible that is equal is expensive, and we might as well just run through everything + if (isEqual(oldData, newData)) return; + + const colorChanges = compareUIDataAndCreateColorChanges( + oldData, + newData + ); colorChanges.forEach((change) => { this.changeAgentsColor(change); }); From 40d9425f0aa2708b80ffc66c72c2dc1162b3d0d8 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Mon, 10 Jun 2024 15:36:25 -0700 Subject: [PATCH 06/27] use controller methods to handle color changes --- src/controller/index.ts | 16 ++++++ src/simularium/SelectionInterface.ts | 57 ++++++++++++++++++-- src/util.ts | 48 ----------------- src/viewport/index.tsx | 80 +++++++++++++++------------- src/visGeometry/index.ts | 7 ++- src/visGeometry/types.ts | 5 ++ 6 files changed, 122 insertions(+), 91 deletions(-) diff --git a/src/controller/index.ts b/src/controller/index.ts index 8998779c..153af1e9 100644 --- a/src/controller/index.ts +++ b/src/controller/index.ts @@ -2,8 +2,10 @@ import jsLogger from "js-logger"; import { isEmpty, noop } from "lodash"; import { VisData, RemoteSimulator } from "../simularium"; import type { + ColorChange, NetConnectionParams, TrajectoryFileInfo, + UIDisplayData, VisDataMessage, } from "../simularium"; import { VisGeometry } from "../visGeometry"; @@ -55,6 +57,8 @@ export default class SimulariumController { public startRecording: () => void; public stopRecording: () => void; public onError?: (error: FrontEndError) => void; + public handleColorSettings?: (settings: UIDisplayData) => void; + public handleColorChange?: (colorChange: ColorChange) => void; private networkEnabled: boolean; private isPaused: boolean; @@ -70,6 +74,8 @@ export default class SimulariumController { this.handleTrajectoryInfo = (/*msg: TrajectoryFileInfo*/) => noop; this.onError = (/*errorMessage*/) => noop; + this.handleColorSettings = (/*settings: ColorSetting[]*/) => noop; + this.handleColorChange = (/*colorChange: ColorChange*/) => noop; // might only be used in unit testing // TODO: change test so controller isn't initialized with a remoteSimulator @@ -118,6 +124,8 @@ export default class SimulariumController { this.setFocusMode = this.setFocusMode.bind(this); this.convertTrajectory = this.convertTrajectory.bind(this); this.setCameraType = this.setCameraType.bind(this); + this.applyColorSettings = this.applyColorSettings.bind(this); + this.applyColorChange = this.applyColorChange.bind(this); } private createSimulatorConnection( @@ -559,6 +567,14 @@ export default class SimulariumController { public setCameraType(ortho: boolean): void { this.visGeometry?.setCameraType(ortho); } + + public applyColorSettings(uiData: UIDisplayData): void { + this.handleColorSettings?.(uiData); + } + + public applyColorChange(colorChange: ColorChange): void { + this.handleColorChange?.(colorChange); + } } export { SimulariumController }; diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 3f561c58..cff92a6c 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -1,6 +1,7 @@ import { filter, find, map, uniq } from "lodash"; import { EncodedTypeMapping } from "./types"; import { convertColorNumberToString } from "../visGeometry/ColorHandler"; +import { ColorSetting } from "../visGeometry/types"; // An individual entry parsed from an encoded name // The encoded names can be just a name or a name plus a @@ -301,7 +302,7 @@ class SelectionInterface { public setInitialAgentColors( uiDisplayData: UIDisplayData, colors: (string | number)[], - setColorForIds: (ids: number[], color: string | number) => void + setColorForIds: (setting: ColorSetting) => void ): (string | number)[] { let defaultColorIndex = 0; uiDisplayData.forEach((group) => { @@ -317,7 +318,10 @@ class SelectionInterface { if (!hasNewColors) { // if no colors have been set by the user for this name, // just give all states of this agent name the same color - setColorForIds(ids, colors[defaultColorIndex]); + setColorForIds({ + agentIds: ids, + color: colors[defaultColorIndex], + }); this.updateUiDataColor( group.name, ids, @@ -355,7 +359,10 @@ class SelectionInterface { } else { groupColorIndex = -1; } - setColorForIds([ids[index]], colors[agentColorIndex]); + setColorForIds({ + agentIds: [ids[index]], + color: colors[agentColorIndex], + }); }); } if (groupColorIndex > -1) { @@ -376,6 +383,50 @@ class SelectionInterface { }); return colors; } + + // when applying color changes or settings, keep entries in sync + // it is the SSOT for UiDisplayData + public updateAgentColors(setting: ColorSetting): void { + const { agentIds, color } = setting; + const newColor = convertColorNumberToString(color); + agentIds.forEach((id) => { + Object.values(this.entries).forEach((entry) => { + entry.forEach((displayState) => { + if (displayState.id === id) { + displayState.color = newColor; + } + }); + }); + }); + } + + // seems like a util + public deriveColorSettingsFromUIData = ( + uiData: UIDisplayData + ): ColorSetting[] => { + const settings: ColorSetting[] = []; + + uiData.forEach((agent) => { + settings.push({ + agentIds: this.getAgentIdsByNamesAndTags([ + { name: agent.name, tags: [] }, + ]), + color: agent.color, + }); + // } + + agent.displayStates.forEach((newState) => { + settings.push({ + agentIds: this.getAgentIdsByNamesAndTags([ + { name: agent.name, tags: [newState.name] }, + ]), + color: newState.color, + }); + }); + }); + + return settings; + }; } export { SelectionInterface }; diff --git a/src/util.ts b/src/util.ts index 25193bfe..ac7d0140 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,7 +1,6 @@ import type { ISimulariumFile } from "./simularium/ISimulariumFile"; import JsonFileReader from "./simularium/JsonFileReader"; import BinaryFileReader from "./simularium/BinaryFileReader"; -import { ColorChange, UIDisplayData } from "./simularium"; export const compareTimes = ( time1: number, @@ -75,50 +74,3 @@ export function loadSimulariumFile(file: Blob): Promise { } }); } - -export const compareUIDataAndCreateColorChanges = ( - oldData: UIDisplayData, - newData: UIDisplayData -): ColorChange[] => { - const changes: ColorChange[] = []; - - newData.forEach((agent) => { - const oldAgent = oldData.find( - (oldAgent) => oldAgent.name === agent.name - ); - - if (!oldAgent) { - console.log(`Agent ${agent.name} not found in old data`); - return []; - } - - if (oldAgent.color !== agent.color) { - changes.push({ - agent: { name: agent.name, tags: [] }, - color: agent.color, - }); - } - - agent.displayStates.forEach((newState) => { - const oldState = oldAgent.displayStates.find( - (state) => state.name === newState.name - ); - - if (!oldState) { - console.log( - `Agent state ${newState.name} not found in old data` - ); - return []; - } - - if (newState.color !== oldState.color) { - changes.push({ - agent: { name: agent.name, tags: [newState.name] }, - color: newState.color, - }); - } - }); - }); - - return changes; -}; diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index fe6a3e8f..d274bef6 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -15,11 +15,15 @@ import { import { TrajectoryFileInfoAny } from "../simularium/types"; import { updateTrajectoryFileInfoFormat } from "../simularium/versionHandlers"; import { FrontEndError, ErrorLevel } from "../simularium/FrontEndError"; -import { RenderStyle, VisGeometry, NO_AGENT } from "../visGeometry"; +import { + RenderStyle, + VisGeometry, + NO_AGENT, +} from "../visGeometry"; import { ColorChange } from "../simularium/SelectionInterface"; import FrameRecorder from "../simularium/FrameRecorder"; import { DEFAULT_FRAME_RATE } from "../constants"; -import { compareUIDataAndCreateColorChanges } from "../util"; +import { ColorSetting } from "../visGeometry/types"; export type PropColor = string | number | [number, number, number]; @@ -36,7 +40,10 @@ type ViewportProps = { onTrajectoryFileInfoChanged: ( cachedData: TrajectoryFileInfo ) => void | undefined; - onUIDisplayDataChanged: (data: UIDisplayData) => void | undefined; + onUIDisplayDataChanged: ( + data: UIDisplayData, + setDefault?: boolean + ) => void | undefined; loadInitialData: boolean; hideAllAgents: boolean; showPaths: boolean; @@ -233,10 +240,12 @@ class Viewport extends React.Component< if (!isEqual(updatedColors, agentColors)) { this.visGeometry.createMaterials(updatedColors); } - - onUIDisplayDataChanged(this.selectionInterface.getUIDisplayData()); + onUIDisplayDataChanged( + this.selectionInterface.getUIDisplayData(), + /* set default UI Data: */ true + ); if (sessionUIData) { - this.receiveSessionUIData(sessionUIData); + this.handleColorSettings(sessionUIData); } } @@ -277,6 +286,10 @@ class Viewport extends React.Component< }; simulariumController.startRecording = this.startRecording.bind(this); simulariumController.stopRecording = this.stopRecording.bind(this); + simulariumController.handleColorSettings = + this.handleColorSettings.bind(this); + simulariumController.handleColorChange = + this.handleColorChange.bind(this); if (this.vdomRef.current) { this.vdomRef.current.addEventListener( @@ -320,7 +333,6 @@ class Viewport extends React.Component< selectionStateInfo, lockedCamera, disableCache, - sessionUIData, } = this.props; if (selectionStateInfo) { @@ -346,15 +358,6 @@ class Viewport extends React.Component< this.selectionInterface.getHiddenIds(selectionStateInfo); this.visGeometry.setVisibleByIds(hiddenIds); } - if ( - !isEqual( - selectionStateInfo.colorChange, - prevProps.selectionStateInfo.colorChange - ) && - selectionStateInfo.colorChange !== null - ) { - this.changeAgentsColor(selectionStateInfo.colorChange); - } } // note that if the system does not support the molecular render style, then @@ -594,12 +597,31 @@ class Viewport extends React.Component< } } - public changeAgentsColor(colorChange: ColorChange): void { - const { agent, color } = colorChange; - const agentIds = this.selectionInterface.getAgentIdsByNamesAndTags([ - agent, - ]); - this.visGeometry.applyColorToAgents(agentIds, color); + public changeAgentsColor(colorSettings: ColorSetting[]): void { + const { onUIDisplayDataChanged } = this.props; + colorSettings.forEach((setting) => { + this.visGeometry.applyColorToAgents(setting); + this.selectionInterface.updateAgentColors(setting); + }); + onUIDisplayDataChanged(this.selectionInterface.getUIDisplayData()); + } + + public handleColorChange(colorChange: ColorChange): void { + const colorSetting = { + agentIds: this.selectionInterface.getAgentIdsByNamesAndTags([ + colorChange.agent, + ]), + color: colorChange.color, + }; + this.changeAgentsColor([colorSetting]); + } + + private handleColorSettings(newData: UIDisplayData): void { + const oldData = this.selectionInterface.getUIDisplayData(); + if (isEqual(oldData, newData)) return; + const colorSettings = + this.selectionInterface.deriveColorSettingsFromUIData(newData); + this.changeAgentsColor(colorSettings); } public stopAnimate(): void { @@ -609,20 +631,6 @@ class Viewport extends React.Component< } } - private receiveSessionUIData(newData: UIDisplayData): void { - const oldData = this.selectionInterface.getUIDisplayData(); - // possible that is equal is expensive, and we might as well just run through everything - if (isEqual(oldData, newData)) return; - - const colorChanges = compareUIDataAndCreateColorChanges( - oldData, - newData - ); - colorChanges.forEach((change) => { - this.changeAgentsColor(change); - }); - } - public animate(): void { const { simulariumController } = this.props; const { visData } = simulariumController; diff --git a/src/visGeometry/index.ts b/src/visGeometry/index.ts index 6ad77a5f..00c5c84b 100644 --- a/src/visGeometry/index.ts +++ b/src/visGeometry/index.ts @@ -54,6 +54,7 @@ import { LegacyRenderer } from "./rendering/LegacyRenderer"; import GeometryStore from "./GeometryStore"; import { AgentGeometry, + ColorSetting, GeometryDisplayType, GeometryInstanceContainer, MeshGeometry, @@ -1104,10 +1105,8 @@ class VisGeometry { this.setAgentColors(); } - public applyColorToAgents( - agentIds: number[], - color: string | number - ): void { + public applyColorToAgents(setting: ColorSetting): void { + const { agentIds, color } = setting; const newColorData = this.colorHandler.setColorForAgentTypes( agentIds, color diff --git a/src/visGeometry/types.ts b/src/visGeometry/types.ts index 85e998f7..f8c8a35c 100644 --- a/src/visGeometry/types.ts +++ b/src/visGeometry/types.ts @@ -69,3 +69,8 @@ export interface AgentColorInfo { color: Color; colorId: number; } + +export interface ColorSetting { + agentIds: number[]; + color: string | number; +} From 4ca212355f2e4d86b1a9bd2bac57f0e6878698ce Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Mon, 10 Jun 2024 16:09:24 -0700 Subject: [PATCH 07/27] remove ColorChange from SelectionStateInfo --- src/simularium/SelectionInterface.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index cff92a6c..a4d582f2 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -26,7 +26,6 @@ export interface ColorChange { export interface SelectionStateInfo { highlightedAgents: SelectionEntry[]; hiddenAgents: SelectionEntry[]; - colorChange: ColorChange | null; } interface DisplayStateEntry { From fc3f96f096cfdc44ea80a343e0f9b752d04a7a0f Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Mon, 8 Jul 2024 09:14:20 -0700 Subject: [PATCH 08/27] initial consolidation of updateAgentColors and updateUiDataColor --- src/simularium/SelectionInterface.ts | 58 ++++++++++++++-------------- src/viewport/index.tsx | 3 +- src/visGeometry/types.ts | 1 + 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index a4d582f2..97bb66c9 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -283,19 +283,31 @@ class SelectionInterface { }); } - private updateUiDataColor( - agentName: string, + // to do this is blended version of two functions + // could maybe be optimized and typing adjusted/done better + public updateUiDataColor( idsToUpdate: number[], - color: number | string + color: number | string, + agentName?: string ): void { const newColor = convertColorNumberToString(color); - const entry = this.entries[agentName]; - // if no display state update parent color - entry.forEach((displayState) => { - if (idsToUpdate.includes(displayState.id)) { - displayState.color = newColor; - } - }); + if (agentName !== undefined) { + const entry = this.entries[agentName]; + // if no display state update parent color + entry.forEach((displayState) => { + if (idsToUpdate.includes(displayState.id)) { + displayState.color = newColor; + } + }); + } else { + Object.values(this.entries).forEach((entry) => { + entry.forEach((displayState) => { + if (idsToUpdate.includes(displayState.id)) { + displayState.color = newColor; + } + }); + }); + } } public setInitialAgentColors( @@ -322,9 +334,9 @@ class SelectionInterface { color: colors[defaultColorIndex], }); this.updateUiDataColor( - group.name, ids, - colors[defaultColorIndex] + colors[defaultColorIndex], + group.name ); } else { // otherwise, we need to update any user defined colors @@ -345,9 +357,9 @@ class SelectionInterface { } else { // need update the display data with the default color being used this.updateUiDataColor( - group.name, [ids[index]], - colors[groupColorIndex] + colors[groupColorIndex], + group.name ); } // if the user used all the same colors for all states of this agent, @@ -383,22 +395,6 @@ class SelectionInterface { return colors; } - // when applying color changes or settings, keep entries in sync - // it is the SSOT for UiDisplayData - public updateAgentColors(setting: ColorSetting): void { - const { agentIds, color } = setting; - const newColor = convertColorNumberToString(color); - agentIds.forEach((id) => { - Object.values(this.entries).forEach((entry) => { - entry.forEach((displayState) => { - if (displayState.id === id) { - displayState.color = newColor; - } - }); - }); - }); - } - // seems like a util public deriveColorSettingsFromUIData = ( uiData: UIDisplayData @@ -411,6 +407,7 @@ class SelectionInterface { { name: agent.name, tags: [] }, ]), color: agent.color, + name: agent.name, }); // } @@ -420,6 +417,7 @@ class SelectionInterface { { name: agent.name, tags: [newState.name] }, ]), color: newState.color, + name: newState.name, }); }); }); diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 5a6207f3..ef667d4d 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -610,7 +610,7 @@ class Viewport extends React.Component< const { onUIDisplayDataChanged } = this.props; colorSettings.forEach((setting) => { this.visGeometry.applyColorToAgents(setting); - this.selectionInterface.updateAgentColors(setting); + this.selectionInterface.updateUiDataColor(setting.agentIds, setting.color, setting.name); }); onUIDisplayDataChanged(this.selectionInterface.getUIDisplayData()); } @@ -621,6 +621,7 @@ class Viewport extends React.Component< colorChange.agent, ]), color: colorChange.color, + name: colorChange.agent.name }; this.changeAgentsColor([colorSetting]); } diff --git a/src/visGeometry/types.ts b/src/visGeometry/types.ts index f8c8a35c..0fc40d8a 100644 --- a/src/visGeometry/types.ts +++ b/src/visGeometry/types.ts @@ -73,4 +73,5 @@ export interface AgentColorInfo { export interface ColorSetting { agentIds: number[]; color: string | number; + name?: string; } From f3e081696b4eda7af5b40242ed0cff3a064f87de Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Wed, 10 Jul 2024 15:03:52 -0700 Subject: [PATCH 09/27] remove controller methods for applying color changes --- src/controller/index.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/controller/index.ts b/src/controller/index.ts index f3bacb4f..b07a0517 100644 --- a/src/controller/index.ts +++ b/src/controller/index.ts @@ -57,8 +57,6 @@ export default class SimulariumController { public startRecording: () => void; public stopRecording: () => void; public onError?: (error: FrontEndError) => void; - public handleColorSettings?: (settings: UIDisplayData) => void; - public handleColorChange?: (colorChange: ColorChange) => void; private networkEnabled: boolean; private isPaused: boolean; @@ -74,8 +72,6 @@ export default class SimulariumController { this.handleTrajectoryInfo = (/*msg: TrajectoryFileInfo*/) => noop; this.onError = (/*errorMessage*/) => noop; - this.handleColorSettings = (/*settings: ColorSetting[]*/) => noop; - this.handleColorChange = (/*colorChange: ColorChange*/) => noop; // might only be used in unit testing // TODO: change test so controller isn't initialized with a remoteSimulator @@ -124,8 +120,6 @@ export default class SimulariumController { this.setFocusMode = this.setFocusMode.bind(this); this.convertTrajectory = this.convertTrajectory.bind(this); this.setCameraType = this.setCameraType.bind(this); - this.applyColorSettings = this.applyColorSettings.bind(this); - this.applyColorChange = this.applyColorChange.bind(this); } private createSimulatorConnection( @@ -563,14 +557,6 @@ export default class SimulariumController { public setCameraType(ortho: boolean): void { this.visGeometry?.setCameraType(ortho); } - - public applyColorSettings(uiData: UIDisplayData): void { - this.handleColorSettings?.(uiData); - } - - public applyColorChange(colorChange: ColorChange): void { - this.handleColorChange?.(colorChange); - } } export { SimulariumController }; From d01589276eb7fca38ee2daa136690c03dac306f6 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Wed, 10 Jul 2024 15:10:27 -0700 Subject: [PATCH 10/27] go back to using SelectionStateInfo prop to receive and apply color settings from front end --- src/simularium/SelectionInterface.ts | 1 + src/viewport/index.tsx | 55 +++++++++++----------------- 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 97bb66c9..3222bcd5 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -26,6 +26,7 @@ export interface ColorChange { export interface SelectionStateInfo { highlightedAgents: SelectionEntry[]; hiddenAgents: SelectionEntry[]; + colorSettings: UIDisplayData; } interface DisplayStateEntry { diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index ef667d4d..8871e9b4 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -15,12 +15,7 @@ import { import { AgentData, TrajectoryFileInfoAny } from "../simularium/types"; import { updateTrajectoryFileInfoFormat } from "../simularium/versionHandlers"; import { FrontEndError, ErrorLevel } from "../simularium/FrontEndError"; -import { - RenderStyle, - VisGeometry, - NO_AGENT, -} from "../visGeometry"; -import { ColorChange } from "../simularium/SelectionInterface"; +import { RenderStyle, VisGeometry, NO_AGENT } from "../visGeometry"; import FrameRecorder from "../simularium/FrameRecorder"; import { DEFAULT_FRAME_RATE } from "../constants"; import { ColorSetting } from "../visGeometry/types"; @@ -41,8 +36,7 @@ type ViewportProps = { cachedData: TrajectoryFileInfo ) => void | undefined; onUIDisplayDataChanged: ( - data: UIDisplayData, - setDefault?: boolean + data: UIDisplayData ) => void | undefined; loadInitialData: boolean; hideAllAgents: boolean; @@ -242,12 +236,8 @@ class Viewport extends React.Component< this.visGeometry.createMaterials(updatedColors); } onUIDisplayDataChanged( - this.selectionInterface.getUIDisplayData(), - /* set default UI Data: */ true + this.selectionInterface.getUIDisplayData() ); - if (sessionUIData) { - this.handleColorSettings(sessionUIData); - } } public componentDidMount(): void { @@ -287,10 +277,6 @@ class Viewport extends React.Component< }; simulariumController.startRecording = this.startRecording.bind(this); simulariumController.stopRecording = this.stopRecording.bind(this); - simulariumController.handleColorSettings = - this.handleColorSettings.bind(this); - simulariumController.handleColorChange = - this.handleColorChange.bind(this); if (this.vdomRef.current) { this.vdomRef.current.addEventListener( @@ -359,6 +345,15 @@ class Viewport extends React.Component< this.selectionInterface.getHiddenIds(selectionStateInfo); this.visGeometry.setVisibleByIds(hiddenIds); } + if ( + !isEqual( + selectionStateInfo.colorSettings, + prevProps.selectionStateInfo.colorSettings + ) && + selectionStateInfo.colorSettings.length > 0 + ) { + this.handleColorSettings(selectionStateInfo.colorSettings); + } } // note that if the system does not support the molecular render style, then @@ -607,28 +602,22 @@ class Viewport extends React.Component< } public changeAgentsColor(colorSettings: ColorSetting[]): void { - const { onUIDisplayDataChanged } = this.props; + if (colorSettings.length === 0) { + return; + } colorSettings.forEach((setting) => { this.visGeometry.applyColorToAgents(setting); - this.selectionInterface.updateUiDataColor(setting.agentIds, setting.color, setting.name); + this.selectionInterface.updateUiDataColor( + setting.agentIds, + setting.color, + setting.name + ); }); - onUIDisplayDataChanged(this.selectionInterface.getUIDisplayData()); - } - - public handleColorChange(colorChange: ColorChange): void { - const colorSetting = { - agentIds: this.selectionInterface.getAgentIdsByNamesAndTags([ - colorChange.agent, - ]), - color: colorChange.color, - name: colorChange.agent.name - }; - this.changeAgentsColor([colorSetting]); } private handleColorSettings(newData: UIDisplayData): void { - const oldData = this.selectionInterface.getUIDisplayData(); - if (isEqual(oldData, newData)) return; + // color sessions to do: + // only process necessary changes const colorSettings = this.selectionInterface.deriveColorSettingsFromUIData(newData); this.changeAgentsColor(colorSettings); From 627c414e39a5faaa4cabe0720f08adfc68e5e6c9 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 15:33:35 -0700 Subject: [PATCH 11/27] csonsolidate changeAgentsColor and handler, and remove named ColorSetting type from setInitialAgentColors --- src/simularium/SelectionInterface.ts | 17 ++++----------- src/viewport/index.tsx | 31 ++++++++++++---------------- src/visGeometry/index.ts | 6 ++++-- 3 files changed, 21 insertions(+), 33 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 3222bcd5..ed5dc7c0 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -314,7 +314,7 @@ class SelectionInterface { public setInitialAgentColors( uiDisplayData: UIDisplayData, colors: (string | number)[], - setColorForIds: (setting: ColorSetting) => void + setColorForIds: (agentIds: number[], color: string | number) => void ): (string | number)[] { let defaultColorIndex = 0; uiDisplayData.forEach((group) => { @@ -330,10 +330,7 @@ class SelectionInterface { if (!hasNewColors) { // if no colors have been set by the user for this name, // just give all states of this agent name the same color - setColorForIds({ - agentIds: ids, - color: colors[defaultColorIndex], - }); + setColorForIds(ids, colors[defaultColorIndex]); this.updateUiDataColor( ids, colors[defaultColorIndex], @@ -359,8 +356,7 @@ class SelectionInterface { // need update the display data with the default color being used this.updateUiDataColor( [ids[index]], - colors[groupColorIndex], - group.name + colors[groupColorIndex] ); } // if the user used all the same colors for all states of this agent, @@ -371,10 +367,7 @@ class SelectionInterface { } else { groupColorIndex = -1; } - setColorForIds({ - agentIds: [ids[index]], - color: colors[agentColorIndex], - }); + setColorForIds([ids[index]], colors[agentColorIndex]); }); } if (groupColorIndex > -1) { @@ -410,7 +403,6 @@ class SelectionInterface { color: agent.color, name: agent.name, }); - // } agent.displayStates.forEach((newState) => { settings.push({ @@ -418,7 +410,6 @@ class SelectionInterface { { name: agent.name, tags: [newState.name] }, ]), color: newState.color, - name: newState.name, }); }); }); diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 8871e9b4..ca417cdc 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -35,9 +35,7 @@ type ViewportProps = { onTrajectoryFileInfoChanged: ( cachedData: TrajectoryFileInfo ) => void | undefined; - onUIDisplayDataChanged: ( - data: UIDisplayData - ) => void | undefined; + onUIDisplayDataChanged: (data: UIDisplayData) => void | undefined; loadInitialData: boolean; hideAllAgents: boolean; showPaths: boolean; @@ -235,9 +233,7 @@ class Viewport extends React.Component< if (!isEqual(updatedColors, agentColors)) { this.visGeometry.createMaterials(updatedColors); } - onUIDisplayDataChanged( - this.selectionInterface.getUIDisplayData() - ); + onUIDisplayDataChanged(this.selectionInterface.getUIDisplayData()); } public componentDidMount(): void { @@ -352,7 +348,7 @@ class Viewport extends React.Component< ) && selectionStateInfo.colorSettings.length > 0 ) { - this.handleColorSettings(selectionStateInfo.colorSettings); + this.changeAgentsColor(selectionStateInfo.colorSettings); } } @@ -601,12 +597,19 @@ class Viewport extends React.Component< } } - public changeAgentsColor(colorSettings: ColorSetting[]): void { - if (colorSettings.length === 0) { + public changeAgentsColor(newData: UIDisplayData): void { + console.log("changeAgentsColor, newData", newData); + if (newData.length === 0) { return; } + const colorSettings = + this.selectionInterface.deriveColorSettingsFromUIData(newData); +console.log("colorSettings in changeAgentsColor", colorSettings); colorSettings.forEach((setting) => { - this.visGeometry.applyColorToAgents(setting); + this.visGeometry.applyColorToAgents( + setting.agentIds, + setting.color + ); this.selectionInterface.updateUiDataColor( setting.agentIds, setting.color, @@ -615,14 +618,6 @@ class Viewport extends React.Component< }); } - private handleColorSettings(newData: UIDisplayData): void { - // color sessions to do: - // only process necessary changes - const colorSettings = - this.selectionInterface.deriveColorSettingsFromUIData(newData); - this.changeAgentsColor(colorSettings); - } - public stopAnimate(): void { if (this.animationRequestID !== 0) { cancelAnimationFrame(this.animationRequestID); diff --git a/src/visGeometry/index.ts b/src/visGeometry/index.ts index fc957e52..25cc66e6 100644 --- a/src/visGeometry/index.ts +++ b/src/visGeometry/index.ts @@ -1117,8 +1117,10 @@ class VisGeometry { this.setAgentColors(); } - public applyColorToAgents(setting: ColorSetting): void { - const { agentIds, color } = setting; + public applyColorToAgents( + agentIds: number[], + color: string | number + ): void { const newColorData = this.colorHandler.setColorForAgentTypes( agentIds, color From dfb53d972690689198df9e559d1c0b5348c559e7 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 15:48:34 -0700 Subject: [PATCH 12/27] remove unused types, imports, and comments --- src/controller/index.ts | 2 -- src/simularium/SelectionInterface.ts | 13 ++++++++++--- src/viewport/index.tsx | 5 ----- src/visGeometry/index.ts | 1 - src/visGeometry/types.ts | 6 ------ 5 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/controller/index.ts b/src/controller/index.ts index b07a0517..00f31a94 100644 --- a/src/controller/index.ts +++ b/src/controller/index.ts @@ -2,10 +2,8 @@ import jsLogger from "js-logger"; import { isEmpty, noop } from "lodash"; import { VisData, RemoteSimulator } from "../simularium"; import type { - ColorChange, NetConnectionParams, TrajectoryFileInfo, - UIDisplayData, VisDataMessage, } from "../simularium"; import { VisGeometry } from "../visGeometry"; diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index ed5dc7c0..119dd0d1 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -1,7 +1,6 @@ import { filter, find, map, uniq } from "lodash"; import { EncodedTypeMapping } from "./types"; import { convertColorNumberToString } from "../visGeometry/ColorHandler"; -import { ColorSetting } from "../visGeometry/types"; // An individual entry parsed from an encoded name // The encoded names can be just a name or a name plus a @@ -392,8 +391,16 @@ class SelectionInterface { // seems like a util public deriveColorSettingsFromUIData = ( uiData: UIDisplayData - ): ColorSetting[] => { - const settings: ColorSetting[] = []; + ): { + agentIds: number[]; + color: string | number; + name?: string; + }[] => { + const settings: { + agentIds: number[]; + color: string | number; + name?: string; + }[] = []; uiData.forEach((agent) => { settings.push({ diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index ca417cdc..ee24dac4 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -18,7 +18,6 @@ import { FrontEndError, ErrorLevel } from "../simularium/FrontEndError"; import { RenderStyle, VisGeometry, NO_AGENT } from "../visGeometry"; import FrameRecorder from "../simularium/FrameRecorder"; import { DEFAULT_FRAME_RATE } from "../constants"; -import { ColorSetting } from "../visGeometry/types"; export type PropColor = string | number | [number, number, number]; @@ -47,7 +46,6 @@ type ViewportProps = { onRecordedMovie?: (blob: Blob) => void; // providing this callback enables movie recording disableCache?: boolean; onFollowObjectChanged?: (agentData: AgentData) => void; // passes agent data about the followed agent to the front end - sessionUIData?: UIDisplayData; } & Partial; const defaultProps = { @@ -176,7 +174,6 @@ class Viewport extends React.Component< onUIDisplayDataChanged, onError, agentColors, - sessionUIData, } = this.props; // Update TrajectoryFileInfo format to latest version @@ -598,13 +595,11 @@ class Viewport extends React.Component< } public changeAgentsColor(newData: UIDisplayData): void { - console.log("changeAgentsColor, newData", newData); if (newData.length === 0) { return; } const colorSettings = this.selectionInterface.deriveColorSettingsFromUIData(newData); -console.log("colorSettings in changeAgentsColor", colorSettings); colorSettings.forEach((setting) => { this.visGeometry.applyColorToAgents( setting.agentIds, diff --git a/src/visGeometry/index.ts b/src/visGeometry/index.ts index 25cc66e6..5b7c76fc 100644 --- a/src/visGeometry/index.ts +++ b/src/visGeometry/index.ts @@ -58,7 +58,6 @@ import { LegacyRenderer } from "./rendering/LegacyRenderer"; import GeometryStore from "./GeometryStore"; import { AgentGeometry, - ColorSetting, GeometryDisplayType, GeometryInstanceContainer, MeshGeometry, diff --git a/src/visGeometry/types.ts b/src/visGeometry/types.ts index 0fc40d8a..85e998f7 100644 --- a/src/visGeometry/types.ts +++ b/src/visGeometry/types.ts @@ -69,9 +69,3 @@ export interface AgentColorInfo { color: Color; colorId: number; } - -export interface ColorSetting { - agentIds: number[]; - color: string | number; - name?: string; -} From 6f9bfa8ca39c9e53bb947946d6e59ce68a64ddfe Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 15:52:19 -0700 Subject: [PATCH 13/27] fix whitespace --- src/viewport/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index ee24dac4..cf64ba9b 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -230,6 +230,7 @@ class Viewport extends React.Component< if (!isEqual(updatedColors, agentColors)) { this.visGeometry.createMaterials(updatedColors); } + onUIDisplayDataChanged(this.selectionInterface.getUIDisplayData()); } From 9678d19e064e5c4e2daa533bf1ce5257268042e5 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 16:17:29 -0700 Subject: [PATCH 14/27] remove unused agnet name from color update arguments --- src/simularium/SelectionInterface.ts | 3 --- src/viewport/index.tsx | 1 - 2 files changed, 4 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 119dd0d1..609ee476 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -394,12 +394,10 @@ class SelectionInterface { ): { agentIds: number[]; color: string | number; - name?: string; }[] => { const settings: { agentIds: number[]; color: string | number; - name?: string; }[] = []; uiData.forEach((agent) => { @@ -408,7 +406,6 @@ class SelectionInterface { { name: agent.name, tags: [] }, ]), color: agent.color, - name: agent.name, }); agent.displayStates.forEach((newState) => { diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index cf64ba9b..bc5c263a 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -609,7 +609,6 @@ class Viewport extends React.Component< this.selectionInterface.updateUiDataColor( setting.agentIds, setting.color, - setting.name ); }); } From 1bab4fe8f7830500cabee2a372aea589dc08c667 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 16:23:01 -0700 Subject: [PATCH 15/27] rename getIdsAndColorsFromUIData --- src/simularium/SelectionInterface.ts | 3 +-- src/viewport/index.tsx | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 609ee476..dceb2aae 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -388,8 +388,7 @@ class SelectionInterface { return colors; } - // seems like a util - public deriveColorSettingsFromUIData = ( + public getIdsAndColorsFromUIData = ( uiData: UIDisplayData ): { agentIds: number[]; diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index bc5c263a..5ea6d0ae 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -600,7 +600,7 @@ class Viewport extends React.Component< return; } const colorSettings = - this.selectionInterface.deriveColorSettingsFromUIData(newData); + this.selectionInterface.getIdsAndColorsFromUIData(newData); colorSettings.forEach((setting) => { this.visGeometry.applyColorToAgents( setting.agentIds, From d6a6a7635d6338432caa7ac45f9a389ca09f1cf4 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 16:24:52 -0700 Subject: [PATCH 16/27] remove duplicate length check --- src/viewport/index.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 5ea6d0ae..7911690d 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -596,9 +596,6 @@ class Viewport extends React.Component< } public changeAgentsColor(newData: UIDisplayData): void { - if (newData.length === 0) { - return; - } const colorSettings = this.selectionInterface.getIdsAndColorsFromUIData(newData); colorSettings.forEach((setting) => { @@ -608,7 +605,7 @@ class Viewport extends React.Component< ); this.selectionInterface.updateUiDataColor( setting.agentIds, - setting.color, + setting.color ); }); } From a3552554a5e15a279b6d7e049bdc420cbdbd974e Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 16:38:47 -0700 Subject: [PATCH 17/27] rename colorSettings to appliedColors in SelectionStateInfo --- src/simularium/SelectionInterface.ts | 2 +- src/viewport/index.tsx | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index dceb2aae..4a4a3dbb 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -25,7 +25,7 @@ export interface ColorChange { export interface SelectionStateInfo { highlightedAgents: SelectionEntry[]; hiddenAgents: SelectionEntry[]; - colorSettings: UIDisplayData; + appliedColors: UIDisplayData; } interface DisplayStateEntry { diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 7911690d..a15ad955 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -341,12 +341,12 @@ class Viewport extends React.Component< } if ( !isEqual( - selectionStateInfo.colorSettings, - prevProps.selectionStateInfo.colorSettings + selectionStateInfo.appliedColors, + prevProps.selectionStateInfo.appliedColors ) && - selectionStateInfo.colorSettings.length > 0 + selectionStateInfo.appliedColors.length > 0 ) { - this.changeAgentsColor(selectionStateInfo.colorSettings); + this.changeAgentsColor(selectionStateInfo.appliedColors); } } From e3f8f823249c50e00435392ba963a98f06bef225 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 16:49:42 -0700 Subject: [PATCH 18/27] revert updateUiDataColor to not update entries object --- src/simularium/SelectionInterface.ts | 37 ++++++++++------------------ src/viewport/index.tsx | 4 --- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 4a4a3dbb..69b526ef 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -283,31 +283,19 @@ class SelectionInterface { }); } - // to do this is blended version of two functions - // could maybe be optimized and typing adjusted/done better - public updateUiDataColor( + private updateUiDataColor( + agentName: string, idsToUpdate: number[], - color: number | string, - agentName?: string + color: number | string ): void { const newColor = convertColorNumberToString(color); - if (agentName !== undefined) { - const entry = this.entries[agentName]; - // if no display state update parent color - entry.forEach((displayState) => { - if (idsToUpdate.includes(displayState.id)) { - displayState.color = newColor; - } - }); - } else { - Object.values(this.entries).forEach((entry) => { - entry.forEach((displayState) => { - if (idsToUpdate.includes(displayState.id)) { - displayState.color = newColor; - } - }); - }); - } + const entry = this.entries[agentName]; + // if no display state update parent color + entry.forEach((displayState) => { + if (idsToUpdate.includes(displayState.id)) { + displayState.color = newColor; + } + }); } public setInitialAgentColors( @@ -331,9 +319,9 @@ class SelectionInterface { // just give all states of this agent name the same color setColorForIds(ids, colors[defaultColorIndex]); this.updateUiDataColor( + group.name, ids, - colors[defaultColorIndex], - group.name + colors[defaultColorIndex] ); } else { // otherwise, we need to update any user defined colors @@ -354,6 +342,7 @@ class SelectionInterface { } else { // need update the display data with the default color being used this.updateUiDataColor( + group.name, [ids[index]], colors[groupColorIndex] ); diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index a15ad955..3a54dc76 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -603,10 +603,6 @@ class Viewport extends React.Component< setting.agentIds, setting.color ); - this.selectionInterface.updateUiDataColor( - setting.agentIds, - setting.color - ); }); } From cc52ba73ef17618040ebdb319db56ccff63996d9 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 16:50:51 -0700 Subject: [PATCH 19/27] rename argument for changeAgentsColor --- src/viewport/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 3a54dc76..779d0378 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -595,9 +595,9 @@ class Viewport extends React.Component< } } - public changeAgentsColor(newData: UIDisplayData): void { + public changeAgentsColor(appliedColors: UIDisplayData): void { const colorSettings = - this.selectionInterface.getIdsAndColorsFromUIData(newData); + this.selectionInterface.getIdsAndColorsFromUIData(appliedColors); colorSettings.forEach((setting) => { this.visGeometry.applyColorToAgents( setting.agentIds, From 6cae2d5fa6065f82badc3225d490469d9404cbe3 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 16:53:47 -0700 Subject: [PATCH 20/27] rename settings to colorAssignments --- src/simularium/SelectionInterface.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 69b526ef..ce380d70 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -301,7 +301,7 @@ class SelectionInterface { public setInitialAgentColors( uiDisplayData: UIDisplayData, colors: (string | number)[], - setColorForIds: (agentIds: number[], color: string | number) => void + setColorForIds: (ids: number[], color: string | number) => void ): (string | number)[] { let defaultColorIndex = 0; uiDisplayData.forEach((group) => { @@ -383,13 +383,13 @@ class SelectionInterface { agentIds: number[]; color: string | number; }[] => { - const settings: { + const colorAssignments: { agentIds: number[]; color: string | number; }[] = []; uiData.forEach((agent) => { - settings.push({ + colorAssignments.push({ agentIds: this.getAgentIdsByNamesAndTags([ { name: agent.name, tags: [] }, ]), @@ -397,7 +397,7 @@ class SelectionInterface { }); agent.displayStates.forEach((newState) => { - settings.push({ + colorAssignments.push({ agentIds: this.getAgentIdsByNamesAndTags([ { name: agent.name, tags: [newState.name] }, ]), @@ -406,7 +406,7 @@ class SelectionInterface { }); }); - return settings; + return colorAssignments; }; } From a158e4ed0c52685bffd4a7f891f329240008ae82 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 18 Jul 2024 21:45:26 -0700 Subject: [PATCH 21/27] use new UIDisplayData structure in applying color changes in test bed viewer --- examples/src/ColorPicker.tsx | 35 +++++++++++++++++++---------- examples/src/Viewer.tsx | 7 +++--- src/index.ts | 2 +- src/test/SelectionInterface.test.ts | 16 ++++++------- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/examples/src/ColorPicker.tsx b/examples/src/ColorPicker.tsx index e0940792..1ec1e9d7 100644 --- a/examples/src/ColorPicker.tsx +++ b/examples/src/ColorPicker.tsx @@ -1,14 +1,11 @@ import React, { useState } from "react"; -import { SelectionEntry, UIDisplayData } from "../../src"; +import { UIDisplayData } from "../../src"; type ColorPickerProps = { uiDisplayData: UIDisplayData; particleTypeNames: string[]; agentColors: string[] | number[]; - setColorSelectionInfo: (data: { - agent: SelectionEntry; - color: string; - }) => void; + setColorSelectionInfo: (data: UIDisplayData) => void; updateAgentColorArray: (color: string) => void; }; @@ -54,14 +51,28 @@ const ColorPicker = ({ if (selectedSubagent === "") { subAgent = [""]; } - const entry: SelectionEntry = { - name: selectedAgent, - tags: subAgent, - }; - setColorSelectionInfo({ - agent: entry, - color: selectedColor, + 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; }); + setColorSelectionInfo(appliedColors); } }; diff --git a/examples/src/Viewer.tsx b/examples/src/Viewer.tsx index 80c8a803..9fbe0d98 100644 --- a/examples/src/Viewer.tsx +++ b/examples/src/Viewer.tsx @@ -166,7 +166,7 @@ const initialState: ViewerState = { selectionStateInfo: { highlightedAgents: [], hiddenAgents: [], - colorChange: null, + appliedColors: [], }, filePending: null, simulariumFile: null, @@ -676,14 +676,15 @@ class Viewer extends React.Component { this.setState({ agentColors }); }; - public setColorSelectionInfo = (colorChange) => { + public setColorSelectionInfo = (appliedColors) => { this.setState({ ...this.state, + uiDisplayData: appliedColors, selectionStateInfo: { hiddenAgents: this.state.selectionStateInfo.hiddenAgents, highlightedAgents: this.state.selectionStateInfo.highlightedAgents, - colorChange: colorChange, + appliedColors: appliedColors, }, }); }; diff --git a/src/index.ts b/src/index.ts index 7625c064..7aa495e9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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"; export default Viewport; diff --git a/src/test/SelectionInterface.test.ts b/src/test/SelectionInterface.test.ts index 36690046..8ab2d87a 100644 --- a/src/test/SelectionInterface.test.ts +++ b/src/test/SelectionInterface.test.ts @@ -23,7 +23,7 @@ const idMapping = { }; const color = ""; -const initialColorChanges = null; +const initialaAppliedColors = []; describe("SelectionInterface module", () => { describe("decode", () => { @@ -232,7 +232,7 @@ describe("SelectionInterface module", () => { { name: "D", tags: [] }, ], hiddenAgents: [], - colorChange: initialColorChanges, + appliedColors: initialaAppliedColors, }; const ids = si.getHighlightedIds(selectionStateHighlight); const allAs = [0, 1, 2, 3]; @@ -252,7 +252,7 @@ describe("SelectionInterface module", () => { { name: "D", tags: [""] }, ], hiddenAgents: [], - colorChange: initialColorChanges, + appliedColors: initialaAppliedColors, }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -269,7 +269,7 @@ describe("SelectionInterface module", () => { { name: "E", tags: ["t1000"] }, ], hiddenAgents: [], - colorChange: initialColorChanges, + appliedColors: initialaAppliedColors, }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -282,7 +282,7 @@ describe("SelectionInterface module", () => { const selectionStateHighlight = { highlightedAgents: [{ name: "E", tags: [""] }], hiddenAgents: [], - colorChange: initialColorChanges, + appliedColors: initialaAppliedColors, }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -300,7 +300,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: [] }, { name: "C", tags: [] }, ], - colorChange: initialColorChanges, + appliedColors: initialaAppliedColors, }; const ids = si.getHiddenIds(selectionStateHide); @@ -316,7 +316,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: ["t1", "t2"] }, { name: "B", tags: ["t1"] }, ], - colorChange: initialColorChanges, + appliedColors: initialaAppliedColors, }; const ids = si.getHiddenIds(selectionStateHide); expect(ids).toEqual([1, 2, 3, 5, 7]); @@ -332,7 +332,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: [""] }, { name: "C", tags: ["", "t1", "t2"] }, ], - colorChange: initialColorChanges, + appliedColors: initialaAppliedColors, }; const ids = si.getHiddenIds(selectionStateHide); From 8e54623de3a72bd7658f727aeb3ee01d2b9fc388 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Fri, 19 Jul 2024 09:30:52 -0700 Subject: [PATCH 22/27] consolidate helper function into changeAgentsColor --- src/simularium/SelectionInterface.ts | 32 ---------------------------- src/viewport/index.tsx | 19 ++++++++++++----- 2 files changed, 14 insertions(+), 37 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index ce380d70..4adb009e 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -376,38 +376,6 @@ class SelectionInterface { }); return colors; } - - public getIdsAndColorsFromUIData = ( - uiData: UIDisplayData - ): { - agentIds: number[]; - color: string | number; - }[] => { - const colorAssignments: { - agentIds: number[]; - color: string | number; - }[] = []; - - uiData.forEach((agent) => { - colorAssignments.push({ - agentIds: this.getAgentIdsByNamesAndTags([ - { name: agent.name, tags: [] }, - ]), - color: agent.color, - }); - - agent.displayStates.forEach((newState) => { - colorAssignments.push({ - agentIds: this.getAgentIdsByNamesAndTags([ - { name: agent.name, tags: [newState.name] }, - ]), - color: newState.color, - }); - }); - }); - - return colorAssignments; - }; } export { SelectionInterface }; diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 779d0378..ea0de152 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -596,13 +596,22 @@ class Viewport extends React.Component< } public changeAgentsColor(appliedColors: UIDisplayData): void { - const colorSettings = - this.selectionInterface.getIdsAndColorsFromUIData(appliedColors); - colorSettings.forEach((setting) => { + appliedColors.forEach((agent) => { this.visGeometry.applyColorToAgents( - setting.agentIds, - setting.color + this.selectionInterface.getAgentIdsByNamesAndTags([ + { name: agent.name, tags: [] }, + ]), + agent.color ); + + agent.displayStates.forEach((state) => { + this.visGeometry.applyColorToAgents( + this.selectionInterface.getAgentIdsByNamesAndTags([ + { name: agent.name, tags: [state.name] }, + ]), + state.color + ); + }); }); } From 98662fb0f476de234104920a0b87d8b2da0c7999 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Fri, 19 Jul 2024 10:59:36 -0700 Subject: [PATCH 23/27] declare ids before applying to agents for readability in changeAgentsColor --- src/viewport/index.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index ea0de152..b625cb02 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -597,20 +597,20 @@ class Viewport extends React.Component< public changeAgentsColor(appliedColors: UIDisplayData): void { appliedColors.forEach((agent) => { - this.visGeometry.applyColorToAgents( - this.selectionInterface.getAgentIdsByNamesAndTags([ + const agentIds = this.selectionInterface.getAgentIdsByNamesAndTags([ { name: agent.name, tags: [] }, - ]), + ]); + this.visGeometry.applyColorToAgents( + agentIds, agent.color ); agent.displayStates.forEach((state) => { - this.visGeometry.applyColorToAgents( + const stateIds = this.selectionInterface.getAgentIdsByNamesAndTags([ { name: agent.name, tags: [state.name] }, - ]), - state.color - ); + ]); + this.visGeometry.applyColorToAgents(stateIds, state.color); }); }); } From 2337d4058b337cbd3a15033910deb1b46bb42301 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Fri, 19 Jul 2024 11:06:16 -0700 Subject: [PATCH 24/27] typo fix --- src/test/SelectionInterface.test.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/SelectionInterface.test.ts b/src/test/SelectionInterface.test.ts index 8ab2d87a..c5ab8bbd 100644 --- a/src/test/SelectionInterface.test.ts +++ b/src/test/SelectionInterface.test.ts @@ -23,7 +23,7 @@ const idMapping = { }; const color = ""; -const initialaAppliedColors = []; +const initialAppliedColors = []; describe("SelectionInterface module", () => { describe("decode", () => { @@ -232,7 +232,7 @@ describe("SelectionInterface module", () => { { name: "D", tags: [] }, ], hiddenAgents: [], - appliedColors: initialaAppliedColors, + appliedColors: initialAppliedColors, }; const ids = si.getHighlightedIds(selectionStateHighlight); const allAs = [0, 1, 2, 3]; @@ -252,7 +252,7 @@ describe("SelectionInterface module", () => { { name: "D", tags: [""] }, ], hiddenAgents: [], - appliedColors: initialaAppliedColors, + appliedColors: initialAppliedColors, }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -269,7 +269,7 @@ describe("SelectionInterface module", () => { { name: "E", tags: ["t1000"] }, ], hiddenAgents: [], - appliedColors: initialaAppliedColors, + appliedColors: initialAppliedColors, }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -282,7 +282,7 @@ describe("SelectionInterface module", () => { const selectionStateHighlight = { highlightedAgents: [{ name: "E", tags: [""] }], hiddenAgents: [], - appliedColors: initialaAppliedColors, + appliedColors: initialAppliedColors, }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -300,7 +300,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: [] }, { name: "C", tags: [] }, ], - appliedColors: initialaAppliedColors, + appliedColors: initialAppliedColors, }; const ids = si.getHiddenIds(selectionStateHide); @@ -316,7 +316,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: ["t1", "t2"] }, { name: "B", tags: ["t1"] }, ], - appliedColors: initialaAppliedColors, + appliedColors: initialAppliedColors, }; const ids = si.getHiddenIds(selectionStateHide); expect(ids).toEqual([1, 2, 3, 5, 7]); @@ -332,7 +332,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: [""] }, { name: "C", tags: ["", "t1", "t2"] }, ], - appliedColors: initialaAppliedColors, + appliedColors: initialAppliedColors, }; const ids = si.getHiddenIds(selectionStateHide); From 311175c75463a46c9672277b0e8ff5f60532e03a Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Tue, 13 Aug 2024 13:06:09 -0700 Subject: [PATCH 25/27] use appliedColors in place of uiDisplayData in test bed state --- examples/src/Viewer.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/examples/src/Viewer.tsx b/examples/src/Viewer.tsx index 9fbe0d98..e49020c8 100644 --- a/examples/src/Viewer.tsx +++ b/examples/src/Viewer.tsx @@ -97,7 +97,6 @@ interface ViewerState { showPaths: boolean; timeStep: number; totalDuration: number; - uiDisplayData: UIDisplayData; filePending: { type: TrajectoryType; template: { [key: string]: any }; @@ -162,7 +161,6 @@ const initialState: ViewerState = { showPaths: true, timeStep: 1, totalDuration: 100, - uiDisplayData: [], selectionStateInfo: { highlightedAgents: [], hiddenAgents: [], @@ -517,14 +515,13 @@ class Viewer extends React.Component { [] ); const uniqueTags: string[] = [...new Set(allTags)]; - if (isEqual(uiDisplayData, this.state.uiDisplayData)) { + if (isEqual(uiDisplayData, this.state.selectionStateInfo.appliedColors)) { return; } this.setState({ particleTypeNames: uiDisplayData.map((a) => a.name), - uiDisplayData: uiDisplayData, particleTypeTags: uniqueTags, - selectionStateInfo: initialState.selectionStateInfo, + selectionStateInfo: {...initialState.selectionStateInfo, appliedColors: uiDisplayData}, }); } @@ -679,7 +676,6 @@ class Viewer extends React.Component { public setColorSelectionInfo = (appliedColors) => { this.setState({ ...this.state, - uiDisplayData: appliedColors, selectionStateInfo: { hiddenAgents: this.state.selectionStateInfo.hiddenAgents, highlightedAgents: @@ -984,7 +980,7 @@ class Viewer extends React.Component {

Date: Tue, 13 Aug 2024 13:32:31 -0700 Subject: [PATCH 26/27] process batches of assigments in when applying colors to agents to reduce calls of updateScene --- src/simularium/SelectionInterface.ts | 15 +++++++++--- src/test/SelectionInterface.test.ts | 34 +++++++++++++++++----------- src/viewport/index.tsx | 11 ++++----- src/visGeometry/index.ts | 24 ++++++++++---------- src/visGeometry/types.ts | 5 ++++ 5 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 4adb009e..f5ca27a8 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -1,6 +1,7 @@ import { filter, find, map, uniq } from "lodash"; import { EncodedTypeMapping } from "./types"; import { convertColorNumberToString } from "../visGeometry/ColorHandler"; +import { ColorAssignment } from "../visGeometry/types"; // An individual entry parsed from an encoded name // The encoded names can be just a name or a name plus a @@ -301,9 +302,10 @@ class SelectionInterface { public setInitialAgentColors( uiDisplayData: UIDisplayData, colors: (string | number)[], - setColorForIds: (ids: number[], color: string | number) => void + setColorForIds: (colorAssignments: ColorAssignment[]) => void ): (string | number)[] { let defaultColorIndex = 0; + const colorAssignments: ColorAssignment[] = []; uiDisplayData.forEach((group) => { // the color for the whole grouping for this entry.name let groupColorIndex = defaultColorIndex; @@ -317,7 +319,10 @@ class SelectionInterface { if (!hasNewColors) { // if no colors have been set by the user for this name, // just give all states of this agent name the same color - setColorForIds(ids, colors[defaultColorIndex]); + colorAssignments.push({ + agentIds: ids, + color: colors[defaultColorIndex], + }); this.updateUiDataColor( group.name, ids, @@ -355,7 +360,10 @@ class SelectionInterface { } else { groupColorIndex = -1; } - setColorForIds([ids[index]], colors[agentColorIndex]); + colorAssignments.push({ + agentIds: [ids[index]], + color: colors[agentColorIndex], + }); }); } if (groupColorIndex > -1) { @@ -374,6 +382,7 @@ class SelectionInterface { defaultColorIndex++; } }); + setColorForIds(colorAssignments); return colors; } } diff --git a/src/test/SelectionInterface.test.ts b/src/test/SelectionInterface.test.ts index c5ab8bbd..a8fd1ec0 100644 --- a/src/test/SelectionInterface.test.ts +++ b/src/test/SelectionInterface.test.ts @@ -232,7 +232,7 @@ describe("SelectionInterface module", () => { { name: "D", tags: [] }, ], hiddenAgents: [], - appliedColors: initialAppliedColors, + appliedColors: [...initialAppliedColors], }; const ids = si.getHighlightedIds(selectionStateHighlight); const allAs = [0, 1, 2, 3]; @@ -252,7 +252,7 @@ describe("SelectionInterface module", () => { { name: "D", tags: [""] }, ], hiddenAgents: [], - appliedColors: initialAppliedColors, + appliedColors: [...initialAppliedColors], }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -269,7 +269,7 @@ describe("SelectionInterface module", () => { { name: "E", tags: ["t1000"] }, ], hiddenAgents: [], - appliedColors: initialAppliedColors, + appliedColors: [...initialAppliedColors], }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -282,7 +282,7 @@ describe("SelectionInterface module", () => { const selectionStateHighlight = { highlightedAgents: [{ name: "E", tags: [""] }], hiddenAgents: [], - appliedColors: initialAppliedColors, + appliedColors: [...initialAppliedColors], }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -300,7 +300,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: [] }, { name: "C", tags: [] }, ], - appliedColors: initialAppliedColors, + appliedColors: [...initialAppliedColors], }; const ids = si.getHiddenIds(selectionStateHide); @@ -316,7 +316,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: ["t1", "t2"] }, { name: "B", tags: ["t1"] }, ], - appliedColors: initialAppliedColors, + appliedColors: [...initialAppliedColors], }; const ids = si.getHiddenIds(selectionStateHide); expect(ids).toEqual([1, 2, 3, 5, 7]); @@ -332,7 +332,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: [""] }, { name: "C", tags: ["", "t1", "t2"] }, ], - appliedColors: initialAppliedColors, + appliedColors: [...initialAppliedColors], }; const ids = si.getHiddenIds(selectionStateHide); @@ -524,11 +524,15 @@ describe("SelectionInterface module", () => { expect(uiDisplayDataForE?.color).toEqual(""); si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); expect(uiDisplayDataForE?.color).toEqual("#00"); - expect(setColorForIds).toHaveBeenCalledWith([13], "#00"); + expect(setColorForIds).toHaveBeenCalledWith( + expect.arrayContaining([{ agentIds: [13], color: "#00" }]) + ); }); test("If no user colors are provided all the ids for an entry will get a default color", () => { si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); - expect(setColorForIds).toHaveBeenCalledWith([13], "#00"); + expect(setColorForIds).toHaveBeenCalledWith( + expect.arrayContaining([{ agentIds: [13], color: "#00" }]) + ); }); test("if all the colors are the same, the parent entry will also get that color, even if no unmodified color set", () => { si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); @@ -542,10 +546,14 @@ describe("SelectionInterface module", () => { si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); // the first new user color will be appended to the end of the list // these are all the agent A ids, each should get the first new color assigned - expect(setColorForIds).toHaveBeenCalledWith([0], agentColors.A); - expect(setColorForIds).toHaveBeenCalledWith([1], agentColors.A); - expect(setColorForIds).toHaveBeenCalledWith([2], agentColors.A); - expect(setColorForIds).toHaveBeenCalledWith([3], agentColors.A); + expect(setColorForIds).toHaveBeenCalledWith( + expect.arrayContaining([ + { agentIds: [0], color: agentColors.A }, + { agentIds: [1], color: agentColors.A }, + { agentIds: [2], color: agentColors.A }, + { agentIds: [3], color: agentColors.A }, + ]) + ); }); }); }); diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index b625cb02..a6904518 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -16,6 +16,7 @@ import { AgentData, TrajectoryFileInfoAny } from "../simularium/types"; import { updateTrajectoryFileInfoFormat } from "../simularium/versionHandlers"; import { FrontEndError, ErrorLevel } from "../simularium/FrontEndError"; import { RenderStyle, VisGeometry, NO_AGENT } from "../visGeometry"; +import { ColorAssignment } from "../visGeometry/types"; import FrameRecorder from "../simularium/FrameRecorder"; import { DEFAULT_FRAME_RATE } from "../constants"; @@ -596,23 +597,21 @@ class Viewport extends React.Component< } public changeAgentsColor(appliedColors: UIDisplayData): void { + const changes: ColorAssignment[] = []; appliedColors.forEach((agent) => { const agentIds = this.selectionInterface.getAgentIdsByNamesAndTags([ { name: agent.name, tags: [] }, ]); - this.visGeometry.applyColorToAgents( - agentIds, - agent.color - ); - + changes.push({ agentIds, color: agent.color }); agent.displayStates.forEach((state) => { const stateIds = this.selectionInterface.getAgentIdsByNamesAndTags([ { name: agent.name, tags: [state.name] }, ]); - this.visGeometry.applyColorToAgents(stateIds, state.color); + changes.push({ agentIds: stateIds, color: state.color }); }); }); + this.visGeometry.applyColorToAgents(changes); } public stopAnimate(): void { diff --git a/src/visGeometry/index.ts b/src/visGeometry/index.ts index 5b7c76fc..79d3a079 100644 --- a/src/visGeometry/index.ts +++ b/src/visGeometry/index.ts @@ -58,6 +58,7 @@ import { LegacyRenderer } from "./rendering/LegacyRenderer"; import GeometryStore from "./GeometryStore"; import { AgentGeometry, + ColorAssignment, GeometryDisplayType, GeometryInstanceContainer, MeshGeometry, @@ -1116,18 +1117,17 @@ class VisGeometry { this.setAgentColors(); } - public applyColorToAgents( - agentIds: number[], - color: string | number - ): void { - const newColorData = this.colorHandler.setColorForAgentTypes( - agentIds, - color - ); - this.renderer.updateColors( - newColorData.numberOfColors, - newColorData.colorArray - ); + public applyColorToAgents(colorAssignments: ColorAssignment[]): void { + colorAssignments.forEach((color) => { + const newColorData = this.colorHandler.setColorForAgentTypes( + color.agentIds, + color.color + ); + this.renderer.updateColors( + newColorData.numberOfColors, + newColorData.colorArray + ); + }); this.updateScene(this.currentSceneAgents); } diff --git a/src/visGeometry/types.ts b/src/visGeometry/types.ts index 85e998f7..3eb61f68 100644 --- a/src/visGeometry/types.ts +++ b/src/visGeometry/types.ts @@ -69,3 +69,8 @@ export interface AgentColorInfo { color: Color; colorId: number; } + +export interface ColorAssignment { + agentIds: number[]; + color: string | number; +} From 80bb750033a1615088d0980b8539de465bedcdc4 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Tue, 13 Aug 2024 14:22:33 -0700 Subject: [PATCH 27/27] overwrite subagent colors when color changes are applied to parent --- examples/src/ColorPicker.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/src/ColorPicker.tsx b/examples/src/ColorPicker.tsx index 1ec1e9d7..8db0aa33 100644 --- a/examples/src/ColorPicker.tsx +++ b/examples/src/ColorPicker.tsx @@ -59,7 +59,10 @@ const ColorPicker = ({ } const newDisplayStates = agent.displayStates.map( (state: any) => { - if (subAgent.includes(state.id)) { + if ( + subAgent.includes(state.id) || + !subAgent.length + ) { return { ...state, color: selectedColor,