|
@@ -12,6 +12,7 @@ import {Button} from 'sentry/components/button';
|
|
|
import {IconClose, IconZoom} from 'sentry/icons';
|
|
|
import {space} from 'sentry/styles/space';
|
|
|
import type {EChartBrushEndHandler, ReactEchartsRef} from 'sentry/types/echarts';
|
|
|
+import {getMetricConversionFunction} from 'sentry/utils/metrics/normalizeMetricValue';
|
|
|
import type {SelectionRange} from 'sentry/utils/metrics/types';
|
|
|
import type {ValueRect} from 'sentry/views/ddm/chartUtils';
|
|
|
import {getValueRect} from 'sentry/views/ddm/chartUtils';
|
|
@@ -41,7 +42,9 @@ export interface FocusAreaSelection {
|
|
|
export interface UseFocusAreaProps extends FocusAreaProps {
|
|
|
chartRef: RefObject<ReactEchartsRef>;
|
|
|
opts: UseFocusAreaOptions;
|
|
|
+ chartUnit?: string;
|
|
|
onZoom?: (range: DateTimeObject) => void;
|
|
|
+ sampleUnit?: string;
|
|
|
}
|
|
|
|
|
|
type BrushEndResult = Parameters<EChartBrushEndHandler>[0];
|
|
@@ -50,6 +53,8 @@ export function useFocusArea({
|
|
|
chartRef,
|
|
|
selection: selection,
|
|
|
opts: {widgetIndex, isDisabled, useFullYAxis},
|
|
|
+ sampleUnit = 'none',
|
|
|
+ chartUnit = 'none',
|
|
|
onAdd,
|
|
|
onDraw,
|
|
|
onRemove,
|
|
@@ -110,7 +115,14 @@ export function useFocusArea({
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- const range = getSelectionRange(brushEnd, !!useFullYAxis, getValueRect(chartRef));
|
|
|
+ const valueConverter = getMetricConversionFunction(chartUnit, sampleUnit);
|
|
|
+
|
|
|
+ const range = getSelectionRange(
|
|
|
+ brushEnd,
|
|
|
+ !!useFullYAxis,
|
|
|
+ getValueRect(chartRef),
|
|
|
+ valueConverter
|
|
|
+ );
|
|
|
onAdd?.({
|
|
|
widgetIndex,
|
|
|
range,
|
|
@@ -126,7 +138,7 @@ export function useFocusArea({
|
|
|
});
|
|
|
isDrawingRef.current = false;
|
|
|
},
|
|
|
- [chartRef, isDisabled, onAdd, widgetIndex, useFullYAxis]
|
|
|
+ [isDisabled, sampleUnit, chartUnit, useFullYAxis, chartRef, onAdd, widgetIndex]
|
|
|
);
|
|
|
|
|
|
const handleRemove = useCallback(() => {
|
|
@@ -175,6 +187,8 @@ export function useFocusArea({
|
|
|
onZoom={handleZoomIn}
|
|
|
chartRef={chartRef}
|
|
|
useFullYAxis={!!useFullYAxis}
|
|
|
+ sampleUnit={sampleUnit}
|
|
|
+ chartUnit={chartUnit}
|
|
|
/>
|
|
|
),
|
|
|
isDrawingRef,
|
|
@@ -191,9 +205,11 @@ export function useFocusArea({
|
|
|
|
|
|
type BrushRectOverlayProps = {
|
|
|
chartRef: RefObject<ReactEchartsRef>;
|
|
|
+ chartUnit: string;
|
|
|
onRemove: () => void;
|
|
|
onZoom: () => void;
|
|
|
rect: FocusAreaSelection | null;
|
|
|
+ sampleUnit: string;
|
|
|
useFullYAxis: boolean;
|
|
|
};
|
|
|
|
|
@@ -203,6 +219,8 @@ function BrushRectOverlay({
|
|
|
onRemove,
|
|
|
useFullYAxis,
|
|
|
chartRef,
|
|
|
+ sampleUnit,
|
|
|
+ chartUnit,
|
|
|
}: BrushRectOverlayProps) {
|
|
|
const [position, setPosition] = useState<AbsolutePosition | null>(null);
|
|
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
@@ -223,13 +241,17 @@ function BrushRectOverlay({
|
|
|
}
|
|
|
const finder = {xAxisId: 'xAxis', yAxisId: 'yAxis'};
|
|
|
|
|
|
+ const valueConverter = getMetricConversionFunction(sampleUnit, chartUnit);
|
|
|
+ const max = valueConverter(rect.range.max ?? null);
|
|
|
+ const min = valueConverter(rect.range.min ?? null);
|
|
|
+
|
|
|
const topLeft = chartInstance.convertToPixel(finder, [
|
|
|
getTimestamp(rect.range.start),
|
|
|
- rect.range.max,
|
|
|
+ max,
|
|
|
] as number[]);
|
|
|
const bottomRight = chartInstance.convertToPixel(finder, [
|
|
|
getTimestamp(rect.range.end),
|
|
|
- rect.range.min,
|
|
|
+ min,
|
|
|
] as number[]);
|
|
|
|
|
|
if (!topLeft || !bottomRight) {
|
|
@@ -258,7 +280,7 @@ function BrushRectOverlay({
|
|
|
if (!isEqual(newPosition, position)) {
|
|
|
setPosition(newPosition);
|
|
|
}
|
|
|
- }, [chartRef, rect, useFullYAxis, position]);
|
|
|
+ }, [chartRef, rect, sampleUnit, chartUnit, useFullYAxis, position]);
|
|
|
|
|
|
useEffect(() => {
|
|
|
updatePosition();
|
|
@@ -296,7 +318,8 @@ const getTimestamp = date => (date ? moment.utc(date).valueOf() : null);
|
|
|
const getSelectionRange = (
|
|
|
params: BrushEndResult,
|
|
|
useFullYAxis: boolean,
|
|
|
- boundingRect: ValueRect
|
|
|
+ boundingRect: ValueRect,
|
|
|
+ valueConverter: (value: number) => number
|
|
|
): SelectionRange => {
|
|
|
const rect = params.areas[0];
|
|
|
|
|
@@ -306,8 +329,8 @@ const getSelectionRange = (
|
|
|
const startDate = getDate(Math.max(startTimestamp, boundingRect.xMin));
|
|
|
const endDate = getDate(Math.min(endTimestamp, boundingRect.xMax));
|
|
|
|
|
|
- const min = useFullYAxis ? NaN : Math.min(...rect.coordRange[1]);
|
|
|
- const max = useFullYAxis ? NaN : Math.max(...rect.coordRange[1]);
|
|
|
+ const min = useFullYAxis ? NaN : valueConverter(Math.min(...rect.coordRange[1]));
|
|
|
+ const max = useFullYAxis ? NaN : valueConverter(Math.max(...rect.coordRange[1]));
|
|
|
|
|
|
return {
|
|
|
start: startDate,
|