phetsims / projectile-data-lab

"Projectile Data Lab" is an educational simulation in HTML5, by PhET Interactive Simulations.
GNU General Public License v3.0
0 stars 0 forks source link

When selecting an earlier projectile, the speedometer and angle gauge needle should indicate the selected projectile #246

Closed samreid closed 4 months ago

samreid commented 5 months ago

As recommended by @terracoda in https://github.com/phetsims/projectile-data-lab/issues/107#issuecomment-1986172915, When selecting an earlier projectile, the speedometer and angle gauge needle should indicate the selected projectile. When a new projectile is launched, it can show that data.

matthew-blackman commented 5 months ago

@samreid and I worked on this and ran into the following design issue:

I don't see a way to get the heat map tools to also serve as a history tool. The speed and angle tools were designed to display data as they are collecting it, similar to a 'radar gun' as it is registering speed data. It was not designed to be a way to navigate prior data, but rather a live stream of data with a qualitative snapshot of the spread (the heat map itself).

In light of this design limitation, I think this issue can be closed. If we decide to redesign the speed/angle tools, then this may be possible in the future.

If we decide to pick this up at a later date, here is the patch from the work that @samreid and I started on this before running into design limitations:

``` diff Subject: [PATCH] Add sampleNumber to CODAP available data - https://github.com/phetsims/projectile-data-lab/issues/243 --- Index: js/common-vsm/view/AngleToolNode.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/view/AngleToolNode.ts b/js/common-vsm/view/AngleToolNode.ts --- a/js/common-vsm/view/AngleToolNode.ts (revision 5d5e2fc70076af92ace1f580069befbf6f987f74) +++ b/js/common-vsm/view/AngleToolNode.ts (date 1710268940684) @@ -55,7 +55,7 @@ // elementsForRaised is used to keep track of the elements that are visible when the tool is raised. private readonly elementsForRaised: Node[] = []; - public constructor( latestValueProperty: TReadOnlyProperty, + public constructor( displayedValueProperty: TReadOnlyProperty, isRaisedProperty: TReadOnlyProperty, providedOptions: AngleToolNodeOptions ) { @@ -123,7 +123,7 @@ readoutPatternStringProperty: ProjectileDataLabStrings.valueDegreesPatternStringProperty, isIcon: false }, providedOptions ); - super( latestValueProperty, options ); + super( displayedValueProperty, options ); // rotatedElements is used to keep track of the elements that need to be rotated to their correct positions. const rotatedElements = [ ...this.heatNodes, ...this.tickMarks ]; Index: js/common-vsm/view/HeatMapToolNode.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/view/HeatMapToolNode.ts b/js/common-vsm/view/HeatMapToolNode.ts --- a/js/common-vsm/view/HeatMapToolNode.ts (revision 5d5e2fc70076af92ace1f580069befbf6f987f74) +++ b/js/common-vsm/view/HeatMapToolNode.ts (date 1710268868112) @@ -153,8 +153,8 @@ // maxAngle is the maximum angle used to set the angular positioning of the heat nodes, in degrees. private readonly maxAngle: number; - // The latest value Property is used to update the heat map tool's needle rotation. - public constructor( latestValueProperty: TReadOnlyProperty, providedOptions: HeatMapToolNodeOptions ) { + // The latest value Property is used to add data to the heat map, update the heat map tool's needle rotation and set the displayed value. + public constructor( displayedValueProperty: TReadOnlyProperty, providedOptions: HeatMapToolNodeOptions ) { const options = optionize()( { isWithMinorTickMarks: false, @@ -211,8 +211,8 @@ this.needleNode = this.createNeedleNode( options.needleShape ); - const formattedValueProperty = new DerivedProperty( [ latestValueProperty ], latestValue => { - return Utils.toFixed( latestValue, 1 ); + const formattedValueProperty = new DerivedProperty( [ displayedValueProperty ], displayedValue => { + return Utils.toFixed( displayedValue, 1 ); } ); const valueUnitsPatternStringProperty = new PatternStringProperty( options.readoutPatternStringProperty, { @@ -263,9 +263,9 @@ this.minAngle = options.minAngle; this.maxAngle = options.maxAngle; - // Update the needle rotation when the latest value changes - latestValueProperty.link( latestValue => { - this.setNeedleRotation( latestValue ); + // Update the needle rotation when the displayed value changes + displayedValueProperty.link( displayedValue => { + this.setNeedleRotation( displayedValue ); } ); } Index: js/common-vsm/view/VSMScreenView.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/view/VSMScreenView.ts b/js/common-vsm/view/VSMScreenView.ts --- a/js/common-vsm/view/VSMScreenView.ts (revision 5d5e2fc70076af92ace1f580069befbf6f987f74) +++ b/js/common-vsm/view/VSMScreenView.ts (date 1710269046960) @@ -166,14 +166,14 @@ // Create the heat map tools const speedToolNode = new SpeedToolNode( - model.latestLaunchSpeedProperty, + model.displayedLaunchSpeedProperty, isLauncherRaisedProperty, { visibleProperty: model.isLaunchSpeedVisibleProperty, x: originPosition.x, y: originPosition.y } ); const angleToolNode = new AngleToolNode( - model.latestLaunchAngleProperty, + model.displayedLaunchAngleProperty, isLauncherRaisedProperty, { visibleProperty: model.isLaunchAngleVisibleProperty, x: originPosition.x, y: originPosition.y Index: js/common-vsm/view/SpeedToolNode.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/view/SpeedToolNode.ts b/js/common-vsm/view/SpeedToolNode.ts --- a/js/common-vsm/view/SpeedToolNode.ts (revision 5d5e2fc70076af92ace1f580069befbf6f987f74) +++ b/js/common-vsm/view/SpeedToolNode.ts (date 1710268953188) @@ -63,7 +63,7 @@ // The display offset is the position of the tool display panel relative to its origin. private displayOffset: Vector2; - public constructor( latestValueProperty: TReadOnlyProperty, isLauncherRaised: TReadOnlyProperty, providedOptions: SpeedToolNodeOptions ) { + public constructor( displayedValueProperty: TReadOnlyProperty, isLauncherRaised: TReadOnlyProperty, providedOptions: SpeedToolNodeOptions ) { // The body shape is an arc that represents the background of the heat map display. const bodyShape = new Shape().arc( 0, 0, BODY_RADIUS, @@ -112,7 +112,7 @@ isClockwise: true, isIcon: false }, providedOptions ); - super( latestValueProperty, options ); + super( displayedValueProperty, options ); this.displayOffset = options.displayOffset; Index: js/common-vsm/model/VSMModel.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/model/VSMModel.ts b/js/common-vsm/model/VSMModel.ts --- a/js/common-vsm/model/VSMModel.ts (revision 5d5e2fc70076af92ace1f580069befbf6f987f74) +++ b/js/common-vsm/model/VSMModel.ts (date 1710268402387) @@ -59,6 +59,9 @@ //////////////////////////////////////////////////////////////////////////////////////// // These DynamicProperties select based on the selected VSMField + public readonly displayedLaunchAngleProperty: TReadOnlyProperty; + public readonly displayedLaunchSpeedProperty: TReadOnlyProperty; + public readonly latestLaunchAngleProperty: TReadOnlyProperty; public readonly latestLaunchSpeedProperty: TReadOnlyProperty; @@ -111,6 +114,16 @@ validValues: allLaunchers } ); + this.displayedLaunchAngleProperty = new DynamicProperty( this.fieldProperty, { + bidirectional: true, + derive: field => field.displayedLaunchAngleProperty + } ); + + this.displayedLaunchSpeedProperty = new DynamicProperty( this.fieldProperty, { + bidirectional: true, + derive: field => field.displayedLaunchSpeedProperty + } ); + this.latestLaunchAngleProperty = new DynamicProperty( this.fieldProperty, { bidirectional: true, derive: field => field.latestLaunchAngleProperty Index: js/common-vsm/model/VSMField.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/model/VSMField.ts b/js/common-vsm/model/VSMField.ts --- a/js/common-vsm/model/VSMField.ts (revision 5d5e2fc70076af92ace1f580069befbf6f987f74) +++ b/js/common-vsm/model/VSMField.ts (date 1710269180848) @@ -39,6 +39,12 @@ export default class VSMField extends Field { + // The launch angle being displayed on the angle heat map tool. + public readonly displayedLaunchAngleProperty: Property; + + // The launch speed being displayed on the speed heat map tool. + public readonly displayedLaunchSpeedProperty: Property; + // The most recent launch angle on this field, in degrees public readonly latestLaunchAngleProperty: Property; @@ -80,21 +86,26 @@ super( launchers, launcherProperty, PDLUtils.colorForFieldIndex( VSMFieldIdentifierValues.indexOf( identifier ) ), options ); this.continuousLaunchTimer = new PDLEventTimer( PDLConstants.MINIMUM_TIME_BETWEEN_LAUNCHES, options.tandem.createTandem( 'continuousLaunchTimer' ) ); - this.latestLaunchAngleProperty = new NumberProperty( this.meanAngleProperty.value, { - tandem: providedOptions.tandem.createTandem( 'latestLaunchAngleProperty' ), + this.displayedLaunchAngleProperty = new NumberProperty( this.meanAngleProperty.value, { + tandem: providedOptions.tandem.createTandem( 'displayedLaunchAngleProperty' ), phetioReadOnly: true, - phetioDocumentation: 'This Property is the current angle of the launcher, in degrees. When a projectile is launched, this property is set to the launch angle.' - + ' When the launcher configuration or angle stabilizer changes, this Property is set to the configured launch angle.', + phetioDocumentation: 'This Property is the value displayed on the angle tool, in degrees.' + + 'When a projectile is launched or selected, this is set to the launch angle of that projectile.', phetioFeatured: true } ); - this.latestLaunchSpeedProperty = new NumberProperty( 0, { - tandem: providedOptions.tandem.createTandem( 'latestLaunchSpeedProperty' ), + this.displayedLaunchSpeedProperty = new NumberProperty( 0, { + tandem: providedOptions.tandem.createTandem( 'displayedLaunchSpeedProperty' ), phetioReadOnly: true, - phetioDocumentation: 'This Property is the latest launch speed, in meters per second. When a projectile is launched, this is set to the launch speed.', + phetioDocumentation: 'This Property is the value displayed on the speed tool, in meters per second.' + + 'When a projectile is launched or selected, this is set to the launch speed of that projectile.', phetioFeatured: true } ); + this.latestLaunchAngleProperty = new NumberProperty( this.meanAngleProperty.value ); + + this.latestLaunchSpeedProperty = new NumberProperty( 0 ); + this.selectedProjectileNumberProperty = new NumberProperty( 0, { phetioFeatured: true, tandem: providedOptions.tandem.createTandem( 'selectedProjectileNumberProperty' ), @@ -156,6 +167,16 @@ this.standardDeviationAngleProperty.lazyLink( () => { this.latestLaunchAngleProperty.value = this.meanAngleProperty.value; } ); + + // When the latest launch angle changes, update the displayed launch angle + this.latestLaunchAngleProperty.link( value => { + this.displayedLaunchAngleProperty.value = value; + } ); + + // When the latest launch speed changes, update the displayed launch speed + this.latestLaunchSpeedProperty.link( value => { + this.displayedLaunchSpeedProperty.value = value; + } ); } private updateProjectileCounts(): void { @@ -175,6 +196,9 @@ this.latestLaunchSpeedProperty.value = projectile.launchSpeed; this.projectileLaunchedEmitter.emit( projectile ); + + this.latestLaunchAngleProperty.value = projectile.launchAngle; + this.latestLaunchSpeedProperty.value = projectile.launchSpeed; } public createLandedProjectile(): void { ```
terracoda commented 4 months ago

