Skip to content

Commit

Permalink
add magic numbers highlighting (first pass), #87
Browse files Browse the repository at this point in the history
  • Loading branch information
zepumph committed Jul 24, 2023
1 parent eff1828 commit 5b3694b
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 28 deletions.
11 changes: 7 additions & 4 deletions js/chart-intro/view/ChartIntroScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,14 @@ class ChartIntroScreenView extends BANScreenView<ChartIntroModel> {
this.periodicTableAndIsotopeSymbol.centerY, dashedLineOptions );
this.addChild( rightDashedLine );

// Whether to show a special highlight for magic-numbered nuclides in the charts
const showMagicNumbersProperty = new BooleanProperty( false );

// TODO: use align group to match width's of accordion box and periodic table https://github.com/phetsims/build-a-nucleus/issues/93
const nuclideChartAccordionBox = new NuclideChartAccordionBox( this.model.particleAtom.protonCountProperty,
this.model.particleAtom.neutronCountProperty, this.periodicTableAndIsotopeSymbol.width,
this.model.selectedNuclideChartProperty, this.model.decayEquationModel, this.decayAtom.bind( this ) );
this.model.selectedNuclideChartProperty, this.model.decayEquationModel, this.decayAtom.bind( this ), showMagicNumbersProperty );

nuclideChartAccordionBox.top = this.periodicTableAndIsotopeSymbol.bottom + CHART_VERTICAL_MARGINS;
nuclideChartAccordionBox.left = this.periodicTableAndIsotopeSymbol.left;
this.addChild( nuclideChartAccordionBox );
Expand All @@ -193,9 +197,8 @@ class ChartIntroScreenView extends BANScreenView<ChartIntroModel> {
} );
this.addChild( partialChartRadioButton );

