Skip to content

Commit

Permalink
🚧 split functionality out as 'focus'
Browse files Browse the repository at this point in the history
Simply renaming this functionality and separating it from 'zoom' helped
me understand the difference better. The separate buttons may be helpful
too.
  • Loading branch information
victorlin committed Sep 13, 2024
1 parent 1c0ad29 commit 7321e43
Show file tree
Hide file tree
Showing 13 changed files with 78 additions and 54 deletions.
4 changes: 2 additions & 2 deletions src/actions/recomputeReduxState.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ const modifyStateViaURLQuery = (state, query) => {
if (query.m && state.branchLengthsToDisplay === "divAndDate") {
state["distanceMeasure"] = query.m;
}
if (query.z) {
state["treeZoom"] = query.z;
if (query.focus) {
state["treeFocus"] = query.focus;
}
if (query.c) {
state["colorBy"] = query.c;
Expand Down
2 changes: 1 addition & 1 deletion src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const SEARCH_INPUT_CHANGE = "SEARCH_INPUT_CHANGE";
export const CHANGE_LAYOUT = "CHANGE_LAYOUT";
export const CHANGE_BRANCH_LABEL = "CHANGE_BRANCH_LABEL";
export const CHANGE_DISTANCE_MEASURE = "CHANGE_DISTANCE_MEASURE";
export const CHANGE_TREE_ZOOM = "CHANGE_TREE_ZOOM";
export const CHANGE_TREE_FOCUS = "CHANGE_TREE_FOCUS";
export const CHANGE_DATES_VISIBILITY_THICKNESS = "CHANGE_DATES_VISIBILITY_THICKNESS";
export const CHANGE_ABSOLUTE_DATE_MIN = "CHANGE_ABSOLUTE_DATE_MIN";
export const CHANGE_ABSOLUTE_DATE_MAX = "CHANGE_ABSOLUTE_DATE_MAX";
Expand Down
2 changes: 1 addition & 1 deletion src/components/tree/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const Tree = connect((state) => ({
temporalConfidence: state.controls.temporalConfidence,
distanceMeasure: state.controls.distanceMeasure,
explodeAttr: state.controls.explodeAttr,
treeZoom: state.controls.treeZoom,
treeFocus: state.controls.treeFocus,
colorScale: state.controls.colorScale,
colorings: state.metadata.colorings,
genomeMap: state.entropy.genomeMap,
Expand Down
14 changes: 7 additions & 7 deletions src/components/tree/phyloTree/change.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ export const change = function change({
/* change these things to provided value (unless undefined) */
newDistance = undefined,
newLayout = undefined,
newTreeZoom = undefined,
newTreeFocus = undefined,
updateLayout = undefined, // todo - this seems identical to `newLayout`
newBranchLabellingKey = undefined,
showAllBranchLabels = undefined,
Expand Down Expand Up @@ -314,7 +314,7 @@ export const change = function change({
svgPropsToUpdate.add("stroke-width");
nodePropsToModify["stroke-width"] = branchThickness;
}
if (newDistance || newLayout || newTreeZoom || updateLayout || zoomIntoClade || svgHasChangedDimensions || changeNodeOrder) {
if (newDistance || newLayout || newTreeFocus || updateLayout || zoomIntoClade || svgHasChangedDimensions || changeNodeOrder) {
elemsToUpdate.add(".tip").add(".branch.S").add(".branch.T").add(".branch");
elemsToUpdate.add(".vaccineCross").add(".vaccineDottedLine").add(".conf");
elemsToUpdate.add('.branchLabel').add('.tipLabel');
Expand Down Expand Up @@ -360,10 +360,10 @@ export const change = function change({
/* run calculations as needed - these update properties on the phylotreeNodes (similar to updateNodesWithNewData) */
/* distance */
if (newDistance || updateLayout) this.setDistance(newDistance);
/* treeZoom */
if (newTreeZoom || updateLayout) this.setTreeZoom(newTreeZoom);
/* layout (must run after distance and treeZoom) */
if (newDistance || newLayout || newTreeZoom || updateLayout || changeNodeOrder) {
/* treeFocus */
if (newTreeFocus || updateLayout) this.setTreeFocus(newTreeFocus);
/* layout (must run after distance and treeFocus) */
if (newDistance || newLayout || newTreeFocus || updateLayout || changeNodeOrder) {
this.setLayout(newLayout || this.layout, scatterVariables);
}
/* show confidences - set this param which actually adds the svg paths for
Expand All @@ -380,7 +380,7 @@ export const change = function change({
newDistance ||
newLayout ||
changeNodeOrder ||
newTreeZoom ||
newTreeFocus ||
updateLayout ||
zoomIntoClade ||
svgHasChangedDimensions ||
Expand Down
22 changes: 11 additions & 11 deletions src/components/tree/phyloTree/layouts.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ export const calcYValues = (nodes, spacing = "even") => {
// console.log("calcYValues started with ", spacing);
let total = 0; /* cumulative counter of y value at tip */
let calcY; /* fn called calcY(node) to return some amount of y value at a tip */
if (spacing.includes("zoom") && 'visibility' in nodes[0]) {
if (spacing.includes("focus") && 'visibility' in nodes[0]) {
const numberOfTips = nodes.length;
const numTipsVisible = nodes.filter((d) => !d.hasChildren && d.visibility === NODE_VISIBLE).length;
const yPerVisible = (0.8 * numberOfTips) / numTipsVisible;
Expand Down Expand Up @@ -334,19 +334,19 @@ export const calcYValues = (nodes, spacing = "even") => {
};

/**
* assigns the attribute this.treeZoom and calls the function that
* recalculates yvalues based on treeZoom setting
* @param treeZoom -- how to zoom nodes, eg ["even", "zoom"]
* assigns the attribute this.treeFocus and calls the function that
* recalculates yvalues based on treeFocus setting
* @param treeFocus -- how to zoom nodes, eg ["even", "focus"]
*/
export const setTreeZoom = function setTreeZoom(treeZoom) {
timerStart("setTreeZoom");
if (typeof treeZoom === "undefined") {
this.treeZoom = "even";
export const setTreeFocus = function setTreeFocus(treeFocus) {
timerStart("setTreeFocus");
if (typeof treeFocus === "undefined") {
this.treeFocus = "even";
} else {
this.treeZoom = treeZoom;
this.treeFocus = treeFocus;
}
calcYValues(this.nodes, this.treeZoom);
timerEnd("setTreeZoom");
calcYValues(this.nodes, this.treeFocus);
timerEnd("setTreeFocus");
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/components/tree/phyloTree/phyloTree.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ PhyloTree.prototype.updateColorBy = renderers.updateColorBy;
/* C A L C U L A T E G E O M E T R I E S E T C ( M O D I F I E S N O D E S , N O T S V G ) */
PhyloTree.prototype.setDistance = layouts.setDistance;
PhyloTree.prototype.setLayout = layouts.setLayout;
PhyloTree.prototype.setTreeZoom = layouts.setTreeZoom;
PhyloTree.prototype.setTreeFocus = layouts.setTreeFocus;
PhyloTree.prototype.rectangularLayout = layouts.rectangularLayout;
PhyloTree.prototype.scatterplotLayout = layouts.scatterplotLayout;
PhyloTree.prototype.unrootedLayout = layouts.unrootedLayout;
Expand Down
6 changes: 3 additions & 3 deletions src/components/tree/phyloTree/renderers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getEmphasizedColor } from "../../../util/colorHelpers";
* @param {d3 selection} svg -- the svg into which the tree is drawn
* @param {string} layout -- the layout to be used, e.g. "rect"
* @param {string} distance -- the property used as branch length, e.g. div or num_date
* @param {string} treeZoom -- how to to treat spread of yValues, e.g. "even" or "zoom"
* @param {string} treeFocus -- how to to treat spread of yValues, e.g. "even" or "focus"
* @param {object} parameters -- an object that contains options that will be added to this.params
* @param {object} callbacks -- an object with call back function defining mouse behavior
* @param {array} branchThickness -- array of branch thicknesses (same ordering as tree nodes)
Expand All @@ -22,7 +22,7 @@ import { getEmphasizedColor } from "../../../util/colorHelpers";
* @param {object} scatterVariables -- {x, y} properties to map nodes => scatterplot (only used if layout="scatter")
* @return {null}
*/
export const render = function render(svg, layout, distance, treeZoom, parameters, callbacks, branchThickness, visibility, drawConfidence, vaccines, branchStroke, tipStroke, tipFill, tipRadii, dateRange, scatterVariables) {
export const render = function render(svg, layout, distance, treeFocus, parameters, callbacks, branchThickness, visibility, drawConfidence, vaccines, branchStroke, tipStroke, tipFill, tipRadii, dateRange, scatterVariables) {
timerStart("phyloTree render()");
this.svg = svg;
this.params = Object.assign(this.params, parameters);
Expand All @@ -43,7 +43,7 @@ export const render = function render(svg, layout, distance, treeZoom, parameter
/* set x, y values & scale them to the screen */
setDisplayOrder(this.nodes);
this.setDistance(distance);
this.setTreeZoom(treeZoom);
this.setTreeFocus(treeFocus);
this.setLayout(layout, scatterVariables);
this.mapToScreen();

Expand Down
6 changes: 3 additions & 3 deletions src/components/tree/reactD3Interface/change.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ export const changePhyloTreeViaPropsComparison = (mainTree, phylotree, oldProps,
args.changeNodeOrder = true;
}

/* change treeZoom behavior */
if (oldProps.treeZoom !== newProps.treeZoom) {
args.newTreeZoom = newProps.treeZoom;
/* change treeFocus behavior */
if (oldProps.treeFocus !== newProps.treeFocus) {
args.newTreeFocus = newProps.treeFocus;
args.updateLayout = true;
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/tree/reactD3Interface/initialRender.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const renderTree = (that, main, phylotree, props) => {
select(ref),
props.layout,
props.distanceMeasure,
props.treeZoom,
props.treeFocus,
{ /* parameters (modifies PhyloTree's defaults) */
grid: true,
confidence: props.temporalConfidence.display,
Expand Down
56 changes: 40 additions & 16 deletions src/components/tree/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { withTranslation } from "react-i18next";
import { FaSearchMinus } from "react-icons/fa";
import { updateVisibleTipsAndBranchThicknesses } from "../../actions/tree";
import { CHANGE_TREE_ZOOM } from "../../actions/types";
import { CHANGE_TREE_FOCUS } from "../../actions/types";
import Card from "../framework/card";
import Legend from "./legend/legend";
import PhyloTree from "./phyloTree/phyloTree";
Expand Down Expand Up @@ -40,7 +40,7 @@ class Tree extends React.Component {
this.clearSelectedNode = callbacks.clearSelectedNode.bind(this);
// this.handleIconClickHOF = callbacks.handleIconClickHOF.bind(this);
this.redrawTree = () => {
this.props.dispatch({ type: CHANGE_TREE_ZOOM, data: "even" });
this.props.dispatch({ type: CHANGE_TREE_FOCUS, data: "even" });
this.props.dispatch(updateVisibleTipsAndBranchThicknesses({
root: [0, 0]
}));
Expand Down Expand Up @@ -112,9 +112,17 @@ class Tree extends React.Component {
}

getStyles = () => {
// FIXME: double-check this
const activeResetTreeButton = true;
const activeZoomButton = true;
const activeResetTreeButton = this.props.tree.idxOfInViewRootNode !== 0 ||
this.props.treeToo.idxOfInViewRootNode !== 0;

const filteredTree = !!this.props.tree.idxOfFilteredRoot &&
this.props.tree.idxOfInViewRootNode !== this.props.tree.idxOfFilteredRoot;
const filteredTreeToo = !!this.props.treeToo.idxOfFilteredRoot &&
this.props.treeToo.idxOfInViewRootNode !== this.props.treeToo.idxOfFilteredRoot;
const activeZoomButton = filteredTree || filteredTreeToo;

const activeFocusButton = true;

const treeIsZoomed = this.props.tree.idxOfInViewRootNode !== 0 ||
this.props.treeToo.idxOfInViewRootNode !== 0;

Expand All @@ -139,6 +147,13 @@ class Tree extends React.Component {
color: activeZoomButton ? darkGrey : lightGrey,
pointerEvents: activeZoomButton ? "auto" : "none"
},
focusOnSelectedButton: {
zIndex: 100,
display: "inline-block",
cursor: activeFocusButton ? "pointer" : "auto",
color: activeFocusButton ? darkGrey : lightGrey,
pointerEvents: activeFocusButton ? "auto" : "none"
},
zoomOutButton: {
zIndex: 100,
display: "inline-block",
Expand All @@ -162,20 +177,23 @@ class Tree extends React.Component {
);
}

zoomToSelected = () => {
// if currently set to "even", start at "zoom"
let treeZoomData = "zoom";
if (this.props.treeZoom.includes("zoom")) {
// if currently at "zoom", increment to "zoom-2"
if (!this.props.treeZoom.includes("-")) {
treeZoomData = "zoom-2";
focusOnSelected = () => {
// if currently set to "even", start at "focus"
let treeFocusData = "focus";
if (this.props.treeFocus.includes("focus")) {
// if currently at "focus", increment to "focus-2"
if (!this.props.treeFocus.includes("-")) {
treeFocusData = "focus-2";
} else {
// if currently at "zoom-2", increment to "zoom-3", etc...
const increment = parseInt(this.props.treeZoom.split('-')[1], 10) + 1;
treeZoomData = "zoom-" + increment.toString();
// if currently at "focus-2", increment to "focus-3", etc...
const increment = parseInt(this.props.treeFocus.split('-')[1], 10) + 1;
treeFocusData = "focus-" + increment.toString();
}
}
this.props.dispatch({ type: CHANGE_TREE_ZOOM, data: treeZoomData });
this.props.dispatch({ type: CHANGE_TREE_FOCUS, data: treeFocusData });
};

zoomToSelected = () => {
this.props.dispatch(updateVisibleTipsAndBranchThicknesses({
root: [this.props.tree.idxOfFilteredRoot, this.props.treeToo.idxOfFilteredRoot]
}));
Expand Down Expand Up @@ -266,6 +284,12 @@ class Tree extends React.Component {
>
{t("Zoom to Selected")}
</button>
<button
style={{...tabSingle, ...styles.focusOnSelectedButton}}
onClick={this.focusOnSelected}
>
{t("Focus On Selected")}
</button>
<button
style={{...tabSingle, ...styles.resetTreeButton}}
onClick={this.redrawTree}
Expand Down
4 changes: 2 additions & 2 deletions src/middleware/changeURL.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ export const changeURLMiddleware = (store) => (next) => (action) => {
query.p = action.notInURLState === true ? undefined : action.data;
break;
}
case types.CHANGE_TREE_ZOOM: {
query.z = action.data === state.controls.defaults.treeZoom ? undefined : action.data;
case types.CHANGE_TREE_FOCUS: {
query.z = action.data === state.controls.defaults.treeFocus ? undefined : action.data;
break;
}
case types.TOGGLE_SIDEBAR: {
Expand Down
10 changes: 5 additions & 5 deletions src/reducers/controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { defaultGeoResolution,
defaultDateRange,
defaultDistanceMeasure,
defaultLayout,
defaultTreeZoom,
defaultTreeFocus,
controlsHiddenWidth,
strainSymbol,
twoColumnBreakpoint } from "../util/globals";
Expand Down Expand Up @@ -44,7 +44,7 @@ export const getDefaultControlsState = () => {
const defaults: Partial<ControlsState> = {
distanceMeasure: defaultDistanceMeasure,
layout: defaultLayout,
treeZoom: defaultTreeZoom,
treeFocus: defaultTreeFocus,
geoResolution: defaultGeoResolution,
filters: {},
filtersInFooter: [],
Expand Down Expand Up @@ -72,7 +72,7 @@ export const getDefaultControlsState = () => {
layout: defaults.layout,
scatterVariables: {},
distanceMeasure: defaults.distanceMeasure,
treeZoom: defaults.treeZoom,
treeFocus: defaults.treeFocus,
dateMin,
dateMinNumeric,
dateMax,
Expand Down Expand Up @@ -195,9 +195,9 @@ const Controls = (state: ControlsState = getDefaultControlsState(), action): Con
}
return Object.assign({}, state, updatesToState);
}
case types.CHANGE_TREE_ZOOM:
case types.CHANGE_TREE_FOCUS:
return Object.assign({}, state, {
treeZoom: action.data
treeFocus: action.data
});
case types.CHANGE_DATES_VISIBILITY_THICKNESS: {
const newDates: Partial<ControlsState> = { quickdraw: action.quickdraw };
Expand Down
2 changes: 1 addition & 1 deletion src/util/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const defaultColorBy = "country";
export const defaultGeoResolution = "country";
export const defaultLayout = "rect";
export const defaultDistanceMeasure = "num_date";
export const defaultTreeZoom = "even";
export const defaultTreeFocus = "even";
export const defaultDateRange = 6;
export const date_select = true;
export const file_prefix = "Zika_";
Expand Down

0 comments on commit 7321e43

Please sign in to comment.