I am not fully understanding why this issues was closed.

samreid commented 4 months ago

@terracoda and @matthew-blackman I discussed this further:

matthew-blackman commented 4 months ago

Reopening for design meeting discussion

terracoda commented 4 months ago

Was this re-opened because of interview feedback?

matthew-blackman commented 4 months ago

@terracoda I reopened this to discuss the QA question as to whether some users could possibly be confused by this (although QA was not confused by this).

After meeting with the design team, it was determined that there are significant challenges to changing the design of the heat map tools due to the following constraints:

One proposed idea is to "null out" the heat map readout/needle when selecting a previous projectile. This could improve confusion in some cases, but also introduces a new source of confusion:

If the projectiles land out of order, and then the user selects previous ones, and then goes back to selecting the most recent one, the number/needle would now reappear, despite being out of sync with this projectile. This would send the message that they are in sync with the most recently landed projectile (since the value/needle just become non-null), whereas this will not be the case. I find this design to be more complicated and error-prone than the current design.

The original design of the sim (and its current behavior) calls for the heat map tools to update when a new projectile is launched. Changing this rule be conditional when a previous projectile is selected is more complicated, and in my opinion will leave even greater room for user confusion. It was also noted by @KatieWoe that she was not actually confused by this behavior and figured it out within a few seconds. As of now, no user interviews or workshop attendees have expressed confusion in the behavior of these tools.

