From 08382d4c684f5bd6f5ec5208c0d3b8f1691dabdf Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 3 Aug 2023 11:43:50 -0700 Subject: [PATCH 01/34] handle colorChangeAgents in selectioninterface --- src/simularium/SelectionInterface.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index eebba453..bfe5294d 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -18,6 +18,7 @@ export interface SelectionEntry { export interface SelectionStateInfo { highlightedAgents: SelectionEntry[]; hiddenAgents: SelectionEntry[]; + colorChangeAgents: SelectionEntry[]; } interface DisplayStateEntry { @@ -218,6 +219,18 @@ class SelectionInterface { return indices; } + public getColorChangeAgentIds(info: SelectionStateInfo): number[] { + const requests = info.colorChangeAgents; + let indices: number[] = []; + + requests.forEach((r) => { + const name = r.name; + const tags = r.tags; + indices = [...indices, ...this.getIds(name, tags)]; + }); + return indices; + } + public clear(): void { this.entries = new Map(); } From 531897ea19411620c2b0d99e43896702ca9e26d6 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 3 Aug 2023 11:44:56 -0700 Subject: [PATCH 02/34] apply color changes in viewport --- src/viewport/index.tsx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 5c7146f0..ca578e2c 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -41,6 +41,7 @@ type ViewportProps = { selectionStateInfo: SelectionStateInfo; showCameraControls: boolean; onError?: (error: FrontEndError) => void; + selectedColor: string; } & Partial; const defaultProps = { @@ -315,6 +316,27 @@ class Viewport extends React.Component< this.selectionInterface.getHiddenIds(selectionStateInfo); this.visGeometry.setVisibleByIds(hiddenIds); } + if ( + !isEqual( + selectionStateInfo.colorChangeAgents, + prevProps.selectionStateInfo.colorChangeAgents + ) + ) { + const colorChangeAgentIds = + this.selectionInterface.getColorChangeAgentIds( + selectionStateInfo + ); + //get the selected color + let typeCastAgentColors = agentColors as string[]; + let colorChangeColorId = typeCastAgentColors.indexOf( + this.props.selectedColor + ); + this.visGeometry.setColorForIds( + colorChangeAgentIds, + colorChangeColorId + ); + this.visGeometry.setColorChangeByIds(colorChangeAgentIds); + } } // note that if the system does not support the molecular render style, then From 37700b78c30041e016f9d82369ded5c6a433dae3 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 3 Aug 2023 11:45:37 -0700 Subject: [PATCH 03/34] set color change in visGeometry --- src/visGeometry/index.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/visGeometry/index.ts b/src/visGeometry/index.ts index a2291b52..3db1b0ab 100644 --- a/src/visGeometry/index.ts +++ b/src/visGeometry/index.ts @@ -116,6 +116,7 @@ class VisGeometry { public visAgentInstances: Map; public fixLightsToCamera: boolean; public highlightedIds: number[]; + public colorChangeIds: number[]; public hiddenIds: number[]; public agentPaths: Map; public mlogger: ILogger; @@ -187,6 +188,7 @@ class VisGeometry { this.visAgentInstances = new Map(); this.fixLightsToCamera = true; this.highlightedIds = []; + this.colorChangeIds = []; this.hiddenIds = []; this.needToCenterCamera = false; this.needToReOrientCamera = false; @@ -724,6 +726,11 @@ class VisGeometry { this.updateScene(this.currentSceneAgents); } + public setColorChangeByIds(ids: number[]): void { + this.colorChangeIds = ids; + this.updateScene(this.currentSceneAgents); + } + public dehighlight(): void { this.setHighlightByIds([]); } @@ -1146,11 +1153,15 @@ class VisGeometry { * @param ids agent ids that should all have the same color * @param colorId index into the color array */ - if (this.isIdColorMappingSet) { - throw new FrontEndError( - "Attempted to set agent-color after color mapping was finalized" - ); - } + + //todo: this code is commented out for now to allow colors to be changed + // after the intitial mapping is finalized + // need to either make a new function or handle setting and resettting isIdColorMappingSet + // if (this.isIdColorMappingSet) { + // throw new FrontEndError( + // "Attempted to set agent-color after color mapping was finalized" + // ); + // } ids.forEach((id) => this.setColorForId(id, colorId)); } From 9eb0c444ce001b899b83b02846c9f2cf981ad57e Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 3 Aug 2023 11:46:02 -0700 Subject: [PATCH 04/34] implement ui for color change in example viewer --- examples/Viewer.tsx | 92 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/examples/Viewer.tsx b/examples/Viewer.tsx index 7cd831bc..d37d837c 100644 --- a/examples/Viewer.tsx +++ b/examples/Viewer.tsx @@ -31,6 +31,7 @@ import ConversionForm from "./ConversionForm"; import MetaballSimulator from "./MetaballSimulator"; import { TrajectoryType } from "../src/constants"; import { NetConnectionParams } from "../src/simularium"; +import { SelectionEntry } from "../src/simularium/SelectionInterface"; let playbackFile = "TEST_LIVEMODE_API"; //"medyan_paper_M:A_0.675.simularium"; let queryStringFile = ""; @@ -85,6 +86,9 @@ interface ViewerState { name: string; data: ISimulariumFile | null; } | null; + selectedColor: string; + selectedAgent: string; + colorToAdd: string; } interface BaseType { @@ -139,9 +143,13 @@ const initialState: ViewerState = { selectionStateInfo: { highlightedAgents: [], hiddenAgents: [], + colorChangeAgents: [], }, filePending: null, simulariumFile: null, + selectedColor: "", + selectedAgent: "", + colorToAdd: "", }; type FrontEndError = typeof FrontEndError; @@ -590,6 +598,57 @@ class Viewer extends React.Component { URL.revokeObjectURL(downloadLink.href); } + public handleColorSelection = (event) => { + this.setState({ selectedColor: event.target.value }); + }; + + public handleAgentSelection = (event) => { + const value = event.target.value; + this.setState({ selectedAgent: value }); + }; + + public assignColorToAgent = () => { + if (!this.state.selectedAgent) { + throw new Error("No agent selected"); + return; + } else if (!this.state.selectedColor) { + throw new Error("No color selected"); + return; + } else { + // todo: handle tags + const entry: SelectionEntry = { + name: this.state.selectedAgent, + tags: [], + }; + const entryArray: SelectionEntry[] = [entry]; + this.setState({ + ...this.state, + selectionStateInfo: { + ...this.state.selectionStateInfo, + colorChangeAgents: entryArray, + }, + }); + } + }; + + public receiveNewColorInput = (event) => { + const value = event.target.value; + this.setState({ colorToAdd: value }); + }; + + public addColorToColorArray = (event) => { + const hexColorCodeRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; + const color = this.state.colorToAdd; + if (hexColorCodeRegex.test(color)) { + this.setState({ + agentColors: [...this.state.agentColors, color] as string[], + }); + simulariumController.visGeometry.addColorToColorArray(color); + } else { + alert("Please enter a valid hex color code"); + } + }; + public render(): JSX.Element { if (this.state.filePending) { const fileType = this.state.filePending.type; @@ -828,6 +887,38 @@ class Viewer extends React.Component { Tick interval length:{" "} {simulariumController.tickIntervalLength} + + + + +
{ showPaths={this.state.showPaths} onError={this.onError} backgroundColor={[0, 0, 0]} + selectedColor={this.state.selectedColor} />
From f38819026ab1f35084c99023adf32cabea42aca8 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 3 Aug 2023 16:56:46 -0700 Subject: [PATCH 05/34] main function setAgentColor and helper functions --- src/simularium/SelectionInterface.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index bfe5294d..62e251f0 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -219,8 +219,8 @@ class SelectionInterface { return indices; } - public getColorChangeAgentIds(info: SelectionStateInfo): number[] { - const requests = info.colorChangeAgents; + public getColorChangeAgentIds(info: SelectionEntry[]): number[] { + const requests = info; let indices: number[] = []; requests.forEach((r) => { From 1479b4550d7e59b2937bf0713185bf7c5ebf05fc Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 3 Aug 2023 17:06:46 -0700 Subject: [PATCH 06/34] tighten up variable names --- src/viewport/index.tsx | 64 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index ca578e2c..7f863ea5 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -17,6 +17,7 @@ import { TrajectoryFileInfoAny } from "../simularium/types"; import { updateTrajectoryFileInfoFormat } from "../simularium/versionHandlers"; import { FrontEndError, ErrorLevel } from "../simularium/FrontEndError"; import { RenderStyle, VisGeometry, NO_AGENT } from "../visGeometry"; +import { SelectionEntry } from "../simularium/SelectionInterface"; export type PropColor = string | number | [number, number, number]; @@ -322,20 +323,10 @@ class Viewport extends React.Component< prevProps.selectionStateInfo.colorChangeAgents ) ) { - const colorChangeAgentIds = - this.selectionInterface.getColorChangeAgentIds( - selectionStateInfo - ); - //get the selected color - let typeCastAgentColors = agentColors as string[]; - let colorChangeColorId = typeCastAgentColors.indexOf( + this.changeAgentColor( + selectionStateInfo.colorChangeAgents, this.props.selectedColor ); - this.visGeometry.setColorForIds( - colorChangeAgentIds, - colorChangeColorId - ); - this.visGeometry.setColorChangeByIds(colorChangeAgentIds); } } @@ -564,6 +555,55 @@ class Viewport extends React.Component< } } + public changeAgentColor( + agents: string | SelectionEntry[], + color: string + ): void { + // TODO: if color is not present in color array, add it + if (typeof agents === "string") { + agents = this.selectionEntryFromAgentName(agents); + } + const agentIds = this.selectionInterface.getColorChangeAgentIds(agents); + const colorId = this.getColorId( + color, + this.props.agentColors as string[] + ); + this.applyColorToAgents(agentIds, colorId); + } + + public selectionEntryFromAgentName(name: string): SelectionEntry[] { + const uiDisplayData = this.selectionInterface.getUIDisplayData(); + const agentNames = uiDisplayData.map((a) => a.name); + if (!agentNames.includes(name)) { + throw new Error("Agent name not found"); + } else { + const colorChangeAgents = { + name: name, + tags: [], + }; + return [colorChangeAgents]; + } + } + + public getColorId(color: string, agentColors: string[] | number[]): number { + const hexColorCodeRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; + if (!hexColorCodeRegex.test(color)) { + throw new Error("Invalid color code"); + } + const typeCastAgentColors = agentColors as string[]; + if (!typeCastAgentColors.includes(color)) { + // todo: if color is not present in color array, add it + throw new Error("Color not found"); + } + const colorId = typeCastAgentColors.indexOf(color); + return colorId; + } + + public applyColorToAgents(agentIds: number[], colorId: number): void { + this.visGeometry.setColorForIds(agentIds, colorId); + this.visGeometry.setColorChangeByIds(agentIds); + } + public stopAnimate(): void { if (this.animationRequestID !== 0) { cancelAnimationFrame(this.animationRequestID); From 25c37a8f2bb7542c25d7415add07c97b7a620c2e Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Fri, 4 Aug 2023 09:02:58 -0700 Subject: [PATCH 07/34] clean up, rename functions --- examples/Viewer.tsx | 1 - src/viewport/index.tsx | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/Viewer.tsx b/examples/Viewer.tsx index d37d837c..34cc1c8c 100644 --- a/examples/Viewer.tsx +++ b/examples/Viewer.tsx @@ -643,7 +643,6 @@ class Viewer extends React.Component { this.setState({ agentColors: [...this.state.agentColors, color] as string[], }); - simulariumController.visGeometry.addColorToColorArray(color); } else { alert("Please enter a valid hex color code"); } diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 7f863ea5..562c5c4b 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -561,7 +561,7 @@ class Viewport extends React.Component< ): void { // TODO: if color is not present in color array, add it if (typeof agents === "string") { - agents = this.selectionEntryFromAgentName(agents); + agents = this.convertAgentNameToSelectionEntry(agents); } const agentIds = this.selectionInterface.getColorChangeAgentIds(agents); const colorId = this.getColorId( @@ -571,7 +571,7 @@ class Viewport extends React.Component< this.applyColorToAgents(agentIds, colorId); } - public selectionEntryFromAgentName(name: string): SelectionEntry[] { + public convertAgentNameToSelectionEntry(name: string): SelectionEntry[] { const uiDisplayData = this.selectionInterface.getUIDisplayData(); const agentNames = uiDisplayData.map((a) => a.name); if (!agentNames.includes(name)) { From ee6ed4aaf92c4ebde7ddc7968c520a31a7f2a42f Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Fri, 4 Aug 2023 11:12:10 -0700 Subject: [PATCH 08/34] rename custom and assigned color props --- examples/Viewer.tsx | 12 +++++++----- src/viewport/index.tsx | 6 ++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/examples/Viewer.tsx b/examples/Viewer.tsx index 34cc1c8c..98bf94c1 100644 --- a/examples/Viewer.tsx +++ b/examples/Viewer.tsx @@ -87,8 +87,9 @@ interface ViewerState { data: ISimulariumFile | null; } | null; selectedColor: string; + customColor: string; + assignedColor: string; selectedAgent: string; - colorToAdd: string; } interface BaseType { @@ -149,7 +150,7 @@ const initialState: ViewerState = { simulariumFile: null, selectedColor: "", selectedAgent: "", - colorToAdd: "", + customColor: "", }; type FrontEndError = typeof FrontEndError; @@ -627,18 +628,19 @@ class Viewer extends React.Component { ...this.state.selectionStateInfo, colorChangeAgents: entryArray, }, + assignedColor: this.state.selectedColor, }); } }; public receiveNewColorInput = (event) => { const value = event.target.value; - this.setState({ colorToAdd: value }); + this.setState({ customColor: value }); }; public addColorToColorArray = (event) => { const hexColorCodeRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; - const color = this.state.colorToAdd; + const color = this.state.customColor; if (hexColorCodeRegex.test(color)) { this.setState({ agentColors: [...this.state.agentColors, color] as string[], @@ -941,7 +943,7 @@ class Viewer extends React.Component { showPaths={this.state.showPaths} onError={this.onError} backgroundColor={[0, 0, 0]} - selectedColor={this.state.selectedColor} + assignedColor={this.state.assignedColor} /> diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 562c5c4b..54b1c807 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -42,7 +42,7 @@ type ViewportProps = { selectionStateInfo: SelectionStateInfo; showCameraControls: boolean; onError?: (error: FrontEndError) => void; - selectedColor: string; + assignedColor: string; } & Partial; const defaultProps = { @@ -322,10 +322,12 @@ class Viewport extends React.Component< selectionStateInfo.colorChangeAgents, prevProps.selectionStateInfo.colorChangeAgents ) + || + !isEqual(this.props.assignedColor, prevProps.assignedColor) ) { this.changeAgentColor( selectionStateInfo.colorChangeAgents, - this.props.selectedColor + this.props.assignedColor ); } } From 63522b6b6e961635b058fd4eece729255b2733da Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Wed, 9 Aug 2023 09:41:00 -0700 Subject: [PATCH 09/34] add user colors to agentcolors --- src/viewport/index.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 54b1c807..254195eb 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -321,8 +321,7 @@ class Viewport extends React.Component< !isEqual( selectionStateInfo.colorChangeAgents, prevProps.selectionStateInfo.colorChangeAgents - ) - || + ) || !isEqual(this.props.assignedColor, prevProps.assignedColor) ) { this.changeAgentColor( @@ -561,7 +560,6 @@ class Viewport extends React.Component< agents: string | SelectionEntry[], color: string ): void { - // TODO: if color is not present in color array, add it if (typeof agents === "string") { agents = this.convertAgentNameToSelectionEntry(agents); } @@ -594,8 +592,13 @@ class Viewport extends React.Component< } const typeCastAgentColors = agentColors as string[]; if (!typeCastAgentColors.includes(color)) { - // todo: if color is not present in color array, add it - throw new Error("Color not found"); + const uiDisplayData = this.selectionInterface.getUIDisplayData(); + const updatedColors = this.selectionInterface.setAgentColors( + uiDisplayData, + [...agentColors, color], + this.visGeometry.setColorForIds.bind(this.visGeometry) + ); + this.visGeometry.createMaterials(updatedColors); } const colorId = typeCastAgentColors.indexOf(color); return colorId; From 3965da37a1f47c07f343a87741bdf9cecdbe77ca Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Wed, 9 Aug 2023 09:41:50 -0700 Subject: [PATCH 10/34] update tests, add test for getColorChangeIds --- src/test/SelectionInterface.test.ts | 65 +++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/test/SelectionInterface.test.ts b/src/test/SelectionInterface.test.ts index 7bfc93cb..f87c06d2 100644 --- a/src/test/SelectionInterface.test.ts +++ b/src/test/SelectionInterface.test.ts @@ -231,6 +231,7 @@ describe("SelectionInterface module", () => { { name: "D", tags: [] }, ], hiddenAgents: [], + colorChangeAgents: [], }; const ids = si.getHighlightedIds(selectionStateHighlight); const allAs = [0, 1, 2, 3]; @@ -250,6 +251,7 @@ describe("SelectionInterface module", () => { { name: "D", tags: [""] }, ], hiddenAgents: [], + colorChangeAgents: [], }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -266,6 +268,7 @@ describe("SelectionInterface module", () => { { name: "E", tags: ["t1000"] }, ], hiddenAgents: [], + colorChangeAgents: [], }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -278,6 +281,7 @@ describe("SelectionInterface module", () => { const selectionStateHighlight = { highlightedAgents: [{ name: "E", tags: [""] }], hiddenAgents: [], + colorChangeAgents: [], }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -295,6 +299,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: [] }, { name: "C", tags: [] }, ], + colorChangeAgents: [], }; const ids = si.getHiddenIds(selectionStateHide); @@ -310,6 +315,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: ["t1", "t2"] }, { name: "B", tags: ["t1"] }, ], + colorChangeAgents: [], }; const ids = si.getHiddenIds(selectionStateHide); expect(ids).toEqual([1, 2, 3, 5, 7]); @@ -325,6 +331,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: [""] }, { name: "C", tags: ["", "t1", "t2"] }, ], + colorChangeAgents: [], }; const ids = si.getHiddenIds(selectionStateHide); @@ -332,6 +339,62 @@ describe("SelectionInterface module", () => { }); }); + describe("getColorChangeIds", () => { + test("Color change: select multiple by name", () => { + const si = new SelectionInterface(); + si.parse(idMapping); + const selectionStateColor = { + highlightedAgents: [], + hiddenAgents: [], + colorChangeAgents: [ + { name: "A", tags: [] }, + { name: "C", tags: [] }, + ], + }; + const ids = si.getColorChangeAgentIds( + selectionStateColor.colorChangeAgents + ); + + expect(ids).toEqual([0, 1, 2, 3, 8, 9, 10, 11]); + }); + + test("Color change: change color by name & tags", () => { + const si = new SelectionInterface(); + si.parse(idMapping); + const selectionStateColor = { + highlightedAgents: [], + hiddenAgents: [], + colorChangeAgents: [ + { name: "A", tags: ["t1", "t2"] }, + { name: "B", tags: ["t1"] }, + ], + }; + const ids = si.getColorChangeAgentIds( + selectionStateColor.colorChangeAgents + ); + expect(ids).toEqual([1, 2, 3, 5, 7]); + }); + + test("Color change: change color by name & null tag", () => { + const si = new SelectionInterface(); + si.parse(idMapping); + + const selectionStateColor = { + highlightedAgents: [], + hiddenAgents: [], + colorChangeAgents: [ + { name: "A", tags: [""] }, + { name: "C", tags: ["", "t1", "t2"] }, + ], + }; + const ids = si.getColorChangeAgentIds( + selectionStateColor.colorChangeAgents + ); + + expect(ids).toEqual([0, 8, 9, 10, 11]); + }); + }); + describe("getUIDisplayData", () => { test("Doesn't crash", () => { const si = new SelectionInterface(); @@ -406,6 +469,8 @@ describe("SelectionInterface module", () => { }); }); + describe("changeAgentColors", () => {}); + describe("setAgentColors", () => { const defaultColor = "#0"; const defaultColorListLength = 6; From 4e13fb43bcb6d5556757575ed2227cb75902cf44 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Wed, 16 Aug 2023 16:08:03 -0700 Subject: [PATCH 11/34] setColors function --- src/viewport/index.tsx | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 254195eb..99617339 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -203,17 +203,8 @@ class Viewport extends React.Component< } } onTrajectoryFileInfoChanged(trajectoryFileInfo); - this.visGeometry.clearColorMapping(); + this.setColors(agentColors); const uiDisplayData = this.selectionInterface.getUIDisplayData(); - const updatedColors = this.selectionInterface.setAgentColors( - uiDisplayData, - agentColors, - this.visGeometry.setColorForIds.bind(this.visGeometry) - ); - if (!isEqual(updatedColors, agentColors)) { - this.visGeometry.createMaterials(updatedColors); - } - this.visGeometry.finalizeIdColorMapping(); onUIDisplayDataChanged(uiDisplayData); } @@ -592,18 +583,27 @@ class Viewport extends React.Component< } const typeCastAgentColors = agentColors as string[]; if (!typeCastAgentColors.includes(color)) { - const uiDisplayData = this.selectionInterface.getUIDisplayData(); - const updatedColors = this.selectionInterface.setAgentColors( - uiDisplayData, - [...agentColors, color], - this.visGeometry.setColorForIds.bind(this.visGeometry) - ); - this.visGeometry.createMaterials(updatedColors); + const updatedColors = [...agentColors, color] as string[] + this.setColors(updatedColors); } const colorId = typeCastAgentColors.indexOf(color); return colorId; } + public setColors(agentColors: string[] | number[]): void { + this.visGeometry.clearColorMapping(); + const uiDisplayData = this.selectionInterface.getUIDisplayData(); + const updatedColors = this.selectionInterface.setAgentColors( + uiDisplayData, + agentColors, + this.visGeometry.setColorForIds.bind(this.visGeometry) + ); + if (!isEqual(updatedColors, agentColors)) { + this.visGeometry.createMaterials(updatedColors); + } + this.visGeometry.finalizeIdColorMapping(); + } + public applyColorToAgents(agentIds: number[], colorId: number): void { this.visGeometry.setColorForIds(agentIds, colorId); this.visGeometry.setColorChangeByIds(agentIds); From 135ee7b54b870b95f497dc788342cbd84901e852 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 17 Aug 2023 13:10:28 -0700 Subject: [PATCH 12/34] add tag/subagent selection to example viewer --- examples/Viewer.tsx | 88 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/examples/Viewer.tsx b/examples/Viewer.tsx index 98bf94c1..fa0038e2 100644 --- a/examples/Viewer.tsx +++ b/examples/Viewer.tsx @@ -90,6 +90,8 @@ interface ViewerState { customColor: string; assignedColor: string; selectedAgent: string; + subAgentNames: string[]; + selectedSubAgent: string; } interface BaseType { @@ -151,6 +153,8 @@ const initialState: ViewerState = { selectedColor: "", selectedAgent: "", customColor: "", + subAgentNames: [], + selectedSubAgent: "", }; type FrontEndError = typeof FrontEndError; @@ -606,6 +610,26 @@ class Viewer extends React.Component { public handleAgentSelection = (event) => { const value = event.target.value; this.setState({ selectedAgent: value }); + const subAgents = this.getSubAgentsforAgent(value); + if (subAgents) { + this.setState({ subAgentNames: subAgents }); + } + }; + + public handleSubAgentSelection = (event) => { + const value = event.target.value; + this.setState({ selectedSubAgent: value }); + }; + + public getSubAgentsforAgent = (agentName: string) => { + const agent = this.state.uiDisplayData.find( + (element) => element.name === agentName + ); + if (!agent) { + throw new Error("No agent found"); + return; + } + return agent.displayStates.map((element) => element.id); }; public assignColorToAgent = () => { @@ -616,17 +640,16 @@ class Viewer extends React.Component { throw new Error("No color selected"); return; } else { - // todo: handle tags - const entry: SelectionEntry = { + const subAgent: string[] = this.state.selectedSubAgent ? [this.state.selectedSubAgent] : []; + const entry: SelectionEntry[] = [{ name: this.state.selectedAgent, - tags: [], - }; - const entryArray: SelectionEntry[] = [entry]; + tags: subAgent, + }]; this.setState({ ...this.state, selectionStateInfo: { ...this.state.selectionStateInfo, - colorChangeAgents: entryArray, + colorChangeAgents: entry, }, assignedColor: this.state.selectedColor, }); @@ -684,15 +707,33 @@ class Viewer extends React.Component { - - - - - - - - - + + + + + + + + + @@ -855,7 +896,9 @@ class Viewer extends React.Component {
+ + + + ); +}; + +export default ColorPicker; diff --git a/examples/Viewer.tsx b/examples/Viewer.tsx index 0365e084..5763b70f 100644 --- a/examples/Viewer.tsx +++ b/examples/Viewer.tsx @@ -20,6 +20,7 @@ import PointSimulatorLive from "./PointSimulatorLive"; import PdbSimulator from "./PdbSimulator"; import SinglePdbSimulator from "./SinglePdbSimulator"; import CurveSimulator from "./CurveSimulator"; +import ColorPicker from "./ColorPicker"; import { SMOLDYN_TEMPLATE, UI_BASE_TYPES, @@ -31,7 +32,6 @@ import ConversionForm from "./ConversionForm"; import MetaballSimulator from "./MetaballSimulator"; import { TrajectoryType } from "../src/constants"; import { NetConnectionParams } from "../src/simularium"; -import { SelectionEntry } from "../src/simularium/SelectionInterface"; let playbackFile = "TEST_LIVEMODE_API"; //"medyan_paper_M:A_0.675.simularium"; let queryStringFile = ""; @@ -86,7 +86,6 @@ interface ViewerState { name: string; data: ISimulariumFile | null; } | null; - selectedColor: string; customColor: string; assignedColor: string; selectedAgent: string; @@ -146,11 +145,10 @@ const initialState: ViewerState = { selectionStateInfo: { highlightedAgents: [], hiddenAgents: [], - colorChangeAgents: [], + colorChanges: { agents: [], color: "" }, }, filePending: null, simulariumFile: null, - selectedColor: "", selectedAgent: "", customColor: "", subAgentNames: [], @@ -367,9 +365,8 @@ class Viewer extends React.Component { } public convertFile(obj: Record, fileType: TrajectoryType) { - simulariumController.convertAndLoadTrajectory( - this.netConnectionSettings, obj, fileType - ) + simulariumController + .convertAndLoadTrajectory(this.netConnectionSettings, obj, fileType) .then(() => { this.clearPendingFile(); }) @@ -603,74 +600,21 @@ class Viewer extends React.Component { URL.revokeObjectURL(downloadLink.href); } - public handleColorSelection = (event) => { - this.setState({ selectedColor: event.target.value }); - }; - - public handleAgentSelection = (event) => { - const value = event.target.value; - this.setState({ selectedAgent: value }); - const subAgents = this.getSubAgentsforAgent(value); - if (subAgents) { - this.setState({ subAgentNames: subAgents }); - } - }; - - public handleSubAgentSelection = (event) => { - const value = event.target.value; - this.setState({ selectedSubAgent: value }); - }; - - public getSubAgentsforAgent = (agentName: string) => { - const agent = this.state.uiDisplayData.find( - (element) => element.name === agentName - ); - if (!agent) { - throw new Error("No agent found"); - return; - } - return agent.displayStates.map((element) => element.id); - }; - - public assignColorToAgent = () => { - if (!this.state.selectedAgent) { - throw new Error("No agent selected"); - return; - } else if (!this.state.selectedColor) { - throw new Error("No color selected"); - return; - } else { - const subAgent: string[] = this.state.selectedSubAgent ? [this.state.selectedSubAgent] : []; - const entry: SelectionEntry[] = [{ - name: this.state.selectedAgent, - tags: subAgent, - }]; - this.setState({ - ...this.state, - selectionStateInfo: { - ...this.state.selectionStateInfo, - colorChangeAgents: entry, - }, - assignedColor: this.state.selectedColor, - }); - } - }; - - public receiveNewColorInput = (event) => { - const value = event.target.value; - this.setState({ customColor: value }); + public updateAgentColorArray = (color) => { + const agentColors = [...this.state.agentColors, color] as string[]; + this.setState({ agentColors }); }; - public addColorToColorArray = (event) => { - const hexColorCodeRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; - const color = this.state.customColor; - if (hexColorCodeRegex.test(color)) { - this.setState({ - agentColors: [...this.state.agentColors, color] as string[], - }); - } else { - alert("Please enter a valid hex color code"); - } + public setColorSelectionInfo = (colorChanges) => { + this.setState({ + ...this.state, + selectionStateInfo: { + hiddenAgents: this.state.selectionStateInfo.hiddenAgents, + highlightedAgents: + this.state.selectionStateInfo.highlightedAgents, + colorChanges: colorChanges, + }, + }); }; public render(): JSX.Element { @@ -932,49 +876,13 @@ class Viewer extends React.Component { {simulariumController.tickIntervalLength}

- Color change agent selections: - - - - - - +
Date: Wed, 23 Aug 2023 16:08:33 -0700 Subject: [PATCH 17/34] allow to add agent color --- examples/ColorPicker.tsx | 11 ++++++----- examples/Viewer.tsx | 12 +----------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/examples/ColorPicker.tsx b/examples/ColorPicker.tsx index f3a75f20..1eeb9dbe 100644 --- a/examples/ColorPicker.tsx +++ b/examples/ColorPicker.tsx @@ -12,6 +12,7 @@ const ColorPicker = ({ const [selectedAgent, setSelectedAgent] = useState(""); const [selectedColor, setSelectedColor] = useState(""); const [selectedSubagent, setSelectedSubAgent] = useState(""); + const [colorToAppend, setColorToAppend] = useState(""); const getSubAgentsforAgent = (agentName: string) => { const agent = uiDisplayData.find( @@ -55,9 +56,7 @@ const ColorPicker = ({ } }; - const addColorToColorArray = (event) => { - const customColor = event.target.value; - + const addColorToColorArray = (customColor: string) => { const hexColorCodeRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; const color = customColor; if (hexColorCodeRegex.test(color)) { @@ -110,9 +109,11 @@ const ColorPicker = ({ id="colorAddition" type="text" placeholder="add Hex Color" - onChange={addColorToColorArray} + onChange={(event) => { + console.log(event.target.value) + setColorToAppend(event.target.value)}} > - diff --git a/examples/Viewer.tsx b/examples/Viewer.tsx index 5763b70f..27d98a62 100644 --- a/examples/Viewer.tsx +++ b/examples/Viewer.tsx @@ -86,11 +86,6 @@ interface ViewerState { name: string; data: ISimulariumFile | null; } | null; - customColor: string; - assignedColor: string; - selectedAgent: string; - subAgentNames: string[]; - selectedSubAgent: string; } interface BaseType { @@ -149,10 +144,6 @@ const initialState: ViewerState = { }, filePending: null, simulariumFile: null, - selectedAgent: "", - customColor: "", - subAgentNames: [], - selectedSubAgent: "", }; type FrontEndError = typeof FrontEndError; @@ -879,7 +870,7 @@ class Viewer extends React.Component { @@ -906,7 +897,6 @@ class Viewer extends React.Component { showPaths={this.state.showPaths} onError={this.onError} backgroundColor={[0, 0, 0]} - assignedColor={this.state.assignedColor} />
From ccc229fd6fd20e9ee8a9a903293c810bcbaf2eca Mon Sep 17 00:00:00 2001 From: meganrm Date: Wed, 23 Aug 2023 16:10:38 -0700 Subject: [PATCH 18/34] move more of the color change to visGeometry --- src/simularium/SelectionInterface.ts | 93 +++++++++++++++------------ src/test/SelectionInterface.test.ts | 14 ++--- src/viewport/index.tsx | 94 +++++++++------------------- src/visGeometry/color-utils.ts | 18 ++++++ src/visGeometry/index.ts | 42 ++++++++++--- 5 files changed, 142 insertions(+), 119 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 62e251f0..cc7785fa 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -3,6 +3,8 @@ import { EncodedTypeMapping } from "./types"; import { convertColorNumberToString } from "../visGeometry/color-utils"; // An individual entry parsed from an encoded name +// The encoded names can be just a name or a name plus a +// state, such as "proteinA#bound" interface DecodedTypeEntry { id: number; name: string; @@ -15,10 +17,15 @@ export interface SelectionEntry { tags: string[]; } +export interface ColorChanges { + agents: SelectionEntry[]; + color: string; +} + export interface SelectionStateInfo { highlightedAgents: SelectionEntry[]; hiddenAgents: SelectionEntry[]; - colorChangeAgents: SelectionEntry[]; + colorChanges: ColorChanges; } interface DisplayStateEntry { @@ -80,6 +87,10 @@ class SelectionInterface { } public decode(encodedName: string, color: string, idParam?: number): void { + /** + * Takes an encoded name, the color and the agent id, and stores + * a decoded entry on the class mapped by the agent name + */ let name = ""; let tags: string[] = []; const id = idParam !== undefined ? idParam : -1; @@ -186,14 +197,9 @@ class SelectionInterface { } return []; } - /* - * If an entity has both a name and all the tags specified in the - * selection state info, it will be considered highlighted - */ - public getHighlightedIds(info: SelectionStateInfo): number[] { - const requests = info.highlightedAgents; - let indices: number[] = []; + public getAgentIdsByNamesAndTags(requests: SelectionEntry[]): number[] { + let indices: number[] = []; requests.forEach((r) => { const name = r.name; const tags = r.tags; @@ -202,33 +208,22 @@ class SelectionInterface { return indices; } + /* + * If an entity has both a name and all the tags specified in the + * selection state info, it will be considered highlighted + */ + public getHighlightedIds(info: SelectionStateInfo): number[] { + const requests = info.highlightedAgents; + return this.getAgentIdsByNamesAndTags(requests); + } + /* * If an entry has a name specified in the selection state info * or a tag specified, it will be considered hidden */ public getHiddenIds(info: SelectionStateInfo): number[] { const requests = info.hiddenAgents; - let indices: number[] = []; - - requests.forEach((r) => { - const name = r.name; - const tags = r.tags; - indices = [...indices, ...this.getIds(name, tags)]; - }); - - return indices; - } - - public getColorChangeAgentIds(info: SelectionEntry[]): number[] { - const requests = info; - let indices: number[] = []; - - requests.forEach((r) => { - const name = r.name; - const tags = r.tags; - indices = [...indices, ...this.getIds(name, tags)]; - }); - return indices; + return this.getAgentIdsByNamesAndTags(requests); } public clear(): void { @@ -276,19 +271,39 @@ class SelectionInterface { } private updateUiDataColor( - entry: UIDisplayEntry, - id: number, + agentName: string, + idsToUpdate: number[], color: number | string - ) { - const tagsToUpdate = this.getTags(entry.name, id); - entry.displayStates.forEach((displayState: DisplayStateEntry) => { - if (tagsToUpdate.includes(displayState.id)) { - displayState.color = convertColorNumberToString(color); + ): void { + const newColor = convertColorNumberToString(color); + const entry = this.entries[agentName]; + entry.forEach((displayState) => { + if (idsToUpdate.includes(displayState.id)) { + displayState.color = newColor; + } + }); + } + + public updateAgentColors( + agentIds: number[], + colorChanges: ColorChanges + ): void { + const uiDisplayData = this.getUIDisplayData(); + colorChanges.agents.forEach((agentToUpdate) => { + for (const group of uiDisplayData) { + if (group.name === agentToUpdate.name) { + this.updateUiDataColor( + group.name, + agentIds, + colorChanges.color + ); + break; + } } }); } - public setAgentColors( + public setInitialAgentColors( uiDisplayData: UIDisplayData, colors: (string | number)[], setColorForIds: (ids: number[], colorIndex: number) => void @@ -327,8 +342,8 @@ class SelectionInterface { } else { // need update the display data with the default color being used this.updateUiDataColor( - group, - ids[index], + group.name, + [ids[index]], colors[groupColorIndex] ); } diff --git a/src/test/SelectionInterface.test.ts b/src/test/SelectionInterface.test.ts index f87c06d2..467f357c 100644 --- a/src/test/SelectionInterface.test.ts +++ b/src/test/SelectionInterface.test.ts @@ -548,7 +548,7 @@ describe("SelectionInterface module", () => { test("it will create a new material for each of the use defined colors", () => { const numberOfNewColors = Object.keys(agentColors).length + 2; // two additional colors for G - const updatedColors = si.setAgentColors( + const updatedColors = si.setInitialAgentColors( uiDisplayData, colorList, setColorForIds @@ -563,31 +563,31 @@ describe("SelectionInterface module", () => { // initially should have no color expect(uiDisplayDataForA?.color).toEqual(""); expect(uiDisplayDataForB?.color).toEqual(""); - si.setAgentColors(uiDisplayData, colorList, setColorForIds); + si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); expect(uiDisplayDataForA?.color).toEqual("#aaaaaa"); expect(uiDisplayDataForB?.color).toEqual("#bbbbbb"); }); test("If no user colors are provided entry will get a default color", () => { // initially should have no color expect(uiDisplayDataForE?.color).toEqual(""); - si.setAgentColors(uiDisplayData, colorList, setColorForIds); + si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); expect(uiDisplayDataForE?.color).toEqual("#00"); expect(setColorForIds).toHaveBeenCalledWith([13], 0); }); test("If no user colors are provided all the ids for an entry will get a default color", () => { - si.setAgentColors(uiDisplayData, colorList, setColorForIds); + si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); expect(setColorForIds).toHaveBeenCalledWith([13], 0); }); test("if all the colors are the same, the parent entry will also get that color, even if no unmodified color set", () => { - si.setAgentColors(uiDisplayData, colorList, setColorForIds); + si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); expect(uiDisplayDataForF?.color).toEqual("#ffffff"); }); test("If user defined colors are different, parent doesn't get a color", () => { - si.setAgentColors(uiDisplayData, colorList, setColorForIds); + si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); expect(uiDisplayDataForG?.color).toEqual(""); }); test("If user colors are provided each id will be set with the new color", () => { - si.setAgentColors(uiDisplayData, colorList, setColorForIds); + si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); // the first new user color will be appended to the end of the list const indexOfColorForA = defaultColorListLength; // these are all the agent A ids, each should get the first new color assigned diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 99617339..bf2c6878 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -17,7 +17,8 @@ import { TrajectoryFileInfoAny } from "../simularium/types"; import { updateTrajectoryFileInfoFormat } from "../simularium/versionHandlers"; import { FrontEndError, ErrorLevel } from "../simularium/FrontEndError"; import { RenderStyle, VisGeometry, NO_AGENT } from "../visGeometry"; -import { SelectionEntry } from "../simularium/SelectionInterface"; +import { ColorChanges } from "../simularium/SelectionInterface"; + export type PropColor = string | number | [number, number, number]; @@ -42,7 +43,6 @@ type ViewportProps = { selectionStateInfo: SelectionStateInfo; showCameraControls: boolean; onError?: (error: FrontEndError) => void; - assignedColor: string; } & Partial; const defaultProps = { @@ -310,15 +310,11 @@ class Viewport extends React.Component< } if ( !isEqual( - selectionStateInfo.colorChangeAgents, - prevProps.selectionStateInfo.colorChangeAgents - ) || - !isEqual(this.props.assignedColor, prevProps.assignedColor) + selectionStateInfo.colorChanges, + prevProps.selectionStateInfo.colorChanges + ) ) { - this.changeAgentColor( - selectionStateInfo.colorChangeAgents, - this.props.assignedColor - ); + this.changeAgentsColor(selectionStateInfo.colorChanges); } } @@ -547,66 +543,36 @@ class Viewport extends React.Component< } } - public changeAgentColor( - agents: string | SelectionEntry[], - color: string - ): void { - if (typeof agents === "string") { - agents = this.convertAgentNameToSelectionEntry(agents); - } - const agentIds = this.selectionInterface.getColorChangeAgentIds(agents); - const colorId = this.getColorId( - color, - this.props.agentColors as string[] - ); - this.applyColorToAgents(agentIds, colorId); + private getColorId(color: string): number { + /** + * Check if the new color is in our current array of color options, if not, + * add it before returning the index + */ + return this.visGeometry.addNewColor(color); } - public convertAgentNameToSelectionEntry(name: string): SelectionEntry[] { - const uiDisplayData = this.selectionInterface.getUIDisplayData(); - const agentNames = uiDisplayData.map((a) => a.name); - if (!agentNames.includes(name)) { - throw new Error("Agent name not found"); - } else { - const colorChangeAgents = { - name: name, - tags: [], - }; - return [colorChangeAgents]; - } - } + public changeAgentsColor(colorChanges: ColorChanges): void { + const { agents, color } = colorChanges; + const agentIds = + this.selectionInterface.getAgentIdsByNamesAndTags(agents); + this.selectionInterface.updateAgentColors(agentIds, colorChanges); + const colorId = this.getColorId(color); + this.visGeometry.applyColorToAgents(agentIds, colorId); - public getColorId(color: string, agentColors: string[] | number[]): number { - const hexColorCodeRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; - if (!hexColorCodeRegex.test(color)) { - throw new Error("Invalid color code"); - } - const typeCastAgentColors = agentColors as string[]; - if (!typeCastAgentColors.includes(color)) { - const updatedColors = [...agentColors, color] as string[] - this.setColors(updatedColors); - } - const colorId = typeCastAgentColors.indexOf(color); - return colorId; } public setColors(agentColors: string[] | number[]): void { - this.visGeometry.clearColorMapping(); - const uiDisplayData = this.selectionInterface.getUIDisplayData(); - const updatedColors = this.selectionInterface.setAgentColors( - uiDisplayData, - agentColors, - this.visGeometry.setColorForIds.bind(this.visGeometry) - ); - if (!isEqual(updatedColors, agentColors)) { - this.visGeometry.createMaterials(updatedColors); - } - this.visGeometry.finalizeIdColorMapping(); - } - - public applyColorToAgents(agentIds: number[], colorId: number): void { - this.visGeometry.setColorForIds(agentIds, colorId); - this.visGeometry.setColorChangeByIds(agentIds); + this.visGeometry.clearColorMapping(); + const uiDisplayData = this.selectionInterface.getUIDisplayData(); + const updatedColors = this.selectionInterface.setInitialAgentColors( + uiDisplayData, + agentColors, + this.visGeometry.setColorForIds.bind(this.visGeometry) + ); + if (!isEqual(updatedColors, agentColors)) { + this.visGeometry.createMaterials(updatedColors); + } + this.visGeometry.finalizeIdColorMapping(); } public stopAnimate(): void { diff --git a/src/visGeometry/color-utils.ts b/src/visGeometry/color-utils.ts index 89fbafea..d39b393c 100644 --- a/src/visGeometry/color-utils.ts +++ b/src/visGeometry/color-utils.ts @@ -13,3 +13,21 @@ export function convertColorNumberToString(color: number | string): string { } return "#" + new Color(color).getHexString(); } + +export const checkHexColor = (color: string): string => { + const hexColorCodeRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; + if (!hexColorCodeRegex.test(color)) { + throw new Error("Invalid color code"); + } + return color; +}; + +export const agentColorArrayAreStrings = ( + agentColors: string[] | number[] +): boolean => { + if (typeof agentColors[0] === "string") { + return true; + } else { + return false; + } +}; diff --git a/src/visGeometry/index.ts b/src/visGeometry/index.ts index 91a44cdc..eb2e5856 100644 --- a/src/visGeometry/index.ts +++ b/src/visGeometry/index.ts @@ -30,7 +30,7 @@ import * as EssentialsPlugin from "@tweakpane/plugin-essentials"; import { ButtonGridApi } from "@tweakpane/plugin-essentials/dist/types/button-grid/api/button-grid"; import jsLogger from "js-logger"; import { ILogger, ILogLevel } from "js-logger"; -import { cloneDeep, noop } from "lodash"; +import { cloneDeep, isEqual, map, noop, round } from "lodash"; import VisAgent from "./VisAgent"; import VisTypes from "../simularium/VisTypes"; @@ -116,7 +116,6 @@ class VisGeometry { public visAgentInstances: Map; public fixLightsToCamera: boolean; public highlightedIds: number[]; - public colorChangeIds: number[]; public hiddenIds: number[]; public agentPaths: Map; public mlogger: ILogger; @@ -188,7 +187,6 @@ class VisGeometry { this.visAgentInstances = new Map(); this.fixLightsToCamera = true; this.highlightedIds = []; - this.colorChangeIds = []; this.hiddenIds = []; this.needToCenterCamera = false; this.needToReOrientCamera = false; @@ -726,11 +724,6 @@ class VisGeometry { this.updateScene(this.currentSceneAgents); } - public setColorChangeByIds(ids: number[]): void { - this.colorChangeIds = ids; - this.updateScene(this.currentSceneAgents); - } - public dehighlight(): void { this.setHighlightByIds([]); } @@ -1093,7 +1086,25 @@ class VisGeometry { } } - public addNewColor(color: number | string): void { + private indexOfColor(color: number[]) { + const colorArray = this.colorsData; + const colorToCheck = map(color, (num) => round(num, 6)); + for (let i = 0; i < colorArray.length - 3; i += 4) { + const index = i / 4; + const currentColor = [ + round(this.colorsData[i], 6), + round(this.colorsData[i + 1], 6), + round(this.colorsData[i + 2], 6), + this.colorsData[i + 3], + ]; + if (isEqual(currentColor, colorToCheck)) { + return index; + } + } + return -1; + } + + public addNewColor(color: number | string): number { const colorNumber = convertColorStringToNumber(color); const newColor = [ ((colorNumber & 0x00ff0000) >> 16) / 255.0, @@ -1101,10 +1112,18 @@ class VisGeometry { ((colorNumber & 0x000000ff) >> 0) / 255.0, 1.0, ]; + const currentIndex = this.indexOfColor(newColor); + if (currentIndex !== -1) { + return currentIndex; + } + + const newIndex = this.colorsData.length; const newArray = [...this.colorsData, ...newColor]; const newColorData = new Float32Array(newArray.length); newColorData.set(newArray); this.colorsData = newColorData; + this.renderer.updateColors(this.colorsData.length / 4, this.colorsData); + return newIndex; } public createMaterials(colors: (number | string)[]): void { @@ -1167,6 +1186,11 @@ class VisGeometry { ids.forEach((id) => this.setColorForId(id, colorId)); } + public applyColorToAgents(agentIds: number[], colorId: number): void { + this.setColorForIds(agentIds, colorId); + this.updateScene(this.currentSceneAgents); + } + public getColorForIndex(index: number): Color { return new Color( this.colorsData[index * 4], From 741e934d7281f056c0e2541465cc6ad71cdc4ef7 Mon Sep 17 00:00:00 2001 From: meganrm Date: Wed, 23 Aug 2023 16:13:26 -0700 Subject: [PATCH 19/34] remove unneeded function --- src/visGeometry/color-utils.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/visGeometry/color-utils.ts b/src/visGeometry/color-utils.ts index d39b393c..8a234627 100644 --- a/src/visGeometry/color-utils.ts +++ b/src/visGeometry/color-utils.ts @@ -21,13 +21,3 @@ export const checkHexColor = (color: string): string => { } return color; }; - -export const agentColorArrayAreStrings = ( - agentColors: string[] | number[] -): boolean => { - if (typeof agentColors[0] === "string") { - return true; - } else { - return false; - } -}; From e0f0d881bde295074f719759f7137b5a141abe51 Mon Sep 17 00:00:00 2001 From: meganrm Date: Wed, 23 Aug 2023 16:31:13 -0700 Subject: [PATCH 20/34] update tests --- src/test/SelectionInterface.test.ts | 94 +++++++++-------------------- 1 file changed, 29 insertions(+), 65 deletions(-) diff --git a/src/test/SelectionInterface.test.ts b/src/test/SelectionInterface.test.ts index 467f357c..c48126e7 100644 --- a/src/test/SelectionInterface.test.ts +++ b/src/test/SelectionInterface.test.ts @@ -23,6 +23,10 @@ const idMapping = { }; const color = ""; +const initialColorChanges = { + agents: [], + color, +}; describe("SelectionInterface module", () => { describe("decode", () => { @@ -231,7 +235,7 @@ describe("SelectionInterface module", () => { { name: "D", tags: [] }, ], hiddenAgents: [], - colorChangeAgents: [], + colorChanges: initialColorChanges, }; const ids = si.getHighlightedIds(selectionStateHighlight); const allAs = [0, 1, 2, 3]; @@ -251,7 +255,7 @@ describe("SelectionInterface module", () => { { name: "D", tags: [""] }, ], hiddenAgents: [], - colorChangeAgents: [], + colorChanges: initialColorChanges, }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -268,7 +272,7 @@ describe("SelectionInterface module", () => { { name: "E", tags: ["t1000"] }, ], hiddenAgents: [], - colorChangeAgents: [], + colorChanges: initialColorChanges, }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -281,7 +285,7 @@ describe("SelectionInterface module", () => { const selectionStateHighlight = { highlightedAgents: [{ name: "E", tags: [""] }], hiddenAgents: [], - colorChangeAgents: [], + colorChanges: initialColorChanges, }; const ids = si.getHighlightedIds(selectionStateHighlight); @@ -299,7 +303,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: [] }, { name: "C", tags: [] }, ], - colorChangeAgents: [], + colorChanges: initialColorChanges, }; const ids = si.getHiddenIds(selectionStateHide); @@ -315,7 +319,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: ["t1", "t2"] }, { name: "B", tags: ["t1"] }, ], - colorChangeAgents: [], + colorChanges: initialColorChanges, }; const ids = si.getHiddenIds(selectionStateHide); expect(ids).toEqual([1, 2, 3, 5, 7]); @@ -331,7 +335,7 @@ describe("SelectionInterface module", () => { { name: "A", tags: [""] }, { name: "C", tags: ["", "t1", "t2"] }, ], - colorChangeAgents: [], + colorChanges: initialColorChanges, }; const ids = si.getHiddenIds(selectionStateHide); @@ -339,62 +343,6 @@ describe("SelectionInterface module", () => { }); }); - describe("getColorChangeIds", () => { - test("Color change: select multiple by name", () => { - const si = new SelectionInterface(); - si.parse(idMapping); - const selectionStateColor = { - highlightedAgents: [], - hiddenAgents: [], - colorChangeAgents: [ - { name: "A", tags: [] }, - { name: "C", tags: [] }, - ], - }; - const ids = si.getColorChangeAgentIds( - selectionStateColor.colorChangeAgents - ); - - expect(ids).toEqual([0, 1, 2, 3, 8, 9, 10, 11]); - }); - - test("Color change: change color by name & tags", () => { - const si = new SelectionInterface(); - si.parse(idMapping); - const selectionStateColor = { - highlightedAgents: [], - hiddenAgents: [], - colorChangeAgents: [ - { name: "A", tags: ["t1", "t2"] }, - { name: "B", tags: ["t1"] }, - ], - }; - const ids = si.getColorChangeAgentIds( - selectionStateColor.colorChangeAgents - ); - expect(ids).toEqual([1, 2, 3, 5, 7]); - }); - - test("Color change: change color by name & null tag", () => { - const si = new SelectionInterface(); - si.parse(idMapping); - - const selectionStateColor = { - highlightedAgents: [], - hiddenAgents: [], - colorChangeAgents: [ - { name: "A", tags: [""] }, - { name: "C", tags: ["", "t1", "t2"] }, - ], - }; - const ids = si.getColorChangeAgentIds( - selectionStateColor.colorChangeAgents - ); - - expect(ids).toEqual([0, 8, 9, 10, 11]); - }); - }); - describe("getUIDisplayData", () => { test("Doesn't crash", () => { const si = new SelectionInterface(); @@ -469,9 +417,25 @@ describe("SelectionInterface module", () => { }); }); - describe("changeAgentColors", () => {}); + describe("updateAgentColors", () => { + test("it will update the entries with a new color", () => { + const agentIds = [0]; + const newColor = "#111111"; + const colorChanges = { + agents: [{ name: "A", tags: [] }], + color: newColor, + }; + const si = new SelectionInterface(); + si.parse(idMapping); + const oldColors = si.getColorsForName("A"); + expect(oldColors).not.toContain(newColor); + si.updateAgentColors(agentIds, colorChanges); + const colors = si.getColorsForName("A"); + expect(colors).toContain(newColor); + }); + }); - describe("setAgentColors", () => { + describe("setInitialAgentColors", () => { const defaultColor = "#0"; const defaultColorListLength = 6; let si: SelectionInterface; From 9c502b1b4d720c3f436a2042fd4d77b60b55104b Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 7 Sep 2023 16:17:56 -0700 Subject: [PATCH 21/34] update colorChanges typing to array --- src/simularium/SelectionInterface.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index cc7785fa..9d7eeea2 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -25,7 +25,7 @@ export interface ColorChanges { export interface SelectionStateInfo { highlightedAgents: SelectionEntry[]; hiddenAgents: SelectionEntry[]; - colorChanges: ColorChanges; + colorChanges: ColorChanges[]; } interface DisplayStateEntry { @@ -277,6 +277,7 @@ class SelectionInterface { ): 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; From 6fa78d249208d3d69835780d725870cfe00f5fd3 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 7 Sep 2023 16:19:07 -0700 Subject: [PATCH 22/34] bug fix restore code to onTrajFileInfo --- src/viewport/index.tsx | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index bf2c6878..3bb4e1d0 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -203,9 +203,17 @@ class Viewport extends React.Component< } } onTrajectoryFileInfoChanged(trajectoryFileInfo); - this.setColors(agentColors); - const uiDisplayData = this.selectionInterface.getUIDisplayData(); - onUIDisplayDataChanged(uiDisplayData); + this.visGeometry.clearColorMapping(); + const uiDisplayData = this.selectionInterface.getUIDisplayData(); + const updatedColors = this.selectionInterface.setInitialAgentColors( + uiDisplayData, + agentColors, + this.visGeometry.setColorForIds.bind(this.visGeometry) + ); + if (!isEqual(updatedColors, agentColors)) { + this.visGeometry.createMaterials(updatedColors); + } + onUIDisplayDataChanged(uiDisplayData); } public componentDidMount(): void { @@ -551,14 +559,16 @@ class Viewport extends React.Component< return this.visGeometry.addNewColor(color); } - public changeAgentsColor(colorChanges: ColorChanges): void { - const { agents, color } = colorChanges; + public changeAgentsColor(colorChanges: ColorChanges[]): void { + colorChanges.forEach((colorChange) => { + const { agents, color } = colorChange; + // const { agents, color } = colorChanges; const agentIds = this.selectionInterface.getAgentIdsByNamesAndTags(agents); - this.selectionInterface.updateAgentColors(agentIds, colorChanges); + this.selectionInterface.updateAgentColors(agentIds, colorChange); const colorId = this.getColorId(color); this.visGeometry.applyColorToAgents(agentIds, colorId); - + }); } public setColors(agentColors: string[] | number[]): void { @@ -572,7 +582,6 @@ class Viewport extends React.Component< if (!isEqual(updatedColors, agentColors)) { this.visGeometry.createMaterials(updatedColors); } - this.visGeometry.finalizeIdColorMapping(); } public stopAnimate(): void { From 7d33f9265018aebda1d0c71576cd2a66cababc8a Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 7 Sep 2023 16:19:35 -0700 Subject: [PATCH 23/34] cleanup unused colormapping in VisGeo --- src/visGeometry/index.ts | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/visGeometry/index.ts b/src/visGeometry/index.ts index eb2e5856..b4b83c7a 100644 --- a/src/visGeometry/index.ts +++ b/src/visGeometry/index.ts @@ -146,7 +146,6 @@ class VisGeometry { public agentPathGroup: Group; public instancedMeshGroup: Group; public idColorMapping: Map; - private isIdColorMappingSet: boolean; private supportsWebGL2Rendering: boolean; private lodBias: number; private lodDistanceStops: number[]; @@ -181,7 +180,6 @@ class VisGeometry { this.geometryStore = new GeometryStore(loggerLevel); this.scaleMapping = new Map(); this.idColorMapping = new Map(); - this.isIdColorMappingSet = false; this.followObjectId = NO_AGENT; this.visAgents = []; this.visAgentInstances = new Map(); @@ -1134,7 +1132,6 @@ class VisGeometry { public clearColorMapping(): void { this.idColorMapping.clear(); - this.isIdColorMappingSet = false; } private getColorIndexForTypeId(typeId: number): number { @@ -1172,17 +1169,6 @@ class VisGeometry { * @param ids agent ids that should all have the same color * @param colorId index into the color array */ - - //TODO: this is commented out because I'm unsure how best to handle this - // the purpose of this feature is to allow color mapping to be changed - // should we just remove this error handling? or should the color change methods - // clear the mapping, apply the color change then reset it? - - // if (this.isIdColorMappingSet) { - // throw new FrontEndError( - // "Attempted to set agent-color after color mapping was finalized" - // ); - // } ids.forEach((id) => this.setColorForId(id, colorId)); } @@ -1199,10 +1185,6 @@ class VisGeometry { ); } - public finalizeIdColorMapping(): void { - this.isIdColorMappingSet = true; - } - /** * Data Management */ @@ -1600,9 +1582,6 @@ class VisGeometry { * Update Scene **/ private updateScene(agents: AgentData[]): void { - if (!this.isIdColorMappingSet) { - return; - } this.currentSceneAgents = agents; // values for updating agent path From 81ebadd2731e70aaa95248f7ec7a7746e6999b3f Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Tue, 19 Sep 2023 12:26:33 -0700 Subject: [PATCH 24/34] working updateUiData --- src/simularium/SelectionInterface.ts | 32 +++++++++++--- src/viewport/index.tsx | 64 ++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 25 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 9d7eeea2..31ff02f2 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -1,6 +1,7 @@ -import { filter, find, uniq } from "lodash"; +import { filter, find, set, uniq } from "lodash"; import { EncodedTypeMapping } from "./types"; import { convertColorNumberToString } from "../visGeometry/color-utils"; +import _ from "lodash"; // An individual entry parsed from an encoded name // The encoded names can be just a name or a name plus a @@ -231,14 +232,16 @@ class SelectionInterface { } public getUIDisplayData(): UIDisplayData { - return Object.keys(this.entries).map((name) => { + let data = Object.keys(this.entries).map((name) => { const displayStates: DisplayStateEntry[] = []; const encounteredTags: string[] = []; const hasMultipleStates = Object.keys(this.entries[name]).length > 1; + // console.log(name, this.entries[name]) this.entries[name].forEach((entry: DecodedTypeEntry) => { // add unmodified state if there are multiple states, and one of them // has no state tags + // console.log("entry", entry.id, "color", entry.color); if (!entry.tags.length && hasMultipleStates) { displayStates.push({ name: "", @@ -260,14 +263,24 @@ class SelectionInterface { displayStates.push(displayState); }); }); - - const color = ""; + const color = this.entries[name][0].color || ""; return { name, displayStates, color, }; }); + + // console.log("deep clone of return value", _.cloneDeep(data)); + // console.log("return value of getUiDisplayData", data); + // setTimeout(() => { + // console.log( + // "delayed deep clone of return value", + // _.cloneDeep(data) + // ); + // console.log("delayed return value of getUiDisplayData", data); + // }, 0); + return data; } private updateUiDataColor( @@ -280,6 +293,7 @@ class SelectionInterface { // if no display state update parent color entry.forEach((displayState) => { if (idsToUpdate.includes(displayState.id)) { + console.log("updateUiDataColor"); displayState.color = newColor; } }); @@ -287,9 +301,9 @@ class SelectionInterface { public updateAgentColors( agentIds: number[], - colorChanges: ColorChanges + colorChanges: ColorChanges, + uiDisplayData: UIDisplayData ): void { - const uiDisplayData = this.getUIDisplayData(); colorChanges.agents.forEach((agentToUpdate) => { for (const group of uiDisplayData) { if (group.name === agentToUpdate.name) { @@ -324,6 +338,11 @@ class SelectionInterface { // 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, defaultColorIndex); + this.updateUiDataColor( + group.name, + ids, + colors[defaultColorIndex] + ); } else { // otherwise, we need to update any user defined colors newColors.forEach((color, index) => { @@ -375,7 +394,6 @@ class SelectionInterface { defaultColorIndex++; } }); - return colors; } } diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 3bb4e1d0..c857eb23 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -19,7 +19,6 @@ import { FrontEndError, ErrorLevel } from "../simularium/FrontEndError"; import { RenderStyle, VisGeometry, NO_AGENT } from "../visGeometry"; import { ColorChanges } from "../simularium/SelectionInterface"; - export type PropColor = string | number | [number, number, number]; type ViewportProps = { @@ -202,18 +201,22 @@ class Viewport extends React.Component< console.log("error parsing 'typeMapping' data", e); } } + const uiDisplayData = this.selectionInterface.getUIDisplayData(); + // console.log("in on trajfileinfo", uiDisplayData); onTrajectoryFileInfoChanged(trajectoryFileInfo); - this.visGeometry.clearColorMapping(); - const uiDisplayData = this.selectionInterface.getUIDisplayData(); - const updatedColors = this.selectionInterface.setInitialAgentColors( - uiDisplayData, - agentColors, - this.visGeometry.setColorForIds.bind(this.visGeometry) - ); - if (!isEqual(updatedColors, agentColors)) { - this.visGeometry.createMaterials(updatedColors); - } - onUIDisplayDataChanged(uiDisplayData); + this.visGeometry.clearColorMapping(); + + const updatedColors = this.selectionInterface.setInitialAgentColors( + uiDisplayData, + agentColors, + this.visGeometry.setColorForIds.bind(this.visGeometry) + ); + if (!isEqual(updatedColors, agentColors)) { + this.visGeometry.createMaterials(updatedColors); + } + + onUIDisplayDataChanged(uiDisplayData); + // console.log("in on trajfileinfo after on data changes", uiDisplayData); } public componentDidMount(): void { @@ -322,6 +325,13 @@ class Viewport extends React.Component< prevProps.selectionStateInfo.colorChanges ) ) { + // console.log( + // "in update", + // this.selectionInterface.getUIDisplayData() + // ); + console.log( + "firing change agents colors in component did update" + ); this.changeAgentsColor(selectionStateInfo.colorChanges); } } @@ -560,18 +570,36 @@ class Viewport extends React.Component< } public changeAgentsColor(colorChanges: ColorChanges[]): void { + const { + onUIDisplayDataChanged, + agentColors, + } = this.props; colorChanges.forEach((colorChange) => { const { agents, color } = colorChange; - // const { agents, color } = colorChanges; - const agentIds = - this.selectionInterface.getAgentIdsByNamesAndTags(agents); - this.selectionInterface.updateAgentColors(agentIds, colorChange); - const colorId = this.getColorId(color); - this.visGeometry.applyColorToAgents(agentIds, colorId); + let uiDisplayData = this.selectionInterface.getUIDisplayData(); + // console.log("uidisplay data in change agents color", uiDisplayData); + const agentIds = + this.selectionInterface.getAgentIdsByNamesAndTags(agents); + + this.selectionInterface.updateAgentColors(agentIds, colorChange, uiDisplayData); + const colorId = this.getColorId(color); + this.visGeometry.applyColorToAgents(agentIds, colorId); + // this.selectionInterface.setInitialAgentColors( + // uiDisplayData, + // agentColors, + // this.visGeometry.setColorForIds.bind(this.visGeometry) + // ); + const updatedUiDisplayData = this.selectionInterface.getUIDisplayData(); + onUIDisplayDataChanged(updatedUiDisplayData); + console.log( + "uiDisplayData at end of change agents color", + updatedUiDisplayData + ); }); } public setColors(agentColors: string[] | number[]): void { + console.log("firing set colors") this.visGeometry.clearColorMapping(); const uiDisplayData = this.selectionInterface.getUIDisplayData(); const updatedColors = this.selectionInterface.setInitialAgentColors( From 498752d08d62b46c54631cc846ccd7ab8792b900 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Tue, 19 Sep 2023 17:06:17 -0700 Subject: [PATCH 25/34] send updated uidata to handler --- src/viewport/index.tsx | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index c857eb23..50a991b0 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -202,7 +202,6 @@ class Viewport extends React.Component< } } const uiDisplayData = this.selectionInterface.getUIDisplayData(); - // console.log("in on trajfileinfo", uiDisplayData); onTrajectoryFileInfoChanged(trajectoryFileInfo); this.visGeometry.clearColorMapping(); @@ -215,8 +214,7 @@ class Viewport extends React.Component< this.visGeometry.createMaterials(updatedColors); } - onUIDisplayDataChanged(uiDisplayData); - // console.log("in on trajfileinfo after on data changes", uiDisplayData); + onUIDisplayDataChanged(this.selectionInterface.getUIDisplayData()); } public componentDidMount(): void { @@ -325,13 +323,6 @@ class Viewport extends React.Component< prevProps.selectionStateInfo.colorChanges ) ) { - // console.log( - // "in update", - // this.selectionInterface.getUIDisplayData() - // ); - console.log( - "firing change agents colors in component did update" - ); this.changeAgentsColor(selectionStateInfo.colorChanges); } } @@ -572,34 +563,22 @@ class Viewport extends React.Component< public changeAgentsColor(colorChanges: ColorChanges[]): void { const { onUIDisplayDataChanged, - agentColors, } = this.props; colorChanges.forEach((colorChange) => { const { agents, color } = colorChange; let uiDisplayData = this.selectionInterface.getUIDisplayData(); - // console.log("uidisplay data in change agents color", uiDisplayData); const agentIds = this.selectionInterface.getAgentIdsByNamesAndTags(agents); this.selectionInterface.updateAgentColors(agentIds, colorChange, uiDisplayData); const colorId = this.getColorId(color); this.visGeometry.applyColorToAgents(agentIds, colorId); - // this.selectionInterface.setInitialAgentColors( - // uiDisplayData, - // agentColors, - // this.visGeometry.setColorForIds.bind(this.visGeometry) - // ); const updatedUiDisplayData = this.selectionInterface.getUIDisplayData(); onUIDisplayDataChanged(updatedUiDisplayData); - console.log( - "uiDisplayData at end of change agents color", - updatedUiDisplayData - ); }); } public setColors(agentColors: string[] | number[]): void { - console.log("firing set colors") this.visGeometry.clearColorMapping(); const uiDisplayData = this.selectionInterface.getUIDisplayData(); const updatedColors = this.selectionInterface.setInitialAgentColors( From 16b162a498c3488cef5f8ef3169d235c6d64db6c Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Tue, 19 Sep 2023 17:07:16 -0700 Subject: [PATCH 26/34] clean up comments --- src/simularium/SelectionInterface.ts | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/simularium/SelectionInterface.ts b/src/simularium/SelectionInterface.ts index 31ff02f2..0375b347 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -232,16 +232,14 @@ class SelectionInterface { } public getUIDisplayData(): UIDisplayData { - let data = Object.keys(this.entries).map((name) => { + return Object.keys(this.entries).map((name) => { const displayStates: DisplayStateEntry[] = []; const encounteredTags: string[] = []; const hasMultipleStates = Object.keys(this.entries[name]).length > 1; - // console.log(name, this.entries[name]) this.entries[name].forEach((entry: DecodedTypeEntry) => { // add unmodified state if there are multiple states, and one of them // has no state tags - // console.log("entry", entry.id, "color", entry.color); if (!entry.tags.length && hasMultipleStates) { displayStates.push({ name: "", @@ -270,17 +268,6 @@ class SelectionInterface { color, }; }); - - // console.log("deep clone of return value", _.cloneDeep(data)); - // console.log("return value of getUiDisplayData", data); - // setTimeout(() => { - // console.log( - // "delayed deep clone of return value", - // _.cloneDeep(data) - // ); - // console.log("delayed return value of getUiDisplayData", data); - // }, 0); - return data; } private updateUiDataColor( @@ -293,7 +280,6 @@ class SelectionInterface { // if no display state update parent color entry.forEach((displayState) => { if (idsToUpdate.includes(displayState.id)) { - console.log("updateUiDataColor"); displayState.color = newColor; } }); From 73ad0f56d63acffc0a2699ac15bcca6375a4dc7a Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 21 Sep 2023 14:35:21 -0700 Subject: [PATCH 27/34] fix example viewer color change --- examples/ColorPicker.tsx | 4 ++-- examples/Viewer.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/ColorPicker.tsx b/examples/ColorPicker.tsx index 1eeb9dbe..a2814b9d 100644 --- a/examples/ColorPicker.tsx +++ b/examples/ColorPicker.tsx @@ -49,10 +49,10 @@ const ColorPicker = ({ tags: subAgent, }, ]; - setColorSelectionInfo({ + setColorSelectionInfo([{ agents: entry, color: selectedColor, - }); + }]); } }; diff --git a/examples/Viewer.tsx b/examples/Viewer.tsx index 27d98a62..45db80fb 100644 --- a/examples/Viewer.tsx +++ b/examples/Viewer.tsx @@ -140,7 +140,7 @@ const initialState: ViewerState = { selectionStateInfo: { highlightedAgents: [], hiddenAgents: [], - colorChanges: { agents: [], color: "" }, + colorChanges: [{ agents: [], color: "" }], }, filePending: null, simulariumFile: null, From 1531bf2baa33828e970705552c44e38e70a10e2c Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Fri, 22 Sep 2023 09:37:58 -0700 Subject: [PATCH 28/34] remove unused function --- src/viewport/index.tsx | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index 50a991b0..f04f43a9 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -578,19 +578,6 @@ class Viewport extends React.Component< }); } - public setColors(agentColors: string[] | number[]): void { - this.visGeometry.clearColorMapping(); - const uiDisplayData = this.selectionInterface.getUIDisplayData(); - const updatedColors = this.selectionInterface.setInitialAgentColors( - uiDisplayData, - agentColors, - this.visGeometry.setColorForIds.bind(this.visGeometry) - ); - if (!isEqual(updatedColors, agentColors)) { - this.visGeometry.createMaterials(updatedColors); - } - } - public stopAnimate(): void { if (this.animationRequestID !== 0) { cancelAnimationFrame(this.animationRequestID); From 33afb92f23b566397061573bc5b5ec074fb57a61 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Fri, 22 Sep 2023 09:38:13 -0700 Subject: [PATCH 29/34] update tests --- src/test/SelectionInterface.test.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/test/SelectionInterface.test.ts b/src/test/SelectionInterface.test.ts index c48126e7..8c02d406 100644 --- a/src/test/SelectionInterface.test.ts +++ b/src/test/SelectionInterface.test.ts @@ -23,10 +23,12 @@ const idMapping = { }; const color = ""; -const initialColorChanges = { - agents: [], - color, -}; +const initialColorChanges = [ + { + agents: [], + color, + }, +]; describe("SelectionInterface module", () => { describe("decode", () => { @@ -427,9 +429,10 @@ describe("SelectionInterface module", () => { }; const si = new SelectionInterface(); si.parse(idMapping); + const uiDisplayData = si.getUIDisplayData(); const oldColors = si.getColorsForName("A"); expect(oldColors).not.toContain(newColor); - si.updateAgentColors(agentIds, colorChanges); + si.updateAgentColors(agentIds, colorChanges, uiDisplayData); const colors = si.getColorsForName("A"); expect(colors).toContain(newColor); }); From 8ddf9d257db28925dd95d08904e3dbc41cba939f Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Fri, 22 Sep 2023 15:33:24 -0700 Subject: [PATCH 30/34] adjust tests to code changes --- src/test/SelectionInterface.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/SelectionInterface.test.ts b/src/test/SelectionInterface.test.ts index 8c02d406..fe352ce9 100644 --- a/src/test/SelectionInterface.test.ts +++ b/src/test/SelectionInterface.test.ts @@ -528,8 +528,8 @@ describe("SelectionInterface module", () => { test("it set the entry color to the 'unmodified' state color if provided", () => { // initially should have no color - expect(uiDisplayDataForA?.color).toEqual(""); - expect(uiDisplayDataForB?.color).toEqual(""); + expect(uiDisplayDataForA?.color).toEqual("#aaaaaa"); + expect(uiDisplayDataForB?.color).toEqual("#bbbbbb"); si.setInitialAgentColors(uiDisplayData, colorList, setColorForIds); expect(uiDisplayDataForA?.color).toEqual("#aaaaaa"); expect(uiDisplayDataForB?.color).toEqual("#bbbbbb"); From 72c38cd6a2dc43984ca6ed557e6f235af48bda1e Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Mon, 25 Sep 2023 16:36:46 -0700 Subject: [PATCH 31/34] unused import and const -> let --- 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 0375b347..7796c7e8 100644 --- a/src/simularium/SelectionInterface.ts +++ b/src/simularium/SelectionInterface.ts @@ -1,7 +1,6 @@ -import { filter, find, set, uniq } from "lodash"; +import { filter, find, uniq } from "lodash"; import { EncodedTypeMapping } from "./types"; import { convertColorNumberToString } from "../visGeometry/color-utils"; -import _ from "lodash"; // An individual entry parsed from an encoded name // The encoded names can be just a name or a name plus a diff --git a/src/viewport/index.tsx b/src/viewport/index.tsx index f04f43a9..d1fd9865 100644 --- a/src/viewport/index.tsx +++ b/src/viewport/index.tsx @@ -566,7 +566,7 @@ class Viewport extends React.Component< } = this.props; colorChanges.forEach((colorChange) => { const { agents, color } = colorChange; - let uiDisplayData = this.selectionInterface.getUIDisplayData(); + const uiDisplayData = this.selectionInterface.getUIDisplayData(); const agentIds = this.selectionInterface.getAgentIdsByNamesAndTags(agents); From a36f698c0c33edd3e96acc1e6ae1ed2a87d08cd6 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 5 Oct 2023 12:17:00 -0700 Subject: [PATCH 32/34] typedeclarations colorchange and selectionentry --- src/simularium/index.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/simularium/index.ts b/src/simularium/index.ts index 3f291ce2..33c9ebfe 100644 --- a/src/simularium/index.ts +++ b/src/simularium/index.ts @@ -6,7 +6,12 @@ export type { EncodedTypeMapping, SimulariumFileFormat, } from "./types"; -export type { SelectionStateInfo, UIDisplayData } from "./SelectionInterface"; +export type { + SelectionStateInfo, + UIDisplayData, + ColorChanges, + SelectionEntry, +} from "./SelectionInterface"; export { ErrorLevel, FrontEndError } from "./FrontEndError"; export { NetMessageEnum } from "./WebsocketClient"; export { RemoteSimulator } from "./RemoteSimulator"; From 71649d01e31c95e99c7515f1ad125a0648f49121 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 5 Oct 2023 14:04:15 -0700 Subject: [PATCH 33/34] export types from index --- src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.ts b/src/index.ts index ec3664f9..7d473e33 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,8 @@ export type { SelectionStateInfo, UIDisplayData, VisDataFrame, + ColorChanges, + SelectionEntry, } from "./simularium"; export type { ISimulariumFile } from "./simularium/ISimulariumFile"; From ee7b583eab5cd36019e25637f27d5e361b3930d5 Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Thu, 5 Oct 2023 15:04:01 -0700 Subject: [PATCH 34/34] remove unnecessary type export --- src/simularium/index.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/simularium/index.ts b/src/simularium/index.ts index 33c9ebfe..3f291ce2 100644 --- a/src/simularium/index.ts +++ b/src/simularium/index.ts @@ -6,12 +6,7 @@ export type { EncodedTypeMapping, SimulariumFileFormat, } from "./types"; -export type { - SelectionStateInfo, - UIDisplayData, - ColorChanges, - SelectionEntry, -} from "./SelectionInterface"; +export type { SelectionStateInfo, UIDisplayData } from "./SelectionInterface"; export { ErrorLevel, FrontEndError } from "./FrontEndError"; export { NetMessageEnum } from "./WebsocketClient"; export { RemoteSimulator } from "./RemoteSimulator";