Skip to content

Commit

Permalink
[entropy] usability fixes
Browse files Browse the repository at this point in the history
A number of small improvements, many of which were suggested in review.

Added a "help" icon, following the pattern we use extensively in the
sidebar.

Updated the zoom triangle appearance and their cursor icons. Items 1 and
4 in
<#1684 (comment)>

Changed the "return to nuc" button to a "RESET LAYOUT" button which will
always return you to a fully zoomed out view of the genome. See added
comment for why this isn't greyed out when it is a no-op. Item 2 in
<#1684 (comment)>

Changed the panel title to indicate if we're looking at the genome or a
CDS, and add the CDS name to the title in the latter case. Also added a
small axis label indicating that the numbering system is AA for selected
CDSs (it's a bit cluttered to show 'Nt #' as well)
<#1684 (comment)>
  • Loading branch information
jameshadfield committed Aug 17, 2023
1 parent 936adfc commit 2697a02
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 13 deletions.
22 changes: 21 additions & 1 deletion src/components/entropy/entropyD3.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { brushX } from "d3-brush";
import Mousetrap from "mousetrap";
import { darkGrey, infoPanelStyles } from "../../globalStyles";
import { changeZoom } from "../../actions/entropy";
import { nucleotide_gene, equalArrays } from "../../util/globals";
import { nucleotide_gene } from "../../util/globals";
import { getCdsByName, getNucCoordinatesFromAaPos, getCdsRangeLocalFromRangeGenome,
nucleotideToAaPosition} from "../../util/entropy";

Expand Down Expand Up @@ -90,6 +90,9 @@ EntropyChart.prototype.update = function update({
this._setSelectedNodes();
this._highlightSelectedBars();
}
} else if (zoomMin!==undefined || zoomMax!==undefined) {
this._setZoomCoordinates(zoomMin, zoomMax, false);
this._groups.navBrush.call(this.brush.move, () => this.zoomCoordinates.map(this.scales.xNav));
}
}

Expand Down Expand Up @@ -563,6 +566,20 @@ EntropyChart.prototype._drawAxes = function _drawAxes() {
if (visPos > 1e6) { /* axes number differently if large genome */
this.axes.xNav.tickFormat(format(".1e"));
}

/* A hint that the numbering is AA when a CDS is selected */
this._groups.mainXAxis.append("text")
.attr("class", "axisLabel")
.attr("y", 7)
.attr("x", -2)
.attr("pointer-events", "none")
.attr("text-anchor", "end") // horizontal axis
.attr("dominant-baseline", "hanging") // vertical axis
.style("fill", darkGrey)
.style("font-size", '12px')
.text('AA pos')
.style("visibility", this.aa ? "visible": "hidden")

this._groups.mainYAxis.call(this.axes.y);
this._groups.mainXAxis.call(this.axes.xMain);
this._groups.navXAxis.call(this.axes.xNav);
Expand All @@ -589,6 +606,9 @@ EntropyChart.prototype._updateMainScaleAndAxis = function _updateMainScaleAndAxi
this._groups.mainXAxis.call(this.axes.xMain);
}

this._groups.mainXAxis.select(".axisLabel")
.style("visibility", this.aa ? "visible": "hidden")

this.scales.y
.domain([0, yMax])
.range([this.offsets.heightMainBars, 0]);
Expand Down
73 changes: 61 additions & 12 deletions src/components/entropy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { connect } from "react-redux";
import { select } from "d3-selection";
import { withTranslation } from "react-i18next";
import 'd3-transition';
import { FaInfoCircle } from "react-icons/fa";
import Card from "../framework/card";
import { changeColorBy } from "../../actions/colors";
import { tabGroup, tabGroupMember, tabGroupMemberSelected } from "../../globalStyles";
Expand All @@ -14,8 +15,10 @@ import { timerStart, timerEnd } from "../../util/perf";
import { encodeColorByGenotype } from "../../util/getGenotype";
import { nucleotide_gene, equalArrays } from "../../util/globals";
import { getCdsByName } from "../../util/entropy";
import { StyledTooltip } from "../controls/styles";
import "../../css/entropy.css";