In the interest of simplicity/consistency, @ariel-phet @samreid @Nancy-Salpepi and myself are recommending that we leave the heat map tools as is. If the user selects a previous projectile and the tools are not updating, it should be clear that those readings are not tied to the selected projectile.

terracoda commented 4 months ago

It might look disruptive to have the launcher switch wile navigating data points, but would it make sense to make the launcher match the launched data point when navigating the the data points?

I do not fully understand the purpose of navigating the data points. What is a learner supposed to be looking for when navigating the launched data points.

matthew-blackman commented 4 months ago

@terracoda this would introduce several other issues. I'm happy to discuss synchronously since they are not directly related to this issue.

matthew-blackman commented 4 months ago

The following patch was used for demo/discussion during the 4/11 design meeting. It is an initial draft for the behavior in which the heat map tools are always synced with the selected projectile:

```diff Subject: [PATCH] Patch --- Index: js/common-vsm/view/VSMScreenView.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/view/VSMScreenView.ts b/js/common-vsm/view/VSMScreenView.ts --- a/js/common-vsm/view/VSMScreenView.ts (revision f6284ae547b92e59d1dbdb051152b65b49f62cad) +++ b/js/common-vsm/view/VSMScreenView.ts (date 1712864073507) @@ -166,17 +166,24 @@ const isLauncherRaisedProperty = new DerivedProperty( [ model.launcherHeightProperty ], height => height > 0 ); + const isMostRecentProjectileSelectedProperty = new DerivedProperty( [ model.selectedProjectileNumberProperty, model.numberOfLandedProjectilesProperty ], + ( selectedProjectileNumber, numberOfLandedProjectiles ) => { + return selectedProjectileNumber === numberOfLandedProjectiles; + } ); + // Create the heat map tools const speedToolNode = new SpeedToolNode( model.latestLaunchSpeedProperty, - isLauncherRaisedProperty, { + isLauncherRaisedProperty, + isMostRecentProjectileSelectedProperty, { visibleProperty: model.isLaunchSpeedVisibleProperty, x: originPosition.x, y: originPosition.y } ); const angleToolNode = new AngleToolNode( model.latestLaunchAngleProperty, - isLauncherRaisedProperty, { + isLauncherRaisedProperty, + isMostRecentProjectileSelectedProperty, { visibleProperty: model.isLaunchAngleVisibleProperty, x: originPosition.x, y: originPosition.y } ); Index: js/common-vsm/view/AngleToolNode.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/view/AngleToolNode.ts b/js/common-vsm/view/AngleToolNode.ts --- a/js/common-vsm/view/AngleToolNode.ts (revision f6284ae547b92e59d1dbdb051152b65b49f62cad) +++ b/js/common-vsm/view/AngleToolNode.ts (date 1712864073505) @@ -57,6 +57,7 @@ public constructor( latestValueProperty: TReadOnlyProperty, isRaisedProperty: TReadOnlyProperty, + isMostRecentProjectileSelectedProperty: TReadOnlyProperty, providedOptions: AngleToolNodeOptions ) { // bodyShapeForIsRaised creates the shape of the body of the display panel, which depends on whether the tool is raised. @@ -123,7 +124,7 @@ readoutPatternStringProperty: ProjectileDataLabStrings.valueDegreesPatternStringProperty, isIcon: false }, providedOptions ); - super( latestValueProperty, options ); + super( latestValueProperty, isMostRecentProjectileSelectedProperty, options ); // rotatedElements is used to keep track of the elements that need to be rotated to their correct positions. const rotatedElements = [ ...this.heatNodes, ...this.tickMarks ]; Index: js/common-vsm/view/SpeedToolNode.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/view/SpeedToolNode.ts b/js/common-vsm/view/SpeedToolNode.ts --- a/js/common-vsm/view/SpeedToolNode.ts (revision f6284ae547b92e59d1dbdb051152b65b49f62cad) +++ b/js/common-vsm/view/SpeedToolNode.ts (date 1712864073506) @@ -63,7 +63,11 @@ // The display offset is the position of the tool display panel relative to its origin. private displayOffset: Vector2; - public constructor( latestValueProperty: TReadOnlyProperty, isLauncherRaised: TReadOnlyProperty, providedOptions: SpeedToolNodeOptions ) { + public constructor( + latestValueProperty: TReadOnlyProperty, + isLauncherRaised: TReadOnlyProperty, + isMostRecentProjectileSelectedProperty: TReadOnlyProperty, + providedOptions: SpeedToolNodeOptions ) { // The body shape is an arc that represents the background of the heat map display. const bodyShape = new Shape().arc( 0, 0, BODY_RADIUS, @@ -112,7 +116,7 @@ isClockwise: true, isIcon: false }, providedOptions ); - super( latestValueProperty, options ); + super( latestValueProperty, isMostRecentProjectileSelectedProperty, options ); this.displayOffset = options.displayOffset; @@ -123,7 +127,7 @@ // If this is not an icon, create the graphics for the wire connected to the launcher const launcherCircle = new Circle( 4, { fill: 'black' } ); - const connectingWireShape = this.connectingWireShapeForIsRaised( ); + const connectingWireShape = this.connectingWireShapeForIsRaised(); this.connectingWire = new Node(); this.connectingWire.addChild( new Path( connectingWireShape, { @@ -149,7 +153,7 @@ this.displayOffset = new Vector2( speedToolX, speedToolY ); - const connectingWireShape = this.connectingWireShapeForIsRaised( ); + const connectingWireShape = this.connectingWireShapeForIsRaised(); if ( this.connectingWire ) { this.connectingWire.children = [ new Path( connectingWireShape, { Index: js/common-vsm/view/StaticToolPanel.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/view/StaticToolPanel.ts b/js/common-vsm/view/StaticToolPanel.ts --- a/js/common-vsm/view/StaticToolPanel.ts (revision f6284ae547b92e59d1dbdb051152b65b49f62cad) +++ b/js/common-vsm/view/StaticToolPanel.ts (date 1712864073506) @@ -84,7 +84,8 @@ const angleToolNode = new AngleToolNode( new NumberProperty( 45 ), - new Property( false ), { + new Property( false ), + new Property( true ), { isIcon: true } ).rasterized( { resolution: 1.25 @@ -102,7 +103,8 @@ const speedToolNode = new SpeedToolNode( new NumberProperty( 15 ), - new Property( false ), { + new Property( false ), + new Property( true ), { isIcon: true } ) .rasterized( { Index: js/common-vsm/view/HeatMapToolNode.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/view/HeatMapToolNode.ts b/js/common-vsm/view/HeatMapToolNode.ts --- a/js/common-vsm/view/HeatMapToolNode.ts (revision f6284ae547b92e59d1dbdb051152b65b49f62cad) +++ b/js/common-vsm/view/HeatMapToolNode.ts (date 1712868022881) @@ -154,7 +154,11 @@ private readonly maxAngle: number; // The latest value Property is used to update the heat map tool's needle rotation. - public constructor( latestValueProperty: TReadOnlyProperty, providedOptions: HeatMapToolNodeOptions ) { + // The isMostRecentProjectileSelected Property is used to determine if the needle should be visible. + public constructor( + latestValueProperty: TReadOnlyProperty, + isMostRecentProjectileSelectedProperty: TReadOnlyProperty, + providedOptions: HeatMapToolNodeOptions ) { const options = optionize()( { isWithMinorTickMarks: false, @@ -209,7 +213,14 @@ this.bodyBackNode = new Path( options.bodyShape, { fill: PDLColors.heatMapDisplayFillProperty } ); this.bodyFrontNode = new Path( options.bodyShape, { stroke: PDLColors.heatMapDisplayStrokeProperty, lineWidth: 1 } ); - this.needleNode = this.createNeedleNode( options.needleShape ); + this.needleNode = new Path( options.needleShape, { + visibleProperty: isMostRecentProjectileSelectedProperty, + fill: PDLColors.heatMapNeedleFillProperty, + stroke: PDLColors.heatMapNeedleStrokeProperty, + lineWidth: 1, + x: 0, + y: 0 + } ); const formattedValueProperty = new DerivedProperty( [ latestValueProperty ], latestValue => { return Utils.toFixed( latestValue, 1 ); @@ -367,18 +378,6 @@ return minorTickMarks; } - // createNeedleNode creates the needle node for the heat map tool - private createNeedleNode( needleShape: Shape ): Node { - const needleNode = new Path( needleShape, { - fill: PDLColors.heatMapNeedleFillProperty, - stroke: PDLColors.heatMapNeedleStrokeProperty, - lineWidth: 1, - x: 0, - y: 0 - } ); - return needleNode; - } - // updateHeatMapWithData updates the opacity of each heat node based on the number of values in the bin. // The minimum opacity is 0.2, and the bin with the largest number of values has an opacity of 1. // The opacity of each heat node is scaled based on the number of values in the bin relative to the bin with the Index: js/common-vsm/model/VSMField.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/common-vsm/model/VSMField.ts b/js/common-vsm/model/VSMField.ts --- a/js/common-vsm/model/VSMField.ts (revision f6284ae547b92e59d1dbdb051152b65b49f62cad) +++ b/js/common-vsm/model/VSMField.ts (date 1712864073505) @@ -158,6 +158,17 @@ this.standardDeviationAngleProperty.lazyLink( () => { this.latestLaunchAngleProperty.value = this.meanAngleProperty.value; } ); + + // If a projectile is selected, show its launch angle and speed on the heat map tools + this.selectedProjectileProperty.lazyLink( selectedProjectile => { + + // Only update the displayed launch angle and speed if there are no airborne projectiles + // This prevents the angle and speed from jumping around when projectiles launch/land in different order + if ( this.airborneProjectiles.length === 0 && selectedProjectile ) { + this.latestLaunchAngleProperty.value = selectedProjectile.launchAngle; + this.latestLaunchSpeedProperty.value = selectedProjectile.launchSpeed; + } + } ); } private updateProjectileCounts(): void {
matthew-blackman commented 4 months ago

I hear the points raised above. Discussing this with @ariel-phet, we summarized the design considerations for this issue as follows:

https://github.com/phetsims/projectile-data-lab/assets/108756567/f84e8214-ff08-48a2-9595-a691a425b6c7

For these reasons, we are recommending to keep the heat map tools the way they are. We feel that they are doing a good job at addressing the learning goals of the sim, are consistent with lab tools, and have a very straightforward and learnable UX.

Closing this issue, but anyone is welcome to reopen it if there are further ideas to discuss or explore.

terracoda commented 4 months ago

Thanks for the example. It seems clear the red heat-map lines are not supposed to be directly connected to the purple path lines.

My main concern is/was how will the additional launch angle variability be audibly presented down the road through TTS (voicing or interactive description). Some variability is already represented through sound. I feel it is important to think about this now as it helps determine what information is truly essential to the learning goals.

I completely understand that not every piece of information is essential for the main learning goals, but everyone needs equitable access to readily available information.

Its about finding the right place from which we can interactively make the additional launch angle variability values accessible down the road.