diff --git a/src/actions/tree.ts b/src/actions/tree.ts index dd418a4a5..6beabecb0 100644 --- a/src/actions/tree.ts +++ b/src/actions/tree.ts @@ -12,7 +12,7 @@ import { getTraitFromNode } from "../util/treeMiscHelpers"; import { warningNotification } from "./notifications"; import { calcFullTipCounts, calcTipCounts } from "../util/treeCountingHelpers"; import { TreeState } from "../components/tree/tree"; -import { PhyloNode, ReduxNode, Root } from "../components/tree/phyloTree/types"; +import { Metadata, PhyloNode, ReduxNode, Root } from "../components/tree/phyloTree/types"; import { AppDispatch, RootState } from "../store"; @@ -405,7 +405,11 @@ const _traverseAndCreateSubtrees = ( /** * sort the subtrees by the order the trait would appear in the legend */ -const _orderSubtrees = (metadata: any, nodes: ReduxNode[], attr: string) => { +const _orderSubtrees = ( + metadata: Metadata, + nodes: ReduxNode[], + attr: string, +) => { const attrValueOrder = getLegendOrder(attr, metadata.colorings[attr], nodes, undefined); nodes[0].children.sort((childA, childB) => { const [attrA, attrB] = [getTraitFromNode(childA, attr), getTraitFromNode(childB, attr)]; diff --git a/src/components/tree/index.ts b/src/components/tree/index.ts index 88d26de3e..b00ca20c8 100644 --- a/src/components/tree/index.ts +++ b/src/components/tree/index.ts @@ -1,9 +1,10 @@ import { connect, MapStateToProps } from "react-redux"; import UnconnectedTree from "./tree"; import { RootState } from "../../store"; -import { TreeComponentPropsFromState } from "./tree"; +import { TreeComponentStateProps } from "./tree"; +import { TreeComponentOwnProps } from "./tree"; -const mapStateToProps: MapStateToProps, RootState> = (state: RootState) => ({ +const mapStateToProps: MapStateToProps = (state: RootState) => ({ tree: state.tree, treeToo: state.treeToo, selectedNode: state.controls.selectedNode, diff --git a/src/components/tree/phyloTree/change.ts b/src/components/tree/phyloTree/change.ts index e85037e8d..5aa5ee20e 100644 --- a/src/components/tree/phyloTree/change.ts +++ b/src/components/tree/phyloTree/change.ts @@ -6,8 +6,7 @@ import { NODE_VISIBLE } from "../../../util/globals"; import { getBranchVisibility, strokeForBranch } from "./renderers"; import { shouldDisplayTemporalConfidence } from "../../../reducers/controls"; import { makeTipLabelFunc } from "./labels"; -import { PhyloTree } from "./phyloTree"; -import { Distance, Layout, PhyloNode, PropsForPhyloNodes, SVGProperty, TreeElement, Visibility } from "./types"; +import { Distance, Layout, PhyloNode, PhyloTree, PropsForPhyloNodes, SVGProperty, TreeElement, Visibility } from "./types"; import { Selection, Transition } from "d3"; /* loop through the nodes and update each provided prop with the new value diff --git a/src/components/tree/phyloTree/helpers.ts b/src/components/tree/phyloTree/helpers.ts index 087022651..4d758a064 100644 --- a/src/components/tree/phyloTree/helpers.ts +++ b/src/components/tree/phyloTree/helpers.ts @@ -21,7 +21,7 @@ export const getDomId = (type: string, strain: string): string => { export const applyToChildren = ( phyloNode: PhyloNode, - /** function to apply to each children. Is passed a single argument, the of the children. */ + /** function to apply to each child. Is passed a single argument, the of the children. */ func: (node: PhyloNode) => void, ) => { func(phyloNode); diff --git a/src/components/tree/phyloTree/layouts.ts b/src/components/tree/phyloTree/layouts.ts index f36115eb4..41d7f83cd 100644 --- a/src/components/tree/phyloTree/layouts.ts +++ b/src/components/tree/phyloTree/layouts.ts @@ -6,8 +6,7 @@ import { timerStart, timerEnd } from "../../../util/perf"; import { getTraitFromNode, getDivFromNode } from "../../../util/treeMiscHelpers"; import { stemParent, nodeOrdering } from "./helpers"; import { numDate } from "../../../util/colorHelpers"; -import { PhyloTree } from "./phyloTree"; -import { Distance, Layout, Params, PhyloNode, ReduxNode, ScatterVariables } from "./types"; +import { Distance, Layout, Params, PhyloNode, PhyloTree, ReduxNode, ScatterVariables } from "./types"; /** * assigns the attribute this.layout and calls the function that diff --git a/src/components/tree/phyloTree/phyloTree.ts b/src/components/tree/phyloTree/phyloTree.ts index 68a4d94a5..8c90e387f 100644 --- a/src/components/tree/phyloTree/phyloTree.ts +++ b/src/components/tree/phyloTree/phyloTree.ts @@ -8,89 +8,10 @@ import * as grid from "./grid"; import * as confidence from "./confidence"; import * as labels from "./labels"; import * as regression from "./regression"; -import { Callbacks, Layout, Params, PhyloNode, ReduxNode, ScatterVariables, Visibility } from "./types"; -import { Selection } from "d3"; - -export interface PhyloTree { - grid: boolean - attributes: string[] - params: Params - groups: { - branchGradientDefs?: Selection - branchStem?: Selection - branchTee?: Selection - clipPath?: Selection - confidenceIntervals?: Selection - regression?: Selection - tips?: Selection - vaccines?: Selection - } - id: string - nodes: PhyloNode[] - zoomNode: PhyloNode - dateRange: [number, number] - strainToNode: Record - change: typeof change - modifySVG: typeof modifySVG - modifySVGInStages: typeof modifySVGInStages - render: typeof renderers.render - clearSVG: typeof renderers.clearSVG - setClipMask: typeof renderers.setClipMask - drawTips: typeof renderers.drawTips - drawBranches: typeof renderers.drawBranches - drawVaccines: typeof renderers.drawVaccines - drawRegression: typeof renderers.drawRegression - removeRegression: typeof renderers.removeRegression - updateColorBy: typeof renderers.updateColorBy - setDistance: typeof layouts.setDistance - setLayout: typeof layouts.setLayout - rectangularLayout: typeof layouts.rectangularLayout - scatterplotLayout: typeof layouts.scatterplotLayout - unrootedLayout: typeof layouts.unrootedLayout - radialLayout: typeof layouts.radialLayout - setScales: typeof layouts.setScales - mapToScreen: typeof layouts.mapToScreen - calculateRegression: typeof regression.calculateRegression - removeConfidence: typeof confidence.removeConfidence - drawConfidence: typeof confidence.drawConfidence - drawSingleCI: typeof confidence.drawSingleCI - drawBranchLabels: typeof labels.drawBranchLabels - removeBranchLabels: typeof labels.removeBranchLabels - updateBranchLabels: typeof labels.updateBranchLabels - updateTipLabels: typeof labels.updateTipLabels - removeTipLabels: typeof labels.removeTipLabels - hideGrid: typeof grid.hideGrid - addGrid: typeof grid.addGrid - showTemporalSlice: typeof grid.showTemporalSlice - hideTemporalSlice: typeof grid.hideTemporalSlice - - confidencesInSVG: boolean - regression?: regression.Regression - layout: Layout - svg: Selection - distance: "num_date" | "div" - vaccines?: PhyloNode[] - timeLastRenderRequested?: number - callbacks: Callbacks - visibility: Visibility[] - - scatterVariables?: ScatterVariables - margins: { - right: number - left: number - top: number - bottom: number - } - - // TODO: This should be `d3.ScalePoint | d3.ScaleContinuousNumeric`, conditional on layout - xScale: any - - // TODO: This should be `d3.ScalePoint | d3.ScaleContinuousNumeric`, conditional on layout - yScale: any -} +import { PhyloNode, PhyloTree as PhyloTreeType, ReduxNode } from "./types"; /* phylogenetic tree drawing function - the actual tree is rendered by the render prototype */ -const PhyloTree = function PhyloTree(this: PhyloTree, reduxNodes: ReduxNode[], id: string, idxOfInViewRootNode: number) { +const PhyloTree = function PhyloTree(this: PhyloTreeType, reduxNodes: ReduxNode[], id: string, idxOfInViewRootNode: number) { this.grid = false; this.attributes = ['r', 'cx', 'cy', 'id', 'class', 'd']; this.params = createDefaultParams(); diff --git a/src/components/tree/phyloTree/regression.ts b/src/components/tree/phyloTree/regression.ts index a13a8f911..2bf1e8373 100644 --- a/src/components/tree/phyloTree/regression.ts +++ b/src/components/tree/phyloTree/regression.ts @@ -1,8 +1,7 @@ import { sum } from "d3-array"; import { formatDivergence, guessAreMutationsPerSite} from "./helpers"; import { NODE_VISIBLE } from "../../../util/globals"; -import { PhyloTree } from "./phyloTree"; -import { PhyloNode } from "./types"; +import { PhyloNode, PhyloTree } from "./types"; export interface Regression { slope?: number diff --git a/src/components/tree/phyloTree/renderers.ts b/src/components/tree/phyloTree/renderers.ts index f063dc752..906ab8f54 100644 --- a/src/components/tree/phyloTree/renderers.ts +++ b/src/components/tree/phyloTree/renderers.ts @@ -3,8 +3,7 @@ import { NODE_VISIBLE } from "../../../util/globals"; import { getDomId, setDisplayOrder } from "./helpers"; import { makeRegressionText } from "./regression"; import { getEmphasizedColor } from "../../../util/colorHelpers"; -import { PhyloTree } from "./phyloTree"; -import { Callbacks, Distance, Layout, Params, PhyloNode, ReduxNode, ScatterVariables, Visibility } from "./types"; +import { Callbacks, Distance, Layout, Params, PhyloNode, PhyloTree, ReduxNode, ScatterVariables, Visibility } from "./types"; import { Selection } from "d3"; export const render = function render( diff --git a/src/components/tree/phyloTree/types.ts b/src/components/tree/phyloTree/types.ts index 82a4a9b37..cdfca98c7 100644 --- a/src/components/tree/phyloTree/types.ts +++ b/src/components/tree/phyloTree/types.ts @@ -1,5 +1,13 @@ import { NODE_NOT_VISIBLE, NODE_VISIBLE_TO_MAP_ONLY, NODE_VISIBLE } from "../../../util/globals"; -import { PhyloTree } from "./phyloTree"; +import { Selection } from "d3"; +import { change, modifySVG, modifySVGInStages } from "./change"; + +import * as renderers from "./renderers"; +import * as layouts from "./layouts"; +import * as grid from "./grid"; +import * as confidence from "./confidence"; +import * as labels from "./labels"; +import * as regression from "./regression"; export type Layout = "rect" | "radial" | "unrooted" | "clock" | "scatter" @@ -20,12 +28,6 @@ export type TreeElement = export type Visibility = typeof NODE_NOT_VISIBLE | typeof NODE_VISIBLE_TO_MAP_ONLY | typeof NODE_VISIBLE -export interface Colorings { - [key: string]: { - type: string - } -} - export interface Genotype { gene: string positions: number[] @@ -206,6 +208,84 @@ export interface PhyloNode extends Partial + branchStem?: Selection + branchTee?: Selection + clipPath?: Selection + confidenceIntervals?: Selection + regression?: Selection + tips?: Selection + vaccines?: Selection + } + id: string + nodes: PhyloNode[] + zoomNode: PhyloNode + dateRange: [number, number] + strainToNode: Record + change: typeof change + modifySVG: typeof modifySVG + modifySVGInStages: typeof modifySVGInStages + render: typeof renderers.render + clearSVG: typeof renderers.clearSVG + setClipMask: typeof renderers.setClipMask + drawTips: typeof renderers.drawTips + drawBranches: typeof renderers.drawBranches + drawVaccines: typeof renderers.drawVaccines + drawRegression: typeof renderers.drawRegression + removeRegression: typeof renderers.removeRegression + updateColorBy: typeof renderers.updateColorBy + setDistance: typeof layouts.setDistance + setLayout: typeof layouts.setLayout + rectangularLayout: typeof layouts.rectangularLayout + scatterplotLayout: typeof layouts.scatterplotLayout + unrootedLayout: typeof layouts.unrootedLayout + radialLayout: typeof layouts.radialLayout + setScales: typeof layouts.setScales + mapToScreen: typeof layouts.mapToScreen + calculateRegression: typeof regression.calculateRegression + removeConfidence: typeof confidence.removeConfidence + drawConfidence: typeof confidence.drawConfidence + drawSingleCI: typeof confidence.drawSingleCI + drawBranchLabels: typeof labels.drawBranchLabels + removeBranchLabels: typeof labels.removeBranchLabels + updateBranchLabels: typeof labels.updateBranchLabels + updateTipLabels: typeof labels.updateTipLabels + removeTipLabels: typeof labels.removeTipLabels + hideGrid: typeof grid.hideGrid + addGrid: typeof grid.addGrid + showTemporalSlice: typeof grid.showTemporalSlice + hideTemporalSlice: typeof grid.hideTemporalSlice + + confidencesInSVG: boolean + regression?: regression.Regression + layout: Layout + svg: Selection + distance: Distance + vaccines?: PhyloNode[] + timeLastRenderRequested?: number + callbacks: Callbacks + visibility: Visibility[] + + scatterVariables?: ScatterVariables + margins: { + right: number + left: number + top: number + bottom: number + } + + // TODO: This should be `d3.ScalePoint | d3.ScaleContinuousNumeric`, conditional on layout + xScale: any + + // TODO: This should be `d3.ScalePoint | d3.ScaleContinuousNumeric`, conditional on layout + yScale: any +} + export interface ScatterVariables { showBranches?: boolean showRegression?: boolean @@ -273,3 +353,19 @@ export interface Callbacks { onBranchClick: (d: PhyloNode) => void tipLabel: (d: PhyloNode) => void } + +export type Metadata = { + colorings: Colorings +} + +export type Colorings = { + [key: string]: ColoringInfo +} + +export type ColoringInfo = { + title: string + type: ScaleType + + /** scale set via JSON */ + scale: [string, string][] +} diff --git a/src/components/tree/reactD3Interface/change.ts b/src/components/tree/reactD3Interface/change.ts index 50144235c..ad8758983 100644 --- a/src/components/tree/reactD3Interface/change.ts +++ b/src/components/tree/reactD3Interface/change.ts @@ -1,6 +1,6 @@ import { calculateStrokeColors, getBrighterColor } from "../../../util/colorHelpers"; import { ChangeParams } from "../phyloTree/change"; -import { PhyloTree } from "../phyloTree/phyloTree"; +import { PhyloTree } from "../phyloTree/types"; import { TreeComponentProps, TreeComponentState } from "../tree"; export const changePhyloTreeViaPropsComparison = ( diff --git a/src/components/tree/reactD3Interface/initialRender.ts b/src/components/tree/reactD3Interface/initialRender.ts index a99e03367..ffab21985 100644 --- a/src/components/tree/reactD3Interface/initialRender.ts +++ b/src/components/tree/reactD3Interface/initialRender.ts @@ -3,7 +3,7 @@ import 'd3-transition'; import { calculateStrokeColors, getBrighterColor } from "../../../util/colorHelpers"; import * as callbacks from "./callbacks"; import { makeTipLabelFunc } from "../phyloTree/labels"; -import { PhyloTree } from "../phyloTree/phyloTree"; +import { PhyloTree } from "../phyloTree/types"; import { TreeComponent, TreeComponentProps } from "../tree"; export const renderTree = ( diff --git a/src/components/tree/tree.tsx b/src/components/tree/tree.tsx index 2c0dd857f..72d6307fd 100644 --- a/src/components/tree/tree.tsx +++ b/src/components/tree/tree.tsx @@ -4,8 +4,8 @@ import { FaSearchMinus } from "react-icons/fa"; import { updateVisibleTipsAndBranchThicknesses } from "../../actions/tree"; import Card from "../framework/card"; import Legend from "./legend/legend"; -import PhyloTreeConstructor, { PhyloTree } from "./phyloTree/phyloTree"; -import { ColorScale, Layout, Mutations, ReactTreeNode, ReduxNode, Root, ScatterVariables, TemporalConfidence, TraitCounts, Visibility } from "./phyloTree/types"; +import PhyloTreeConstructor from "./phyloTree/phyloTree"; +import { ColorScale, Layout, Mutations, PhyloTree, ReactTreeNode, ReduxNode, Root, ScatterVariables, TemporalConfidence, TraitCounts, Visibility } from "./phyloTree/types"; import { getParentBeyondPolytomy } from "./phyloTree/helpers"; import HoverInfoPanel from "./infoPanels/hover"; import NodeClickedPanel from "./infoPanels/click"; @@ -53,15 +53,17 @@ interface TreeTooState extends TreeState { tangleTipLookup: any[][] } -export interface TreeComponentProps extends WithTranslation, TreeComponentPropsFromState { +export interface TreeComponentOwnProps { dispatch: AppDispatch height: number width: number } +export interface TreeComponentProps extends WithTranslation, TreeComponentStateProps, TreeComponentOwnProps {} + // This is duplicated from RootState, but good to be explicit about what's // expected here. -export interface TreeComponentPropsFromState { +export interface TreeComponentStateProps { animationPlayPauseButton: "Play" | "Pause" canRenderBranchLabels: boolean colorBy: string diff --git a/src/util/colorScale.ts b/src/util/colorScale.ts index 5b35abc48..4ea333eed 100644 --- a/src/util/colorScale.ts +++ b/src/util/colorScale.ts @@ -9,7 +9,7 @@ import { isColorByGenotype, decodeColorByGenotype } from "./getGenotype"; import { setGenotype, orderOfGenotypeAppearance } from "./setGenotype"; import { getTraitFromNode } from "./treeMiscHelpers"; import { sortedDomain } from "./sortedDomain"; -import { ColorScale, Genotype, LegendBounds, LegendLabels, LegendValues, ReduxNode, ScaleType, Visibility } from "../components/tree/phyloTree/types"; +import { ColoringInfo, ColorScale, Genotype, LegendBounds, LegendLabels, LegendValues, ReduxNode, ScaleType, Visibility } from "../components/tree/phyloTree/types"; import { TreeState } from "../components/tree/tree"; import { ControlsState } from "../reducers/controls"; @@ -402,12 +402,7 @@ function getDiscreteValuesFromTree( */ export function getLegendOrder( attr: string, - coloringInfo: { - type: ScaleType - - /** scale set via JSON */ - scale: [string, string][] - }, + coloringInfo: ColoringInfo, nodesA: ReduxNode[], nodesB: ReduxNode[] | undefined, ) {