Skip to content

Commit

Permalink
nextstrain#1055: add descriptions with counts to the modal (not style…
Browse files Browse the repository at this point in the history
…d yet)
  • Loading branch information
frogsquire committed Apr 15, 2020
1 parent 8dc30f0 commit 671c9b6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 19 deletions.
65 changes: 48 additions & 17 deletions src/components/download/downloadModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { stopProp } from "../tree/infoPanels/click";
import * as helpers from "./helperFunctions";
import * as icons from "../framework/svg-icons";
import { getAcknowledgments} from "../framework/footer";
import { createSummary } from "../info/info";
import { createSummary, getNumSelectedTips } from "../info/info";
import { getFullAuthorInfoFromNode } from "../../util/treeMiscHelpers";

const RectangularTreeIcon = withTheme(icons.RectangularTree);
const PanelsGridIcon = withTheme(icons.PanelsGrid);
Expand Down Expand Up @@ -156,34 +157,64 @@ class DownloadModal extends React.Component {
});
return x;
}

getNumUniqueAuthors(nodes) {
const authors = nodes.map(n => getFullAuthorInfoFromNode(n))
.filter(a => a && a.value);
const uniqueAuthors = new Set(authors.map(a => a.value));
return uniqueAuthors.size;
}
downloadButtons() {
// getNumSelectedTips() is redundant work with createSummaryWrapper() below,
// and with the check done to make sure the node is visible in strainTSV(),
// so if speed becomes a concern, could alter this to just generate the list of selected nodes once,
// on modal creation, and add it as a property on the modal
const selectedTipsCount = getNumSelectedTips(this.props.nodes, this.props.tree.visibility);
// likewise, this is somewhat redundant with authorTSV()
const uniqueAuthorCount = this.getNumUniqueAuthors(this.props.nodes);
const filePrefix = this.getFilePrefix();
const iconWidth = 25;
const buttons = [
["Tree (newick)", (<RectangularTreeIcon width={iconWidth} selected />), () => helpers.newick(this.props.dispatch, filePrefix, this.props.nodes[0], false)],
["TimeTree (newick)", (<RectangularTreeIcon width={iconWidth} selected />), () => helpers.newick(this.props.dispatch, filePrefix, this.props.nodes[0], true)],
["All Metadata (TSV)", (<MetaIcon width={iconWidth} selected />), () => helpers.strainTSV(this.props.dispatch, filePrefix, this.props.nodes, this.props.metadata.colorings, false, null)],
["Selected Metadata (TSV)", (<MetaIcon width={iconWidth} selected />), () => helpers.strainTSV(this.props.dispatch, filePrefix, this.props.nodes, this.props.metadata.colorings, true, this.props.tree.visibility)]
["Tree", "Phylogenetic tree in Newick format with branch lengths in units of divergence.",
(<RectangularTreeIcon width={iconWidth} selected />), () => helpers.newick(this.props.dispatch, filePrefix, this.props.nodes[0], false)],
["TimeTree", "Phylogenetic tree in Newick format with branch lengths measured in years.",
(<RectangularTreeIcon width={iconWidth} selected />), () => helpers.newick(this.props.dispatch, filePrefix, this.props.nodes[0], true)],
["All Metadata (TSV)", `Per-sample metadata for all samples in the dataset (n = ${this.props.metadata.mainTreeNumTips}).`,
(<MetaIcon width={iconWidth} selected />), () => helpers.strainTSV(this.props.dispatch, filePrefix, this.props.nodes, this.props.metadata.colorings, false, null)],
["Selected Metadata (TSV)", `Per-sample metadata for strains which are currently displayed (n = ${selectedTipsCount}/${this.props.metadata.mainTreeNumTips}).`,
(<MetaIcon width={iconWidth} selected />), () => helpers.strainTSV(this.props.dispatch, filePrefix, this.props.nodes,
this.props.metadata.colorings, true, this.props.tree.visibility)]
];
if (helpers.areAuthorsPresent(this.props.tree)) {
buttons.push(["Author Metadata (TSV)", (<MetaIcon width={iconWidth} selected />), () => helpers.authorTSV(this.props.dispatch, filePrefix, this.props.tree)]);
buttons.push(["Author Metadata (TSV)", `Metadata for all samples in the dataset (n = ${this.props.metadata.mainTreeNumTips}) grouped by the ${uniqueAuthorCount} authors.`,
(<MetaIcon width={iconWidth} selected />), () => helpers.authorTSV(this.props.dispatch, filePrefix, this.props.tree)]);
}
buttons.push(
["Screenshot (SVG)", (<PanelsGridIcon width={iconWidth} selected />), () => helpers.SVG(this.props.dispatch, filePrefix, this.props.panelsToDisplay, this.props.panelLayout, this.makeTextStringsForSVGExport())]
["Screenshot (SVG)", "Screenshot of the current nextstrain display in SVG format.",
(<PanelsGridIcon width={iconWidth} selected />), () => helpers.SVG(this.props.dispatch, filePrefix, this.props.panelsToDisplay, this.props.panelLayout, this.makeTextStringsForSVGExport())]
);
const buttonTextStyle = Object.assign({}, materialButton, {backgroundColor: "rgba(0,0,0,0)", paddingLeft: "10px", color: "white"});
// const buttonLabelStyle = Object.assign({}, )
return (
<div style={{display: "flex", flexWrap: "wrap", justifyContent: "space-around"}}>
{buttons.map((data) => (
<div key={data[0]} onClick={data[2]} style={{cursor: 'pointer'}}>
{data[1]}
<button style={buttonTextStyle}>
{data[0]}
</button>
</div>
))}
<div style={{display: "block", justifyContent: "space-around", marginLeft: "25px"}}>
<div style={{float: "left", width: "25%"}}>
{buttons.map((data) => (
<div key={data[0]} onClick={data[3]} style={{cursor: 'pointer'}}>
{data[2]}
<button style={buttonTextStyle}>
{data[0]}
</button>
</div>
))}
</div>
<div style={{float: "right", width: "75%"}}>
{buttons.map((data) => ( // todo: multiple keys?
<div key={data[0]}>
<label>{data[1]}</label>
</div>
))}
</div>
</div>

);
}
dismissModal() {
Expand Down
1 change: 0 additions & 1 deletion src/components/download/helperFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { spaceBetweenTrees } from "../tree/tree";
import { getTraitFromNode, getDivFromNode, getFullAuthorInfoFromNode, getVaccineFromNode, getAccessionFromNode } from "../../util/treeMiscHelpers";
import { numericToCalendar } from "../../util/dateHelpers";
import { NODE_VISIBLE } from "../../util/globals";
import { calcVisiblity } from "../../util/treeVisibilityHelpers";

export const isPaperURLValid = (d) => {
return (
Expand Down
3 changes: 2 additions & 1 deletion src/components/info/info.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ const styliseDateRange = (date) => {
return dateStr;
};

const getNumSelectedTips = (nodes, visibility) => {
export const getNumSelectedTips = (nodes, visibility) => {
let count = 0;
nodes.forEach((d, idx) => {
// todo: should this include nodes which are not inView?
if (!d.hasChildren && visibility[idx] === NODE_VISIBLE) count += 1;
});
return count;
Expand Down

0 comments on commit 671c9b6

Please sign in to comment.