diff --git a/src/actions/types.js b/src/actions/types.js index 84524c336..a617c47f7 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -61,3 +61,4 @@ export const TOGGLE_MEASUREMENTS_OVERALL_MEAN = "TOGGLE_MEASUREMENTS_OVERALL_MEA export const CHANGE_MEASUREMENTS_DISPLAY = "CHANGE_MEASUREMENTS_DISPLAY"; export const APPLY_MEASUREMENTS_FILTER = "APPLY_MEASUREMENTS_FILTER"; export const UPDATE_MEASUREMENTS_ERROR = "UPDATE_MEASUREMENTS_ERROR"; +export const TOGGLE_SHOW_ALL_BRANCH_LABELS = "TOGGLE_SHOW_ALL_BRANCH_LABELS"; diff --git a/src/components/controls/choose-branch-labelling.js b/src/components/controls/choose-branch-labelling.js index 1c2dbff55..0c7fdc9ba 100644 --- a/src/components/controls/choose-branch-labelling.js +++ b/src/components/controls/choose-branch-labelling.js @@ -2,13 +2,15 @@ import React from "react"; import { connect } from "react-redux"; import { withTranslation } from 'react-i18next'; -import { CHANGE_BRANCH_LABEL } from "../../actions/types"; +import { CHANGE_BRANCH_LABEL, TOGGLE_SHOW_ALL_BRANCH_LABELS } from "../../actions/types"; import { SidebarSubtitle } from "./styles"; import { controlsWidth } from "../../util/globals"; import CustomSelect from "./customSelect"; +import Toggle from "./toggle"; @connect((state) => ({ selected: state.controls.selectedBranchLabel, + showAll: state.controls.showAllBranchLabels, available: state.tree.availableBranchLabels, canRenderBranchLabels: state.controls.canRenderBranchLabels })) @@ -36,6 +38,16 @@ class ChooseBranchLabelling extends React.Component { onChange={this.change} /> + + {this.props.selected!=="none" && ( + this.props.dispatch({type: TOGGLE_SHOW_ALL_BRANCH_LABELS})} + label={t("sidebar:Show all labels")} + style={{paddingBottom: "5px", paddingTop: "10px"}} + /> + )} ); } diff --git a/src/components/tree/index.js b/src/components/tree/index.js index bb4f54e73..0ba76de27 100644 --- a/src/components/tree/index.js +++ b/src/components/tree/index.js @@ -22,6 +22,7 @@ const Tree = connect((state) => ({ panelsToDisplay: state.controls.panelsToDisplay, selectedBranchLabel: state.controls.selectedBranchLabel, canRenderBranchLabels: state.controls.canRenderBranchLabels, + showAllBranchLabels: state.controls.showAllBranchLabels, tipLabelKey: state.controls.tipLabelKey, narrativeMode: state.narrative.display, animationPlayPauseButton: state.controls.animationPlayPauseButton diff --git a/src/components/tree/phyloTree/change.js b/src/components/tree/phyloTree/change.js index f749f105f..2465a8cbc 100644 --- a/src/components/tree/phyloTree/change.js +++ b/src/components/tree/phyloTree/change.js @@ -260,6 +260,7 @@ export const change = function change({ newLayout = undefined, updateLayout = undefined, // todo - this seems identical to `newLayout` newBranchLabellingKey = undefined, + showAllBranchLabels = undefined, newTipLabelKey = undefined, /* arrays of data (the same length as nodes) */ branchStroke = undefined, @@ -365,6 +366,11 @@ export const change = function change({ /* 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; + /* keep the state of phylotree in sync with redux (more complex than it should be) */ + if (showAllBranchLabels!==undefined) { + this.params.showAllBranchLabels=showAllBranchLabels; + elemsToUpdate.add('.branchLabel'); + } /* mapToScreen */ if ( svgPropsToUpdate.has(["stroke-width"]) || diff --git a/src/components/tree/phyloTree/labels.js b/src/components/tree/phyloTree/labels.js index 23773ceb7..f04ead7e8 100644 --- a/src/components/tree/phyloTree/labels.js +++ b/src/components/tree/phyloTree/labels.js @@ -70,13 +70,15 @@ const branchLabelFontWeight = (key) => { /** createBranchLabelVisibility (the return value should be passed to d3 style call) * @param {str} key e.g. "aa" or "clade" + * @param {bool} showAll * @param {str} layout * @param {int} totalTipsInView visible tips also in view * @return {func} Returns a function with 1 argument: the current node (branch). * This fn will return "visible" or "hidden". * NOTE: the fn should only be provided nodes which have a label. */ -const createBranchLabelVisibility = (key, layout, totalTipsInView) => (d) => { +const createBranchLabelVisibility = (key, showAll, layout, totalTipsInView) => (d) => { + if (showAll) return "visible"; if (d.visibility !== NODE_VISIBLE) return "hidden"; const magicTipFractionToShowBranchLabel = 0.03; /* if the number of _visible_ tips descending from this node are over the @@ -99,6 +101,7 @@ export const updateBranchLabels = function updateBranchLabels(dt) { } const visibility = createBranchLabelVisibility( this.params.branchLabelKey, + this.params.showAllBranchLabels, this.layout, this.zoomNode.n.tipCount ); @@ -128,7 +131,7 @@ export const drawBranchLabels = function drawBranchLabels(key) { this.params.branchLabelKey = key; const labelSize = branchLabelSize(key); const fontWeight = branchLabelFontWeight(key); - const visibility = createBranchLabelVisibility(key, this.layout, this.zoomNode.n.tipCount); + const visibility = createBranchLabelVisibility(key, this.params.showAllBranchLabels, this.layout, this.zoomNode.n.tipCount); if (!("branchLabels" in this.groups)) { this.groups.branchLabels = this.svg.append("g").attr("id", "branchLabels").attr("clip-path", "url(#treeClip)"); diff --git a/src/components/tree/reactD3Interface/change.js b/src/components/tree/reactD3Interface/change.js index 076d01254..cc5c72d35 100644 --- a/src/components/tree/reactD3Interface/change.js +++ b/src/components/tree/reactD3Interface/change.js @@ -64,6 +64,10 @@ export const changePhyloTreeViaPropsComparison = (mainTree, phylotree, oldProps, ) { args.newBranchLabellingKey = newProps.selectedBranchLabel; } + if (oldProps.showAllBranchLabels!==newProps.showAllBranchLabels) { + args.showAllBranchLabels = newProps.showAllBranchLabels; + } + if (oldProps.tipLabelKey !== newProps.tipLabelKey) { args.newTipLabelKey = newProps.tipLabelKey; } diff --git a/src/components/tree/reactD3Interface/initialRender.js b/src/components/tree/reactD3Interface/initialRender.js index 38ea89c2c..3ee32a1cd 100644 --- a/src/components/tree/reactD3Interface/initialRender.js +++ b/src/components/tree/reactD3Interface/initialRender.js @@ -25,6 +25,7 @@ export const renderTree = (that, main, phylotree, props) => { grid: true, confidence: props.temporalConfidence.display, branchLabelKey: renderBranchLabels && props.selectedBranchLabel, + showAllBranchLabels: props.showAllBranchLabels, orientation: main ? [1, 1] : [-1, 1], tipLabels: true, showTipLabels: true diff --git a/src/reducers/controls.js b/src/reducers/controls.js index 3e741c0fd..794b87cd3 100644 --- a/src/reducers/controls.js +++ b/src/reducers/controls.js @@ -65,6 +65,7 @@ export const getDefaultControlsState = () => { colorScale: undefined, explodeAttr: undefined, selectedBranchLabel: "none", + showAllBranchLabels: false, canRenderBranchLabels: true, analysisSlider: false, geoResolution: defaults.geoResolution, @@ -125,6 +126,8 @@ const Controls = (state = getDefaultControlsState(), action) => { }); case types.CHANGE_BRANCH_LABEL: return Object.assign({}, state, { selectedBranchLabel: action.value }); + case types.TOGGLE_SHOW_ALL_BRANCH_LABELS: + return Object.assign({}, state, { showAllBranchLabels: !state.showAllBranchLabels }); case types.CHANGE_LAYOUT: return Object.assign({}, state, { layout: action.layout,