Added 'print' button to print the current chart

This commit is contained in:
Przemek Wiech 2019-02-21 22:38:22 +01:00
parent 61b65eb1ac
commit a920147ba8
5 changed files with 70 additions and 5 deletions

View File

@ -133,4 +133,27 @@ export class Chart extends React.PureComponent<ChartProps, {}> {
</div>
);
}
/** Shows the print dialog to print the currently displayed chart. */
print() {
const printWindow = document.createElement('iframe');
printWindow.style.position = 'absolute';
printWindow.style.top = '-1000px';
printWindow.style.left = '-1000px';
printWindow.onload = () => {
const svg = document.getElementById('chart')!.cloneNode(true) as Element;
svg.removeAttribute('transform');
const contents = svg.outerHTML;
printWindow.contentDocument!.open();
printWindow.contentDocument!.write(contents);
printWindow.contentDocument!.close();
// Doesn't work on Firefox without the setTimeout.
setTimeout(() => {
printWindow.contentWindow!.focus();
printWindow.contentWindow!.print();
printWindow.parentNode!.removeChild(printWindow);
}, 500);
};
document.body.appendChild(printWindow);
}
}

View File

@ -50,6 +50,7 @@ interface State {
/** The main area of the application dedicated for rendering the family chart. */
export class ChartView extends React.Component<RouteComponentProps, State> {
state: State = {loading: false};
chartRef: Chart | null = null;
/**
* Called when the user clicks an individual box in the chart.
@ -102,7 +103,8 @@ export class ChartView extends React.Component<RouteComponentProps, State> {
? 'https://cors-anywhere.herokuapp.com/' + url
: url;
window.fetch(urlToFetch)
window
.fetch(urlToFetch)
.then((response) => {
if (response.status !== 200) {
return Promise.reject(new Error(response.statusText));
@ -237,6 +239,7 @@ export class ChartView extends React.Component<RouteComponentProps, State> {
data={this.state.data}
onSelection={this.onSelection}
selection={this.state.selection}
ref={(ref) => (this.chartRef = ref)}
/>
);
}
@ -245,4 +248,11 @@ export class ChartView extends React.Component<RouteComponentProps, State> {
}
return <Loader active size="large" />;
}
/** Shows the print dialog to print the currently displayed chart. */
print() {
if (this.chartRef) {
this.chartRef.print();
}
}
}

View File

@ -6,7 +6,12 @@ import messages_pl from './translations/pl.json';
import {addLocaleData} from 'react-intl';
import {detect} from 'detect-browser';
import {ChartView} from './chart_view';
import {HashRouter as Router, Route, Switch} from 'react-router-dom';
import {
HashRouter as Router,
Route,
RouteComponentProps,
Switch,
} from 'react-router-dom';
import {IntlProvider} from 'react-intl';
import {Intro} from './intro';
import {TopBar} from './top_bar';
@ -22,6 +27,8 @@ const language = navigator.language && navigator.language.split(/[-_]/)[0];
const browser = detect();
let chartViewRef: ChartView | null = null;
if (browser && browser.name === 'ie') {
ReactDOM.render(
<p>
@ -35,10 +42,23 @@ if (browser && browser.name === 'ie') {
<IntlProvider locale={language} messages={messages[language]}>
<Router>
<div className="root">
<Route component={TopBar} />
<Route
component={(props: RouteComponentProps) => (
<TopBar
{...props}
onPrint={() => chartViewRef && chartViewRef.print()}
/>
)}
/>
<Switch>
<Route exact path="/" component={Intro} />
<Route exact path="/view" component={ChartView} />
<Route
exact
path="/view"
component={(props: RouteComponentProps) => (
<ChartView {...props} ref={(ref) => (chartViewRef = ref)} />
)}
/>
</Switch>
</div>
</Router>

View File

@ -20,7 +20,14 @@ interface State {
url?: string;
}
export class TopBar extends React.Component<RouteComponentProps, State> {
interface Props {
onPrint: () => void;
}
export class TopBar extends React.Component<
RouteComponentProps & Props,
State
> {
state: State = {loadUrlDialogOpen: false};
inputRef?: Input;
@ -164,6 +171,10 @@ export class TopBar extends React.Component<RouteComponentProps, State> {
/>
</Menu.Item>
</label>
<Menu.Item as="a" onClick={() => this.props.onPrint()}>
<Icon name="print" />
<FormattedMessage id="menu.print" defaultMessage="Print" />
</Menu.Item>
<Menu.Item
as="a"
href="https://github.com/PeWu/topola-viewer"

View File

@ -1,6 +1,7 @@
{
"menu.load_from_url": "Otwórz URL",
"menu.load_from_file": "Otwórz plik",
"menu.print": "Drukuj",
"menu.github": "Źródła na GitHub",
"intro.title": "Topola Genealogy",
"intro.description": "Topola Genealogy pozwala przeglądać drzewo genealogiczne w interaktywny sposób.",