([
['relatives', ChartType.Relatives],
['fancy', ChartType.Fancy],
]);
// Hourglass is the default view.
const chartType = chartTypes.get(view) || ChartType.Hourglass;
const gedcom = this.props.location.state && this.props.location.state.data;
const images =
this.props.location.state && this.props.location.state.images;
if (!url && !hash && !source) {
this.props.history.replace({pathname: '/'});
} else if (this.isNewData(hash, url, gedcom, source)) {
try {
// Set loading state.
this.setState(
Object.assign({}, this.state, {
data: undefined,
selection: undefined,
hash,
error: undefined,
loading: true,
url,
standalone,
chartType,
wikiTreeSource: source === 'wikitree',
}),
);
const data =
source === 'wikitree'
? await loadWikiTree(indi!, authcode)
: hash
? await loadGedcom(hash, gedcom, images)
: await loadFromUrl(url!, handleCors);
const software = getSoftware(data.gedcom.head);
if (source === 'wikitree') {
analyticsEvent('wikitree_loaded');
} else {
analyticsEvent(hash ? 'upload_file_loaded' : 'url_file_loaded', {
event_label: software,
event_value: (images && images.size) || 0,
});
}
// Set state with data.
this.setState(
Object.assign({}, this.state, {
data,
hash,
selection: getSelection(data.chartData, indi, generation),
error: undefined,
loading: false,
url,
showSidePanel,
standalone,
chartType,
wikiTreeSource: source === 'wikitree',
}),
);
} catch (error) {
analyticsEvent(hash ? 'upload_file_error' : 'url_file_error');
this.setError(error.message);
}
} else if (this.state.data && this.state.selection) {
// Update selection if it has changed in the URL.
const selection = getSelection(
this.state.data.chartData,
indi,
generation,
);
const loadMoreFromWikitree =
source === 'wikitree' &&
(!this.state.selection || this.state.selection.id !== selection.id);
this.updateDisplay(selection, {
chartType,
loadingMore: loadMoreFromWikitree || undefined,
});
if (loadMoreFromWikitree) {
const data = await loadWikiTree(indi!);
this.setState(
Object.assign({}, this.state, {
data,
hash,
selection: getSelection(data.chartData, indi, generation),
error: undefined,
loading: false,
url,
showSidePanel,
standalone,
chartType,
wikiTreeSource: source === 'wikitree',
loadingMore: false,
}),
);
}
}
}
/**
* Called when the user clicks an individual box in the chart.
* Updates the browser URL.
*/
private onSelection = (selection: IndiInfo) => {
analyticsEvent('selection_changed');
if (this.state.embedded) {
// In embedded mode the URL doesn't change.
this.updateDisplay(selection);
return;
}
const location = this.props.location;
const search = queryString.parse(location.search);
search.indi = selection.id;
search.gen = String(selection.generation);
location.search = queryString.stringify(search);
this.props.history.push(location);
};
private onPrint = () => {
analyticsEvent('print');
this.chartRef && this.chartRef.print();
};
private showErrorPopup(message: string) {
this.setState(
Object.assign({}, this.state, {
showErrorPopup: true,
error: message,
}),
);
}
private onDownloadPdf = async () => {
analyticsEvent('download_pdf');
try {
this.chartRef && (await this.chartRef.downloadPdf());
} catch (e) {
this.showErrorPopup(
this.context.intl.formatMessage({
id: 'error.failed_pdf',
defaultMessage:
'Failed to generate PDF file.' +
' Please try with a smaller diagram or download an SVG file.',
}),
);
}
};
private onDownloadPng = async () => {
analyticsEvent('download_png');
try {
this.chartRef && (await this.chartRef.downloadPng());
} catch (e) {
this.showErrorPopup(
this.context.intl.formatMessage({
id: 'error.failed_png',
defaultMessage:
'Failed to generate PNG file.' +
' Please try with a smaller diagram or download an SVG file.',
}),
);
}
};
private onDownloadSvg = () => {
analyticsEvent('download_svg');
this.chartRef && this.chartRef.downloadSvg();
};
onDismissErrorPopup = () => {
this.setState(
Object.assign({}, this.state, {
showErrorPopup: false,
}),
);
};
private renderMainArea = () => {
if (this.state.data && this.state.selection) {
return (
{this.state.loadingMore ? (
) : null}
(this.chartRef = ref)}
/>
{this.state.showSidePanel ? (
) : null}
);
}
if (this.state.error) {
return ;
}
return ;
};
render() {
return (
<>
(
)}
/>
>
);
}
}