Skip to content

Commit

Permalink
Merge pull request #1046 from eharkins/522-url-conf-intervals
Browse files Browse the repository at this point in the history
522 Add conf intervals to URL query string
  • Loading branch information
jameshadfield authored Apr 19, 2020
2 parents 8f63963 + ef4a3e7 commit 3ab7754
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 47 deletions.
1 change: 1 addition & 0 deletions docs-src/docs/advanced-functionality/view-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ All URL queries modify the view away from the default settings -- if you change
| `sidebar` | Force the sidebar into a certain state | `sidebar=closed` or `sidebar=open` |
| `legend` | Force the legend into a certain state | `legend=closed` or `legend=open` |
| `onlyPanels` | Do not display the footer / header. Useful for iframes. | `onlyPanels` |
| `ci` | Display confidence intervals on the tree. | `ci` |

**See this in action:**

Expand Down
22 changes: 12 additions & 10 deletions src/actions/recomputeReduxState.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { calcBrowserDimensionsInitialState } from "../reducers/browserDimensions
import { strainNameToIdx, getIdxMatchingLabel, calculateVisiblityAndBranchThickness } from "../util/treeVisibilityHelpers";
import { constructVisibleTipLookupBetweenTrees } from "../util/treeTangleHelpers";
import { calcTipRadii } from "../util/tipRadiusHelpers";
import { getDefaultControlsState } from "../reducers/controls";
import { getDefaultControlsState, shouldDisplayTemporalConfidence } from "../reducers/controls";
import { countTraitsAcrossTree, calcTotalTipsInTree } from "../util/treeCountingHelpers";
import { calcEntropyInView } from "../util/entropy";
import { treeJsonToState } from "../util/treeJsonProcessing";
Expand Down Expand Up @@ -44,7 +44,6 @@ export const getMaxCalDateViaTree = (nodes) => {

/* need a (better) way to keep the queryParams all in "sync" */
const modifyStateViaURLQuery = (state, query) => {
// console.log("Query incoming: ", query);
if (query.l) {
state["layout"] = query.l;
}
Expand All @@ -60,6 +59,11 @@ const modifyStateViaURLQuery = (state, query) => {
if (query.c) {
state["colorBy"] = query.c;
}
if (query.ci === undefined) {
state["temporalConfidence"]["on"] = false;
} else {
state["temporalConfidence"]["on"] = true;
}
if (query.r) {
state["geoResolution"] = query.r;
}
Expand Down Expand Up @@ -460,14 +464,12 @@ const checkAndCorrectErrorsInState = (state, metadata, query, tree, viewingNarra
}

/* temporalConfidence */
if (state.temporalConfidence.exists) {
if (state.layout !== "rect") {
state.temporalConfidence.display = false;
state.temporalConfidence.on = false;
} else if (state.distanceMeasure === "div") {
state.temporalConfidence.display = false;
state.temporalConfidence.on = false;
}
if (shouldDisplayTemporalConfidence(state.temporalConfidence.exists, state.distanceMeasure, state.layout)) {
state.temporalConfidence.display = true;
} else {
state.temporalConfidence.display = false;
state.temporalConfidence.on = false;
delete query.ci; // rm ci from the query if it doesn't apply
}

/* if colorBy is a genotype then we need to set mutType */
Expand Down
9 changes: 7 additions & 2 deletions src/components/tree/phyloTree/change.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { applyToChildren } from "./helpers";
import { timerStart, timerEnd } from "../../../util/perf";
import { NODE_VISIBLE } from "../../../util/globals";
import { getBranchVisibility, strokeForBranch } from "./renderers";
import { shouldDisplayTemporalConfidence } from "../../../reducers/controls";

/* loop through the nodes and update each provided prop with the new value
* additionally, set d.update -> whether or not the node props changed
Expand Down Expand Up @@ -182,7 +183,7 @@ export const modifySVG = function modifySVG(elemsToUpdate, svgPropsToUpdate, tra
} else if (extras.showConfidences && !this.confidencesInSVG) {
this.drawConfidence(); /* see comment above */
} else if (elemsToUpdate.has(".conf") && this.confidencesInSVG) {
if (this.layout === "rect" && this.distance === "num_date") {
if (shouldDisplayTemporalConfidence(true, this.distance, this.layout)) {
updateCall = createUpdateCall(".conf", svgPropsToUpdate);
genericSelectAndModify(this.svg, ".conf", updateCall, transitionTime);
} else {
Expand Down Expand Up @@ -353,14 +354,18 @@ export const change = function change({
if (newDistance) this.setDistance(newDistance);
/* layout (must run after distance) */
if (newDistance || newLayout || updateLayout) this.setLayout(newLayout || this.layout);
/* show confidences - set this param which actually adds the svg paths for
confidence intervals when mapToScreen() gets called below */
if (showConfidences) this.params.confidence = true;
/* mapToScreen */
if (
svgPropsToUpdate.has(["stroke-width"]) ||
newDistance ||
newLayout ||
updateLayout ||
zoomIntoClade ||
svgHasChangedDimensions
svgHasChangedDimensions ||
showConfidences
) {
this.mapToScreen();
}
Expand Down
11 changes: 7 additions & 4 deletions src/components/tree/reactD3Interface/change.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,15 @@ export const changePhyloTreeViaPropsComparison = (mainTree, phylotree, oldProps,
}


/* confidence intervals (on means in the SVG, display means shown in the sidebar) */
if (oldProps.temporalConfidence.display === true && newProps.temporalConfidence.display === false) {
/* confidence intervals (on means in the SVG, display means shown in the sidebar)
This block used to include comparisons of oldProps to newProps. See:
https://github.com/nextstrain/auspice/commit/0713e69b0707c92df806a575796e7205f08332ff
for an explanation of why it no longer does. */
if (newProps.temporalConfidence.display === false) {
args.removeConfidences = true;
} else if (oldProps.temporalConfidence.on === true && newProps.temporalConfidence.on === false) {
} else if (newProps.temporalConfidence.on === false) {
args.removeConfidences = true;
} else if (newProps.temporalConfidence.display === true && oldProps.temporalConfidence.on === false && newProps.temporalConfidence.on === true) {
} else if (newProps.temporalConfidence.display === true && newProps.temporalConfidence.on === true) {
args.showConfidences = true;
}

Expand Down
16 changes: 15 additions & 1 deletion src/middleware/changeURL.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import queryString from "query-string";
import * as types from "../actions/types";
import { numericToCalendar } from "../util/dateHelpers";

import { shouldDisplayTemporalConfidence } from "../reducers/controls";

/**
* This middleware acts to keep the app state and the URL query state in sync by
Expand Down Expand Up @@ -52,12 +52,23 @@ export const changeURLMiddleware = (store) => (next) => (action) => {
case types.NEW_COLORS:
query.c = action.colorBy === state.controls.defaults.colorBy ? undefined : action.colorBy;
break;
case types.TOGGLE_TEMPORAL_CONF:
if ("ci" in query) {
query.ci = undefined;
} else {
// We have to use null here to put "ci" in the query without an "=" after it and a value, i.e. to treat it as a boolean without having "=true"
query.ci = null;
}
break;
case types.APPLY_FILTER: {
query[`f_${action.trait}`] = action.values.join(',');
break;
}
case types.CHANGE_LAYOUT: {
query.l = action.data === state.controls.defaults.layout ? undefined : action.data;
if (!shouldDisplayTemporalConfidence(state.controls.temporalConfidence.exists, state.controls.distanceMeasure, query.l)) {
query.ci = undefined;
}
break;
}
case types.CHANGE_GEO_RESOLUTION: {
Expand All @@ -70,6 +81,9 @@ export const changeURLMiddleware = (store) => (next) => (action) => {
}
case types.CHANGE_DISTANCE_MEASURE: {
query.m = action.data === state.controls.defaults.distanceMeasure ? undefined : action.data;
if (!shouldDisplayTemporalConfidence(state.controls.temporalConfidence.exists, query.m, state.controls.layout)) {
query.ci = undefined;
}
break;
}
case types.CHANGE_PANEL_LAYOUT: {
Expand Down
47 changes: 17 additions & 30 deletions src/reducers/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ export const getDefaultControlsState = () => {
};
};

/* while this may change, div currently doesn't have CIs, so they shouldn't be displayed. */
export const shouldDisplayTemporalConfidence = (exists, distMeasure, layout) => exists && distMeasure === "num_date" && layout === "rect";

const Controls = (state = getDefaultControlsState(), action) => {
switch (action.type) {
case types.URL_QUERY_CHANGE_WITH_COMPUTED_STATE: /* fallthrough */
Expand All @@ -110,41 +113,25 @@ const Controls = (state = getDefaultControlsState(), action) => {
});
case types.CHANGE_BRANCH_LABEL:
return Object.assign({}, state, {selectedBranchLabel: action.value});
case types.CHANGE_LAYOUT: {
const layout = action.data;
/* temporal confidence can only be displayed for rectangular trees */
const temporalConfidence = {
exists: state.temporalConfidence.exists,
display: state.temporalConfidence.exists && layout === "rect",
on: false
};
case types.CHANGE_LAYOUT:
return Object.assign({}, state, {
layout,
temporalConfidence
layout: action.data,
/* temporal confidence can only be displayed for rectangular trees */
temporalConfidence: Object.assign({}, state.temporalConfidence, {
display: shouldDisplayTemporalConfidence(state.temporalConfidence.exists, state.distanceMeasure, action.data),
on: false})
});
}
case types.CHANGE_DISTANCE_MEASURE:
/* while this may change, div currently doesn't have CIs,
so they shouldn't be displayed. */
if (state.temporalConfidence.exists) {
if (state.temporalConfidence.display && action.data === "div") {
return Object.assign({}, state, {
distanceMeasure: action.data,
branchLengthsToDisplay: state.branchLengthsToDisplay,
temporalConfidence: Object.assign({}, state.temporalConfidence, {display: false, on: false})
});
} else if (state.layout === "rect" && action.data === "num_date") {
return Object.assign({}, state, {
distanceMeasure: action.data,
branchLengthsToDisplay: state.branchLengthsToDisplay,
temporalConfidence: Object.assign({}, state.temporalConfidence, {display: true})
});
}
}
return Object.assign({}, state, {
const updatesToState = {
distanceMeasure: action.data,
branchLengthsToDisplay: state.branchLengthsToDisplay
});
};
if (shouldDisplayTemporalConfidence(state.temporalConfidence.exists, action.data, state.layout)) {
updatesToState.temporalConfidence = Object.assign({}, state.temporalConfidence, {display: true});
} else {
updatesToState.temporalConfidence = Object.assign({}, state.temporalConfidence, {display: false, on: false});
}
return Object.assign({}, state, updatesToState);
case types.CHANGE_DATES_VISIBILITY_THICKNESS: {
const newDates = {quickdraw: action.quickdraw};
if (action.dateMin) {
Expand Down

0 comments on commit 3ab7754

Please sign in to comment.