private _renderZoomControls()

in src/PortfolioPlanning/Components/Plan/PlanTimeline.tsx [143:220]


    private _renderZoomControls(): JSX.Element {
        if (this.props.items.length > 0) {
            return (
                <div className="plan-timeline-zoom-controls">
                    <div className="plan-timeline-zoom-slider">
                        <Slider
                            min={-sliderSteps}
                            max={sliderSteps}
                            step={1}
                            showValue={false}
                            value={this.state.sliderValue}
                            disabled={this.props.items.length === 0}
                            onChange={(value: number) => {
                                const middlePoint = moment(
                                    (this.state.visibleTimeEnd.valueOf() + this.state.visibleTimeStart.valueOf()) / 2
                                );

                                let newVisibleTimeStart: moment.Moment;
                                let newVisibleTimeEnd: moment.Moment;

                                const maxMinDifference =
                                    (this.defaultTimeEnd.valueOf() - this.defaultTimeStart.valueOf()) / 2;

                                if (value === 0) {
                                    // Zoom fit zoom level
                                    newVisibleTimeStart = moment(middlePoint).add(-maxMinDifference, "milliseconds");
                                    newVisibleTimeEnd = moment(middlePoint).add(maxMinDifference, "milliseconds");
                                } else if (value < 0) {
                                    // Zoom out
                                    const stepSize = (365 * day) / sliderSteps;

                                    newVisibleTimeStart = moment(middlePoint)
                                        .add(-maxMinDifference, "milliseconds")
                                        .add(stepSize * value);
                                    newVisibleTimeEnd = moment(middlePoint)
                                        .add(maxMinDifference, "milliseconds")
                                        .add(-stepSize * value);
                                } else {
                                    // Zoom in
                                    const maxTimeStart = moment(middlePoint).add(-maxMinDifference, "milliseconds");
                                    const maxTimeEnd = moment(middlePoint).add(maxMinDifference, "milliseconds");
                                    const minTimeEnd = moment(middlePoint).add(maxZoomIn, "milliseconds");
                                    const stepSize = (maxTimeEnd.valueOf() - minTimeEnd.valueOf()) / sliderSteps;

                                    newVisibleTimeStart = moment(maxTimeStart).add(value * stepSize, "milliseconds");
                                    newVisibleTimeEnd = moment(maxTimeEnd).add(-value * stepSize, "milliseconds");
                                }

                                this.setState({
                                    sliderValue: value,
                                    visibleTimeStart: newVisibleTimeStart,
                                    visibleTimeEnd: newVisibleTimeEnd
                                });
                            }}
                        />
                    </div>
                    <div className="plan-timeline-zoom-fit-button">
                        <Button
                            text="Zoom fit"
                            disabled={this.props.items.length === 0}
                            onClick={() => {
                                const [timeStart, timeEnd] = this._getDefaultTimes(this.props.items);

                                this.defaultTimeStart = moment(timeStart);
                                this.defaultTimeEnd = moment(timeEnd);

                                this.setState({
                                    sliderValue: 0,
                                    visibleTimeStart: timeStart,
                                    visibleTimeEnd: timeEnd
                                });
                            }}
                        />
                    </div>
                </div>
            );
        }
    }