Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve React-PhyloTree interface #501

Merged
merged 25 commits into from
Feb 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3b2ebb6
basic idea of new react-phylotree interface
jameshadfield Feb 14, 2018
b2c541a
initial render displays colours without extra phylotree call
jameshadfield Feb 14, 2018
b2883c7
visibility & tipRadii
jameshadfield Feb 14, 2018
7e87e5b
branch thickness & transition logic
jameshadfield Feb 15, 2018
ad2ce97
updateDistance
jameshadfield Feb 16, 2018
e0938da
confidence intervals (buggy)
jameshadfield Feb 16, 2018
20e472e
zooom into clade (without branch thicknesses)
jameshadfield Feb 16, 2018
b68cea6
branch thicknesses change during zoom to clade
jameshadfield Feb 16, 2018
2ee1b3d
layout changes (all transitions at once)
jameshadfield Feb 16, 2018
1cdc192
remove updateStylesAndAttrs and salientPropChanges
jameshadfield Feb 16, 2018
583086c
use timerflush for zero-time transitions
jameshadfield Feb 16, 2018
a0d889d
svg size changes handled
jameshadfield Feb 16, 2018
8f3d6c1
add comments & improve bits of the code
jameshadfield Feb 16, 2018
b070bfc
partial implementation of changePageQuery
jameshadfield Feb 16, 2018
35bda6b
changePageQuery is now a single action
jameshadfield Feb 20, 2018
ea35173
deprecate code
jameshadfield Feb 20, 2018
9705682
implement zoomToParent within phylotree.changes
jameshadfield Feb 20, 2018
7b6c29d
clean up clade labelling functions
jameshadfield Feb 20, 2018
5eccf91
improve initial render()
jameshadfield Feb 20, 2018
f3ebb3a
sync CIs between redux & phylotree
jameshadfield Feb 20, 2018
88c3d96
don't use transitions for CI entry / exit (too slow)
jameshadfield Feb 20, 2018
446e7a5
restore 3-part transitions
jameshadfield Feb 20, 2018
f95eac3
remove console logs. disable action logging middleware.
jameshadfield Feb 20, 2018
85d993c
remove quickdraw (no performance effect)
jameshadfield Feb 20, 2018
e7069e1
Improve speed of compute responsive. Closes #499.
jameshadfield Feb 20, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"d3-selection": "^1.1.0",
"d3-shape": "^1.2.0",
"d3-time-format": "^2.0.5",
"d3-timer": "^1.0.7",
"d3-zoom": "^1.1.3",
"express": "^4.13.3",
"express-static-gzip": "^0.2.2",
Expand Down
36 changes: 19 additions & 17 deletions src/actions/colors.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@ import { timerStart, timerEnd } from "../util/perf";
import { updateEntropyVisibility } from "./entropy";
import * as types from "./types";

export const calcColorScaleAndNodeColors = (colorBy, controls, tree, metadata) => {
let genotype;
if (colorBy.slice(0, 3) === "gt-" && controls.geneLength) {
const x = parseGenotype(colorBy, controls.geneLength);
setGenotype(tree.nodes, x[0][0], x[0][1] + 1); /* modifies nodes recursively */
genotype = parseGenotype(colorBy, controls.geneLength);
}

/* step 1: calculate the required colour scale */
const version = controls.colorScale === undefined ? 1 : controls.colorScale.version + 1;
const colorScale = getColorScale(colorBy, tree, controls.geneLength, metadata.colorOptions, version, controls.absoluteDateMaxNumeric);
if (genotype) colorScale.genotype = genotype;

/* step 2: calculate the node colours */
const nodeColors = calcNodeColor(tree, colorScale);
return {nodeColors, colorScale, version};
};