const getStyles = (width) => {
return {
switchContainer: {
Expand All @@ -33,17 +36,25 @@ const getStyles = (width) => {
position: "relative",
top: -1
},
goBackToNucleotide: {
resetLayout: {
position: "absolute",
right: 144,
right: 190,
top: 0,
zIndex: 100
},
entropyCountSwitch: {
position: "absolute",
right: 5,
right: 50,
top: 0,
zIndex: 100
},
helpIcon: {
position: "absolute",
right: 25,
top: 3,
fontSize: '16px', // controls icon size
cursor: 'help',
color: '#888'
}
};
};
Expand Down Expand Up @@ -111,19 +122,33 @@ class Entropy extends React.Component {
this.setState({hovered: false});
}

goBackToNucleotide(styles) {
if (this.props.narrativeMode) return null;
if (this.props.selectedCds===nucleotide_gene) return null;
resetLayout(styles) {
if (this.props.narrativeMode || !this.state.chart) return null;
const viewingGenome = this.props.selectedCds===nucleotide_gene;
/**
* The intention for this button is to be inactive when viewing the genome &
* fully zoomed out, however zoom actions do not trigger redux state changes
* which would be necessary for this (see comment in @connect decorator
* above). Once we fix that it is simple to conditionally inactivate this
* button.
*/
return (
<div style={{...tabGroup, ...styles.goBackToNucleotide}}>
<div style={{...tabGroup, ...styles.resetLayout}}>
<button
key={1}
style={tabGroupMember}
onClick={() => {
this.props.dispatch(changeEntropyCdsSelection(nucleotide_gene));
if (viewingGenome) {
this.state.chart.update({
zoomMin: this.state.chart.zoomBounds[0],
zoomMax: this.state.chart.zoomBounds[1],
})
} else {
this.props.dispatch(changeEntropyCdsSelection(nucleotide_gene));
}
}}
>
<span style={styles.switchTitle}> {"⏎ nuc"} </span>
<span style={styles.switchTitle}> {'RESET LAYOUT'} </span>
</button>
</div>
);
Expand Down Expand Up @@ -221,11 +246,18 @@ class Entropy extends React.Component {
}
}

title() {
if (this.props.width<500) return "Diversity";
if (this.props.selectedCds===nucleotide_gene) {
return "Nucleotide diversity of genome"
}
return `Amino acid diversity of CDS ${this.props.selectedCds.name}`
}

render() {
const { t } = this.props;
const styles = getStyles(this.props.width);
return (
<Card title={t("Diversity")}>
<Card title={this.title()}>
<InfoPanel d3event={this.state.hovered.d3event} width={this.props.width} height={this.props.height}>
{this.state.hovered ? this.state.hovered.tooltip(this.props.t) : null}
</InfoPanel>
Expand All @@ -237,8 +269,25 @@ class Entropy extends React.Component {
>
<g ref={(c) => { this.d3entropy = c; }} id="d3entropy"/>
</svg>
{this.goBackToNucleotide(styles)}
{this.resetLayout(styles)}
{this.entropyCountSwitch(styles)}
<span style={styles.helpIcon} data-tip data-for="entropyHelp">
<FaInfoCircle/>
</span>
<StyledTooltip place="left" type="dark" effect="solid" id="entropyHelp" style={{maxWidth: '50vh'}}>
<div>
This panel displays the observed diversity across the current genome or a selected CDS
{` (currently you are viewing ${this.props.selectedCds===nucleotide_gene?'the genome':`CDS ${this.props.selectedCds.name}`}). `}
<p/>
The lower axis shows the genome with +ve strand CDSs above and -ve strand CDSs below and
the grey overlay allows zooming in to a region.
The upper axis shows either the zoomed in region of the genome or a selected CDS;
in the latter case the coordinates represent amino acids.
<p/>
Clicking on a CDS will select it and show it on the upper axis.
{` Clicking "Reset Layout" will always return you to viewing the entire genome.`}
</div>
</StyledTooltip>
</Card>
);
}
Expand Down

0 comments on commit 2697a02

Please sign in to comment.