Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 45 additions & 51 deletions static/app/components/charts/barChartZoom.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {Component} from 'react';
import type {Location} from 'history';

import DataZoomInside from 'sentry/components/charts/components/dataZoomInside';
import ToolBox from 'sentry/components/charts/components/toolBox';
import type {
EChartChartReadyHandler,
EChartDataZoomHandler,
EChartFinishedHandler,
ECharts,
} from 'sentry/types/echarts';
import {browserHistory} from 'sentry/utils/browserHistory';
Expand All @@ -14,6 +14,7 @@ type RenderProps = {
dataZoom: ReturnType<typeof DataZoomInside>;
onChartReady: EChartChartReadyHandler;
onDataZoom: EChartDataZoomHandler;
onFinished: EChartFinishedHandler;
toolBox: ReturnType<typeof ToolBox>;
};

Expand Down Expand Up @@ -67,29 +68,30 @@ type Props = {
onHistoryPush?: (start: number, end: number) => void;
};

class BarChartZoom extends Component<Props> {
zooming: (() => void) | null = null;

function BarChartZoom({
buckets,
children,
location,
minZoomWidth,
onChartReady,
onDataZoom,
onDataZoomCancelled,
onHistoryPush,
paramEnd,
paramStart,
xAxisIndex,
}: Props) {
/**
* Enable zoom immediately instead of having to toggle to zoom
*/
handleChartReady = (chart: ECharts) => {
this.props.onChartReady?.(chart);
const handleChartReady = (chart: ECharts) => {
onChartReady?.(chart);
};

/**
* Chart event when *any* rendering+animation finishes
*
* `this.zooming` acts as a callback function so that
* we can let the native zoom animation on the chart complete
* before we update URL state and re-render
*/
handleChartFinished = (_props: any, chart: any) => {
if (typeof this.zooming === 'function') {
this.zooming();
this.zooming = null;
}

const handleChartFinished = (_props: any, chart: any) => {
// This attempts to activate the area zoom toolbox feature
const zoom = chart._componentsViews?.find((c: any) => c._features?.dataZoom);
if (zoom && !zoom._features.dataZoom._isZoomActive) {
Expand All @@ -102,16 +104,14 @@ class BarChartZoom extends Component<Props> {
}
};

handleDataZoom = (evt: any, chart: any) => {
const handleDataZoom = (evt: any, chart: any) => {
const model = chart.getModel();
const {startValue, endValue} = model._payload.batch[0];

// Both of these values should not be null, but we include it just in case.
// These values are null when the user uses the toolbox included in ECharts
// to navigate back through zoom history, but we hide it below.
if (startValue !== null && endValue !== null) {
const {buckets, location, paramStart, paramEnd, minZoomWidth, onHistoryPush} =
this.props;
const {start} = buckets[startValue]!;
const {end} = buckets[endValue]!;

Expand All @@ -132,47 +132,41 @@ class BarChartZoom extends Component<Props> {
} else {
// Dispatch the restore action here to stop ECharts from zooming
chart.dispatchAction({type: 'restore'});
this.props.onDataZoomCancelled?.();
onDataZoomCancelled?.();
}
} else {
// Dispatch the restore action here to stop ECharts from zooming
chart.dispatchAction({type: 'restore'});
this.props.onDataZoomCancelled?.();
onDataZoomCancelled?.();
}

this.props.onDataZoom?.(evt, chart);
onDataZoom?.(evt, chart);
};

render() {
const {children, xAxisIndex} = this.props;

const renderProps = {
onChartReady: this.handleChartReady,
onFinished: this.handleChartFinished,
dataZoom: DataZoomInside({xAxisIndex}),
// We must include data zoom in the toolbox for the zoom to work,
// but we do not want to show the toolbox components.
toolBox: ToolBox(
{},
{
dataZoom: {
title: {
zoom: '',
back: '',
},
iconStyle: {
borderWidth: 0,
color: 'transparent',
opacity: 0,
},
return children({
onChartReady: handleChartReady,
onFinished: handleChartFinished,
dataZoom: DataZoomInside({xAxisIndex}),
// We must include data zoom in the toolbox for the zoom to work,
// but we do not want to show the toolbox components.
toolBox: ToolBox(
{},
{
dataZoom: {
title: {
zoom: '',
back: '',
},
}
),
onDataZoom: this.handleDataZoom,
};

return children(renderProps);
}
iconStyle: {
borderWidth: 0,
color: 'transparent',
opacity: 0,
},
},
}
),
onDataZoom: handleDataZoom,
});
}

export default BarChartZoom;
Loading