Remove option to turn off zoom

This commit is contained in:
Przemek Wiech
2020-04-01 18:57:39 +02:00
parent 2276edab08
commit 36dabfc4a1
2 changed files with 39 additions and 56 deletions

View File

@@ -178,7 +178,6 @@ interface Arguments {
chartType: ChartType; chartType: ChartType;
gedcom?: string; gedcom?: string;
images?: Map<string, string>; images?: Map<string, string>;
enableZoom: boolean;
} }
/** /**
@@ -225,7 +224,6 @@ function getArguments(location: H.Location<any>): Arguments {
gedcom: location.state && location.state.data, gedcom: location.state && location.state.data,
images: location.state && location.state.images, images: location.state && location.state.images,
enableZoom: getParam('enableZoom') !== 'false', // True by default.
}; };
} }
@@ -265,8 +263,6 @@ interface State {
/** Source of the data. */ /** Source of the data. */
source?: DataSourceEnum; source?: DataSourceEnum;
loadingMore?: boolean; loadingMore?: boolean;
/** Whether the zoom functionality is enabled. */
enableZoom: boolean;
} }
export class App extends React.Component<RouteComponentProps, {}> { export class App extends React.Component<RouteComponentProps, {}> {
@@ -276,7 +272,6 @@ export class App extends React.Component<RouteComponentProps, {}> {
standalone: true, standalone: true,
chartType: ChartType.Hourglass, chartType: ChartType.Hourglass,
showErrorPopup: false, showErrorPopup: false,
enableZoom: false,
}; };
chartRef: Chart | null = null; chartRef: Chart | null = null;
@@ -392,7 +387,6 @@ export class App extends React.Component<RouteComponentProps, {}> {
standalone: args.standalone, standalone: args.standalone,
chartType: args.chartType, chartType: args.chartType,
source: args.source, source: args.source,
enableZoom: args.enableZoom,
}), }),
); );
try { try {
@@ -411,7 +405,6 @@ export class App extends React.Component<RouteComponentProps, {}> {
standalone: args.standalone, standalone: args.standalone,
chartType: args.chartType, chartType: args.chartType,
source: args.source, source: args.source,
enableZoom: args.enableZoom,
}), }),
); );
} catch (error) { } catch (error) {
@@ -445,7 +438,6 @@ export class App extends React.Component<RouteComponentProps, {}> {
standalone: args.standalone, standalone: args.standalone,
chartType: args.chartType, chartType: args.chartType,
source: args.source, source: args.source,
enableZoom: args.enableZoom,
loadingMore: false, loadingMore: false,
}), }),
); );
@@ -549,7 +541,6 @@ export class App extends React.Component<RouteComponentProps, {}> {
chartType={this.state.chartType} chartType={this.state.chartType}
onSelection={this.onSelection} onSelection={this.onSelection}
ref={(ref) => (this.chartRef = ref)} ref={(ref) => (this.chartRef = ref)}
enableZoom={this.state.enableZoom}
/> />
{this.state.showSidePanel ? ( {this.state.showSidePanel ? (
<Responsive minWidth={768} id="sidePanel"> <Responsive minWidth={768} id="sidePanel">

View File

@@ -14,7 +14,7 @@ import {
FancyChart, FancyChart,
CircleRenderer, CircleRenderer,
} from 'topola'; } from 'topola';
import { Responsive } from 'semantic-ui-react'; import {Responsive} from 'semantic-ui-react';
/** How much to zoom when using the +/- buttons. */ /** How much to zoom when using the +/- buttons. */
const ZOOM_FACTOR = 1.3; const ZOOM_FACTOR = 1.3;
@@ -24,30 +24,28 @@ const ZOOM_FACTOR = 1.3;
* *
* @param size the size of the chart * @param size the size of the chart
*/ */
function zoomed(size: [number, number], enableZoom: boolean) { function zoomed(size: [number, number]) {
const parent = d3.select('#svgContainer').node() as Element; const parent = d3.select('#svgContainer').node() as Element;
if (enableZoom) { const scale = d3.event.transform.k;
const scale = d3.event.transform.k; const offsetX = d3.max([0, (parent.clientWidth - size[0] * scale) / 2]);
const offsetX = d3.max([0, (parent.clientWidth - size[0] * scale) / 2]); const offsetY = d3.max([0, (parent.clientHeight - size[1] * scale) / 2]);
const offsetY = d3.max([0, (parent.clientHeight - size[1] * scale) / 2]); d3.select('#chartSvg')
d3.select('#chartSvg') .attr('width', size[0] * scale)
.attr('width', size[0] * scale) .attr('height', size[1] * scale)
.attr('height', size[1] * scale) .attr('transform', `translate(${offsetX}, ${offsetY})`);
.attr('transform', `translate(${offsetX}, ${offsetY})`); d3.select('#chart').attr('transform', `scale(${scale})`);
d3.select('#chart').attr('transform', `scale(${scale})`);
}
parent.scrollLeft = -d3.event.transform.x; parent.scrollLeft = -d3.event.transform.x;
parent.scrollTop = -d3.event.transform.y; parent.scrollTop = -d3.event.transform.y;
} }
/** Called when the scrollbars are used. */ /** Called when the scrollbars are used. */
function scrolled(enableZoom: boolean) { function scrolled() {
const parent = d3.select('#svgContainer').node() as Element; const parent = d3.select('#svgContainer').node() as Element;
const x = parent.scrollLeft + parent.clientWidth / 2; const x = parent.scrollLeft + parent.clientWidth / 2;
const y = parent.scrollTop + parent.clientHeight / 2; const y = parent.scrollTop + parent.clientHeight / 2;
const scale = enableZoom ? d3.zoomTransform(parent).k : 1; const scale = d3.zoomTransform(parent).k;
d3.select(parent).call(d3.zoom().translateTo, x / scale, y / scale); d3.select(parent).call(d3.zoom().translateTo, x / scale, y / scale);
} }
@@ -135,7 +133,6 @@ export interface ChartProps {
selection: IndiInfo; selection: IndiInfo;
chartType: ChartType; chartType: ChartType;
onSelection: (indiInfo: IndiInfo) => void; onSelection: (indiInfo: IndiInfo) => void;
enableZoom: boolean;
} }
/** Component showing the genealogy chart and handling transition animations. */ /** Component showing the genealogy chart and handling transition animations. */
@@ -216,24 +213,22 @@ export class Chart extends React.PureComponent<ChartProps, {}> {
const svg = d3.select('#chartSvg'); const svg = d3.select('#chartSvg');
const parent = d3.select('#svgContainer').node() as Element; const parent = d3.select('#svgContainer').node() as Element;
const scale = this.props.enableZoom ? d3.zoomTransform(parent).k : 1; const scale = d3.zoomTransform(parent).k;
const zoomOutFactor = d3.min([ const zoomOutFactor = d3.min([
1, 1,
scale, scale,
parent.clientWidth / chartInfo.size[0], parent.clientWidth / chartInfo.size[0],
parent.clientHeight / chartInfo.size[1], parent.clientHeight / chartInfo.size[1],
])!; ])!;
const extent: [number, number] = this.props.enableZoom const extent: [number, number] = [d3.max([0.1, zoomOutFactor])!, 2];
? [d3.max([0.1, zoomOutFactor])!, 2]
: [1, 1];
this.zoomBehavior = d3 this.zoomBehavior = d3
.zoom() .zoom()
.scaleExtent(extent) .scaleExtent(extent)
.translateExtent([[0, 0], chartInfo.size]) .translateExtent([[0, 0], chartInfo.size])
.on('zoom', () => zoomed(chartInfo.size, this.props.enableZoom)); .on('zoom', () => zoomed(chartInfo.size));
d3.select(parent) d3.select(parent)
.on('scroll', () => scrolled(this.props.enableZoom)) .on('scroll', scrolled)
.call(this.zoomBehavior); .call(this.zoomBehavior);
const scrollTopTween = (scrollTop: number) => { const scrollTopTween = (scrollTop: number) => {
@@ -309,19 +304,17 @@ export class Chart extends React.PureComponent<ChartProps, {}> {
render() { render() {
return ( return (
<div id="svgContainer"> <div id="svgContainer">
{this.props.enableZoom ? ( <Responsive minWidth={768} className="zoom">
<Responsive minWidth={768} className="zoom"> <button className="zoom-in" onClick={() => this.zoom(ZOOM_FACTOR)}>
<button className="zoom-in" onClick={() => this.zoom(ZOOM_FACTOR)}> +
+ </button>
</button> <button
<button className="zoom-out"
className="zoom-out" onClick={() => this.zoom(1 / ZOOM_FACTOR)}
onClick={() => this.zoom(1 / ZOOM_FACTOR)} >
>
</button>
</button> </Responsive>
</Responsive>
) : null}
<svg id="chartSvg"> <svg id="chartSvg">
<g id="chart" /> <g id="chart" />
</svg> </svg>
@@ -334,19 +327,18 @@ export class Chart extends React.PureComponent<ChartProps, {}> {
const svg = document.getElementById('chartSvg')!.cloneNode(true) as Element; const svg = document.getElementById('chartSvg')!.cloneNode(true) as Element;
svg.removeAttribute('transform'); svg.removeAttribute('transform');
if (this.props.enableZoom) { const parent = d3.select('#svgContainer').node() as Element;
const parent = d3.select('#svgContainer').node() as Element; const scale = d3.zoomTransform(parent).k;
const scale = d3.zoomTransform(parent).k; svg.setAttribute(
svg.setAttribute( 'width',
'width', String(Number(svg.getAttribute('width')) / scale),
String(Number(svg.getAttribute('width')) / scale), );
); svg.setAttribute(
svg.setAttribute( 'height',
'height', String(Number(svg.getAttribute('height')) / scale),
String(Number(svg.getAttribute('height')) / scale), );
); svg.querySelector('#chart')!.removeAttribute('transform');
svg.querySelector('#chart')!.removeAttribute('transform');
}
return svg; return svg;
} }