const showMagicNumbersCheckbox = new Checkbox( new BooleanProperty( false ),
new Text( BuildANucleusStrings.magicNumbersStringProperty, { font: BANConstants.LEGEND_FONT, maxWidth: 145 } ),
{
const showMagicNumbersCheckbox = new Checkbox( showMagicNumbersProperty,
new Text( BuildANucleusStrings.magicNumbersStringProperty, { font: BANConstants.LEGEND_FONT, maxWidth: 145 } ), {
boxWidth: 15
} );
showMagicNumbersCheckbox.left = partialChartRadioButton.right + CHART_VERTICAL_MARGINS;
Expand Down
9 changes: 7 additions & 2 deletions js/chart-intro/view/NuclideChartAccordionBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,19 @@ class NuclideChartAccordionBox extends AccordionBox {

public constructor( protonCountProperty: TReadOnlyProperty<number>, neutronCountProperty: TReadOnlyProperty<number>,
minWidth: number, selectedNuclideChartProperty: TReadOnlyProperty<SelectedChartType>,
decayEquationModel: DecayEquationModel, decayAtom: ( decayType: DecayType | null ) => void ) {
decayEquationModel: DecayEquationModel, decayAtom: ( decayType: DecayType | null ) => void,
showMagicNumbersProperty: TReadOnlyProperty<boolean> ) {

const partialChartTransform = NuclideChartAccordionBox.getChartTransform( 18 );
const focusedChartTransform = NuclideChartAccordionBox.getChartTransform( 10 );
const zoomInChartTransform = NuclideChartAccordionBox.getChartTransform( 30 );

const nuclideChartAndNumberLines = new NuclideChartAndNumberLines( protonCountProperty, neutronCountProperty,
partialChartTransform );
partialChartTransform, {
nuclideChartNodeOptions: {
showMagicNumbersProperty: showMagicNumbersProperty
}
} );

const focusedNuclideChartNode = new FocusedNuclideChartNode( protonCountProperty, neutronCountProperty,
focusedChartTransform );
Expand Down
26 changes: 16 additions & 10 deletions js/chart-intro/view/NuclideChartAndNumberLines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,33 @@ import BuildANucleusStrings from '../../BuildANucleusStrings.js';
import NucleonNumberLine from './NucleonNumberLine.js';
import TReadOnlyProperty from '../../../../axon/js/TReadOnlyProperty.js';
import Orientation from '../../../../phet-core/js/Orientation.js';
import NuclideChartNode from './NuclideChartNode.js';
import NuclideChartNode, { NuclideChartNodeOptions } from './NuclideChartNode.js';
import ChartTransform from '../../../../bamboo/js/ChartTransform.js';
import optionize, { EmptySelfOptions } from '../../../../phet-core/js/optionize.js';
import optionize, { combineOptions } from '../../../../phet-core/js/optionize.js';
import StrictOmit from '../../../../phet-core/js/types/StrictOmit.js';

type NuclideChartNodeOptions = StrictOmit<NodeOptions, 'excludeInvisibleChildrenFromBounds' | 'children'>;
type SelfOptions = {
nuclideChartNodeOptions?: Partial<NuclideChartNodeOptions>;
};
type NuclideChartAndNumberLinesOptions = SelfOptions & StrictOmit<NodeOptions, 'excludeInvisibleChildrenFromBounds' | 'children'>;

class NuclideChartAndNumberLines extends Node {

public constructor( protonCountProperty: TReadOnlyProperty<number>, neutronCountProperty: TReadOnlyProperty<number>,
chartTransform: ChartTransform, providedOptions?: NuclideChartNodeOptions ) {
chartTransform: ChartTransform, providedOptions?: NuclideChartAndNumberLinesOptions ) {

const options = optionize<NuclideChartNodeOptions, EmptySelfOptions, NodeOptions>()( {
excludeInvisibleChildrenFromBounds: true
const options = optionize<NuclideChartAndNumberLinesOptions, SelfOptions, NodeOptions>()( {
excludeInvisibleChildrenFromBounds: true,
nuclideChartNodeOptions: {}
}, providedOptions );

// create and add the nuclideChartNode
const nuclideChartNode = new NuclideChartNode( protonCountProperty, neutronCountProperty, chartTransform, {
cellTextFontSize: 11,
arrowSymbol: false
} );
const nuclideChartNode = new NuclideChartNode( protonCountProperty, neutronCountProperty, chartTransform,
combineOptions<NuclideChartNodeOptions>( {
cellTextFontSize: 11,
arrowSymbol: false
}, options.nuclideChartNodeOptions )
);

const protonNumberLine = new NucleonNumberLine( chartTransform, protonCountProperty, Orientation.VERTICAL, {
labelHighlightColorProperty: BANColors.protonColorProperty,
Expand Down
2 changes: 1 addition & 1 deletion js/chart-intro/view/NuclideChartCell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class NuclideChartCell extends Rectangle {
public readonly decayBackgroundColor: TPaint;
public readonly cellModel: NuclideChartCellModel;

public constructor( cellLength: number, cellModel: NuclideChartCellModel, providedOptions: NuclideChartCellOptions ) {
public constructor( cellLength: number, cellModel: NuclideChartCellModel, providedOptions?: NuclideChartCellOptions ) {

const options = optionize<NuclideChartCellOptions, SelfOptions, RectangleOptions>()( {
stroke: BANColors.nuclideChartBorderColorProperty,
Expand Down
41 changes: 31 additions & 10 deletions js/chart-intro/view/NuclideChartNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@ import BANConstants from '../../common/BANConstants.js';
import { Shape } from '../../../../kite/js/imports.js';
import ChartIntroModel from '../model/ChartIntroModel.js';
import NuclideChartCellModel from '../model/NuclideChartCellModel.js';
import BooleanProperty from '../../../../axon/js/BooleanProperty.js';
import BANColors from '../../common/BANColors.js';

type SelfOptions = {
cellTextFontSize: number;
arrowSymbol: boolean;
showMagicNumbersProperty?: TReadOnlyProperty<boolean>;
};

type NuclideChartNodeOptions = SelfOptions & NodeOptions;
export type NuclideChartNodeOptions = SelfOptions & NodeOptions;

// Applies to both proton and neutron counts see showMagicNumbersProperty for details.
const MAGIC_COUNTS = [ 2, 8 ];

// 2D array that defines the table structure.
// The rows are the proton number, for example the first row is protonCount = 0. The numbers in the rows are the neutron number.
Expand All @@ -53,15 +59,16 @@ class NuclideChartNode extends Node {
chartTransform: ChartTransform, providedOptions: NuclideChartNodeOptions ) {

const options = optionize<NuclideChartNodeOptions, SelfOptions, NodeOptions>()( {
excludeInvisibleChildrenFromBounds: true
excludeInvisibleChildrenFromBounds: true,
showMagicNumbersProperty: new BooleanProperty( false )
}, providedOptions );
super( options );

const cellLength = chartTransform.modelToViewDeltaX( 1 );
const cellLayerNode = new Node();

// keep track of the cells of the chart
this.cells = NuclideChartNode.createNuclideChart( cellLayerNode, chartTransform, cellLength );
this.cells = NuclideChartNode.createNuclideChart( cellLayerNode, chartTransform, cellLength, options.showMagicNumbersProperty );

this.addChild( cellLayerNode );

Expand Down Expand Up @@ -153,22 +160,36 @@ class NuclideChartNode extends Node {
Color.BLACK : Color.WHITE;
}

public static createNuclideChart( cellLayerNode: Node, chartTransform: ChartTransform, cellLength: number ): NuclideChartCell[][] {
/**
* Public for icon creation.
*/
public static createNuclideChart( cellLayerNode: Node, chartTransform: ChartTransform, cellLength: number,
showMagicNumbersProperty: TReadOnlyProperty<boolean> = new BooleanProperty( false ) ): NuclideChartCell[][] {
const cells: NuclideChartCell[][] = [];

// create and add the chart cells to the chart. row is proton number and column is neutron number.
chartTransform.forEachSpacing( Orientation.VERTICAL, 1, 0, 'strict', ( row, viewPosition ) => {
const populatedCellsInRow = POPULATED_CELLS[ row ];
chartTransform.forEachSpacing( Orientation.VERTICAL, 1, 0, 'strict', ( protonCount, viewPosition ) => {
const populatedCellsInRow = POPULATED_CELLS[ protonCount ];
const rowCells: NuclideChartCell[] = [];
populatedCellsInRow.forEach( ( column, columnIndex ) => {
populatedCellsInRow.forEach( ( neutronCount, columnIndex ) => {

// create and add the NuclideChartCell
const cell = new NuclideChartCell( cellLength, ChartIntroModel.cellModelArray[ row ][ columnIndex ], {
lineWidth: chartTransform.modelToViewDeltaX( BANConstants.NUCLIDE_CHART_CELL_LINE_WIDTH )
const defaultLineWidth = chartTransform.modelToViewDeltaX( BANConstants.NUCLIDE_CHART_CELL_LINE_WIDTH );
const cell = new NuclideChartCell( cellLength, ChartIntroModel.cellModelArray[ protonCount ][ columnIndex ], {
lineWidth: defaultLineWidth
} );
cell.translation = new Vector2( chartTransform.modelToViewX( column ), viewPosition );
cell.translation = new Vector2( chartTransform.modelToViewX( neutronCount ), viewPosition );
cellLayerNode.addChild( cell );
rowCells.push( cell );

const cellIsMagic = MAGIC_COUNTS.includes( protonCount ) || MAGIC_COUNTS.includes( neutronCount );
if ( cellIsMagic ) {
showMagicNumbersProperty.link( showMagic => {
showMagic && cell.moveToFront();
cell.lineWidth = showMagic ? defaultLineWidth + 2 : defaultLineWidth;
cell.stroke = showMagic ? BANColors.nuclideChartBorderMagicNumberColorProperty : BANColors.nuclideChartBorderColorProperty;
} );
}
} );
cells.push( rowCells );
} );
Expand Down
6 changes: 5 additions & 1 deletion js/chart-intro/view/ZoomInChartNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ class ZoomInChartNode extends NuclideChartNode {

public constructor( protonCountProperty: TReadOnlyProperty<number>, neutronCountProperty: TReadOnlyProperty<number>,
chartTransform: ChartTransform ) {
super( protonCountProperty, neutronCountProperty, chartTransform, { cellTextFontSize: 18, arrowSymbol: true } );

super( protonCountProperty, neutronCountProperty, chartTransform, {
cellTextFontSize: 18,
arrowSymbol: true
} );

const squareLength = chartTransform.modelToViewDeltaX( 5 + ( 2 * BANConstants.NUCLIDE_CHART_CELL_LINE_WIDTH ) );

Expand Down
4 changes: 4 additions & 0 deletions js/common/BANColors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ const BANColors = {
default: new Color( 143, 143, 143 )
} ),

nuclideChartBorderMagicNumberColorProperty: new ProfileColorProperty( buildANucleus, 'nuclideChartBorderMagicNumberColor', {
default: new Color( 100, 100, 100 )
} ),

chartRadioButtonsBackgroundColorProperty: new ProfileColorProperty( buildANucleus, 'chartRadioButtonsBackgroundColor', {
default: new Color( 241, 250, 254 )
} ),
Expand Down

0 comments on commit 5b3694b

Please sign in to comment.