/* providedColorBy: undefined | string */
export const changeColorBy = (providedColorBy = undefined) => { // eslint-disable-line import/prefer-default-export
return (dispatch, getState) => {
Expand All @@ -23,23 +41,7 @@ export const changeColorBy = (providedColorBy = undefined) => { // eslint-disabl
return null;
}
const colorBy = providedColorBy ? providedColorBy : controls.colorBy;

if (colorBy.slice(0, 3) === "gt-") {
const x = parseGenotype(colorBy, controls.geneLength);
setGenotype(tree.nodes, x[0][0], x[0][1] + 1);
}

/* step 1: calculate the required colour scale */
const version = controls.colorScale === undefined ? 1 : controls.colorScale.version + 1;
// console.log("updateColorScale setting colorScale to ", version);
const colorScale = getColorScale(colorBy, tree, controls.geneLength, metadata.colorOptions, version, controls.absoluteDateMaxNumeric);
/* */
if (colorBy.slice(0, 3) === "gt-" && controls.geneLength) {
colorScale.genotype = parseGenotype(colorBy, controls.geneLength);
}

/* step 2: calculate the node colours */
const nodeColors = calcNodeColor(tree, colorScale);
const {nodeColors, colorScale, version} = calcColorScaleAndNodeColors(colorBy, controls, tree, metadata);

/* step 3: change in mutType? */
const newMutType = determineColorByGenotypeType(colorBy) !== controls.mutType ? determineColorByGenotypeType(colorBy) : false;
Expand Down
60 changes: 45 additions & 15 deletions src/actions/navigation.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import parseParams from "../util/parseParams";
import queryString from "query-string";
import parseParams from "../util/parseParams";
import { getPost } from "../util/getMarkdown";
import { PAGE_CHANGE, URL_QUERY_CHANGE } from "./types";
import { updateVisibleTipsAndBranchThicknesses } from "./treeProperties";
import { changeColorBy } from "./colors";
import { PAGE_CHANGE, URL_QUERY_CHANGE_WITH_COMPUTED_STATE } from "./types";
import { calculateVisiblityAndBranchThickness } from "./treeProperties";
import { calcColorScaleAndNodeColors } from "./colors";
import { restoreQueryableStateToDefaults, modifyStateViaURLQuery, checkAndCorrectErrorsInState, checkColorByConfidence } from "../reducers/controls";
import { calcEntropyInView } from "../util/treeTraversals";

// make prefix for data files with fields joined by _ instead of / as in URL
const makeDataPathFromParsedParams = (parsedParams) => {
Expand Down Expand Up @@ -78,21 +80,49 @@ ARGUMENTS:
(2) push - OPTIONAL (default: true) - signals that pushState should be used (has no effect on the reducers)
*/
export const changePageQuery = ({query, push = true}) => (dispatch, getState) => {
const { controls, metadata } = getState();
console.log("\t---------- change page query -------------");
const { controls, metadata, tree, entropy } = getState();

/* 1 - calculate entire new state of the controls reducer */
let newControls = Object.assign({}, controls);
newControls = restoreQueryableStateToDefaults(newControls);
newControls = modifyStateViaURLQuery(newControls, query);
newControls = checkAndCorrectErrorsInState(newControls, metadata);

/* 2 - calculate new branch thicknesses & visibility */
const visAndThicknessData = calculateVisiblityAndBranchThickness(
tree,
newControls,
{dateMinNumeric: newControls.dateMinNumeric, dateMaxNumeric: newControls.dateMaxNumeric},
{tipSelectedIdx: 0, validIdxRoot: tree.idxOfInViewRootNode}
);
visAndThicknessData.stateCountAttrs = Object.keys(newControls.filters);
const newTree = Object.assign({}, tree, visAndThicknessData);

/* 3 - calculate colours */
if (controls.colorBy !== newControls.colorBy) {
const {nodeColors, colorScale, version} = calcColorScaleAndNodeColors(newControls.colorBy, newControls, tree, metadata);
newControls.colorScale = colorScale;
newControls.colorByConfidence = checkColorByConfidence(newControls.attrs, newControls.colorBy);
newTree.nodeColorsVersion = version;
newTree.nodeColors = nodeColors;
}

/* 4 - calculate entropy in view */
const [entropyBars, entropyMaxYVal] = calcEntropyInView(newTree.nodes, newTree.visibility, newControls.mutType, entropy.geneMap, entropy.showCounts);

dispatch({
type: URL_QUERY_CHANGE,
query,
metadata,
pushState: push
type: URL_QUERY_CHANGE_WITH_COMPUTED_STATE,
newControls,
pushState: push,
newTree,
entropyBars,
entropyMaxYVal,
query
});
const newState = getState();
/* working out whether visibility / thickness needs updating is tricky - ideally we could avoid this dispatch in some situations */
dispatch(updateVisibleTipsAndBranchThicknesses());
if (controls.colorBy !== newState.controls.colorBy) {
dispatch(changeColorBy());
}
};


export const browserBackForward = () => (dispatch, getState) => {
const { datasets } = getState();
/* if the pathname has changed, trigger the changePage action (will trigger new post to load, new dataset to load, etc) */
Expand Down
16 changes: 14 additions & 2 deletions src/actions/treeProperties.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { calcVisibility,
import * as types from "./types";
import { updateEntropyVisibility } from "./entropy";
import { calendarToNumeric } from "../util/dateHelpers";
import { applyToChildren } from "../components/tree/phyloTree/helpers";


const calculateVisiblityAndBranchThickness = (tree, controls, dates, {idxOfInViewRootNode = 0, tipSelectedIdx = 0} = {}) => {
export const calculateVisiblityAndBranchThickness = (tree, controls, dates, {idxOfInViewRootNode = 0, tipSelectedIdx = 0} = {}) => {
const visibility = tipSelectedIdx ? identifyPathToTip(tree.nodes, tipSelectedIdx) : calcVisibility(tree, controls, dates);
/* recalculate tipCounts over the tree - modifies redux tree nodes in place (yeah, I know) */
calcTipCounts(tree.nodes[0], visibility);
Expand Down Expand Up @@ -38,6 +38,18 @@ export const updateVisibleTipsAndBranchThicknesses = (
const { tree, controls } = getState();
if (!tree.nodes) {return;}
const validIdxRoot = idxOfInViewRootNode !== undefined ? idxOfInViewRootNode : tree.idxOfInViewRootNode;
if (idxOfInViewRootNode !== tree.idxOfInViewRootNode && tree.nodes[0].shell) {
/* a bit hacky, should be somewhere else */
tree.nodes.forEach((d) => {
d.shell.inView = false;
d.shell.update = true;
});
if (tree.nodes[validIdxRoot].shell.terminal) {
applyToChildren(tree.nodes[validIdxRoot].shell.parent, (d) => {d.inView = true;});
} else {
applyToChildren(tree.nodes[validIdxRoot].shell, (d) => {d.inView = true;});
}
}
const data = calculateVisiblityAndBranchThickness(tree, controls, {dateMinNumeric: controls.dateMinNumeric, dateMaxNumeric: controls.dateMaxNumeric}, {tipSelectedIdx, validIdxRoot});
dispatch({
type: types.UPDATE_VISIBILITY_AND_BRANCH_THICKNESS,
Expand Down
3 changes: 1 addition & 2 deletions src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export const REQUEST_FREQUENCIES = "REQUEST_FREQUENCIES";
export const RECEIVE_FREQUENCIES = "RECEIVE_FREQUENCIES";
export const FREQUENCIES_FETCH_ERROR = "FREQUENCIES_FETCH_ERROR";
export const BROWSER_DIMENSIONS = "BROWSER_DIMENSIONS";
export const TOGGLE_BRANCH_LABELS = "TOGGLE_BRANCH_LABELS";
export const LEGEND_ITEM_MOUSEENTER = "LEGEND_ITEM_MOUSEENTER";
export const LEGEND_ITEM_MOUSELEAVE = "LEGEND_ITEM_MOUSELEAVE";
export const BRANCH_MOUSEENTER = "BRANCH_MOUSEENTER";
Expand Down Expand Up @@ -42,7 +41,6 @@ export const ADD_COLOR_BYS = "ADD_COLOR_BYS";
export const MANIFEST_RECEIVED = "MANIFEST_RECEIVED";
export const POSTS_MANIFEST_RECEIVED = "POSTS_MANIFEST_RECEIVED";
export const CHANGE_TREE_ROOT_IDX = "CHANGE_TREE_ROOT_IDX";
export const URL_QUERY_CHANGE = "URL_QUERY_CHANGE";
export const NEW_NARRATIVE = "NEW_NARRATIVE";
export const TOGGLE_NARRATIVE = "TOGGLE_NARRATIVE";
export const ENTROPY_DATA = "ENTROPY_DATA";
Expand All @@ -51,3 +49,4 @@ export const PAGE_CHANGE = "PAGE_CHANGE";
export const NEW_POST = "NEW_POST";
export const URL = "URL";
export const MIDDLEWARE_ONLY_ANIMATION_STARTED = "MIDDLEWARE_ONLY_ANIMATION_STARTED";
export const URL_QUERY_CHANGE_WITH_COMPUTED_STATE = "URL_QUERY_CHANGE_WITH_COMPUTED_STATE";
4 changes: 1 addition & 3 deletions src/components/controls/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ import ChooseMetric from "./choose-metric";
import PanelLayout from "./panel-layout";
import GeoResolution from "./geo-resolution";
import MapAnimationControls from "./map-animation";
import { controlsWidth, enableAnimationDisplay } from "../../util/globals";
import { controlsWidth } from "../../util/globals";
import { titleStyles } from "../../globalStyles";
import DataSource from "./data-source";
import Toggle from "./toggle";

const header = (text) => (
<span style={titleStyles.small}>
Expand Down Expand Up @@ -47,7 +46,6 @@ class Controls extends React.Component {
}
return null;
}
// restore <ToggleBranchLabels/> below when perf is improved
render() {
const mapAndTree = this.props.panels !== undefined && this.props.panels.indexOf("map") !== -1 && this.props.panels.indexOf("tree") !== -1;

Expand Down
36 changes: 0 additions & 36 deletions src/components/controls/toggle-branch-labels.js

This file was deleted.

6 changes: 3 additions & 3 deletions src/components/info/info.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import { connect } from "react-redux";
import Card from "../framework/card";
import computeResponsive from "../../util/computeResponsive";
import { titleFont, headerFont, medGrey, darkGrey } from "../../globalStyles";
import { applyFilter, changeDateFilter } from "../../actions/treeProperties";
import { applyFilter, changeDateFilter, updateVisibleTipsAndBranchThicknesses } from "../../actions/treeProperties";
import { prettyString } from "../../util/stringHelpers";
import { displayFilterValueAsButton } from "../framework/footer";
import { CHANGE_TREE_ROOT_IDX } from "../../actions/types";
// import { CHANGE_TREE_ROOT_IDX } from "../../actions/types";

const resetTreeButton = (dispatch) => {
return (
<div
className={`boxed-item active-clickable`}
style={{paddingLeft: '5px', paddingRight: '5px', display: "inline-block"}}
onClick={() => dispatch({type: CHANGE_TREE_ROOT_IDX, idxOfInViewRootNode: 0})}
onClick={() => dispatch(updateVisibleTipsAndBranchThicknesses({idxOfInViewRootNode: 0}))}
>
{"View entire tree."}
</div>
Expand Down
Loading