diff --git a/src/components/download/downloadButtons.js b/src/components/download/downloadButtons.js
index b077016cc..69fa93309 100644
--- a/src/components/download/downloadButtons.js
+++ b/src/components/download/downloadButtons.js
@@ -10,6 +10,7 @@ import { getNumSelectedTips } from "../../util/treeVisibilityHelpers";
const RectangularTreeIcon = withTheme(icons.RectangularTree);
const PanelsGridIcon = withTheme(icons.PanelsGrid);
const MetaIcon = withTheme(icons.Meta);
+const DatasetIcon = withTheme(icons.Dataset);
const iconWidth = 25;
/**
@@ -47,6 +48,14 @@ export const DownloadButtons = ({dispatch, t, tree, entropy, metadata, colorBy,
{partialData ? `Currently ${selectedTipsCount}/${totalTipCount} tips are displayed and will be downloaded.` : `Currently the entire dataset (${totalTipCount} tips) will be downloaded.`}
+ {!gisaidProvenance && (
+ }
+ onClick={() => helpers.auspiceJSON(dispatch)}
+ />
+ )}
{
return (
@@ -56,7 +57,8 @@ const MIME = {
text: "text/plain;charset=utf-8;",
csv: 'text/csv;charset=utf-8;',
tsv: `text/tab-separated-values;charset=utf-8;`,
- svg: "image/svg+xml;charset=utf-8"
+ svg: "image/svg+xml;charset=utf-8",
+ json: "application/json",
};
const treeToNexus = (tree, colorings, colorBy, temporal) => {
@@ -616,3 +618,33 @@ export const entropyTSV = (dispatch, filePrefix, entropy) => {
write(filename, MIME.tsv, createTsvString(objectsToWrite, headerFields));
dispatch(infoNotification({message: `Diversity data exported to ${filename}`}));
};
+
+
+/**
+ * Write out Auspice JSON(s) for the current view. We do this by re-fetching the original
+ * JSON because we don't keep a copy of the unprocessed data around.
+ *
+ * Sidecar files are not fetched, but we can also download them if desired.
+ *
+ * Note that we are not viewing a narrative, as the download button functionality is disabled
+ * for narratives.
+ */
+export const auspiceJSON = (dispatch) => {
+ const filenames = [];
+ for (const datasetName of getDatasetNamesFromUrl(window.location.pathname)) {
+ if (!datasetName) continue; // e.g. no 2nd tree
+ const filename = datasetName.replace('/', '_') + '.json';
+ filenames.push(filename);
+ const dataset = new Dataset(datasetName);
+ dataset.fetchMain(); // initialises dataset.main (a promise)
+ dataset.main.then((jsonContents) => {
+ write(filename, MIME.json, JSON.stringify(jsonContents));
+ }).catch((err) => {
+ // I think this error path should be rarely (never!) encountered, because the fetch call has
+ // worked to load the dataset in the first place...
+ console.error(`Error fetching JSON for ${datasetName}: ${err}`);
+ dispatch(errorNotification({message: `Error preparing ${filename} JSON for download (see console for more info)`}));
+ });
+ }
+ dispatch(infoNotification({message: `Preparing Auspice JSON(s) for download: ${filenames.join(', ')}`}));
+};
\ No newline at end of file
diff --git a/src/components/framework/svg-icons.js b/src/components/framework/svg-icons.js
index 90c552080..4a5815b3e 100644
--- a/src/components/framework/svg-icons.js
+++ b/src/components/framework/svg-icons.js
@@ -150,3 +150,20 @@ export const PanelsFull = ({theme, selected, width}) => {
);
};
+
+
+export const Dataset = ({theme, selected, width}) => {
+ const stroke = selected ? theme.selectedColor : theme.unselectedColor;
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+};