Browse Source

feat(ddm): dynamic chart height (#63006)

Ogi 1 year ago
parent
commit
551156afaa
3 changed files with 48 additions and 37 deletions
  1. 15 10
      static/app/views/ddm/chart.tsx
  2. 4 4
      static/app/views/ddm/chartBrush.tsx
  3. 29 23
      static/app/views/ddm/widget.tsx

+ 15 - 10
static/app/views/ddm/chart.tsx

@@ -26,13 +26,14 @@ import {getFormatter} from '../../components/charts/components/tooltip';
 import {Series} from './widget';
 
 type ChartProps = {
-  addFocusArea: (area: FocusArea) => void;
   displayType: MetricDisplayType;
   focusArea: FocusArea | null;
-  removeFocusArea: () => void;
   series: Series[];
   widgetIndex: number;
+  addFocusArea?: (area: FocusArea) => void;
+  height?: number;
   operation?: string;
+  removeFocusArea?: () => void;
 };
 
 // We need to enable canvas renderer for echarts before we use it here.
@@ -50,6 +51,7 @@ export const MetricChart = forwardRef<ReactEchartsRef, ChartProps>(
       addFocusArea,
       focusArea,
       removeFocusArea,
+      height,
     },
     forwardedRef
   ) => {
@@ -71,14 +73,14 @@ export const MetricChart = forwardRef<ReactEchartsRef, ChartProps>(
     const focusAreaBrush = useFocusAreaBrush(
       chartRef,
       focusArea,
-      addFocusArea,
-      removeFocusArea,
-      handleZoom,
       {
         widgetIndex,
-        isDisabled: !isHovered,
+        isDisabled: !isHovered || !addFocusArea || !removeFocusArea || !handleZoom,
         useFullYAxis: isCumulativeOp(operation),
-      }
+      },
+      addFocusArea,
+      removeFocusArea,
+      handleZoom
     );
 
     // TODO(ddm): Try to do this in a more elegant way
@@ -114,13 +116,16 @@ export const MetricChart = forwardRef<ReactEchartsRef, ChartProps>(
         addSecondsToTimeFormat: isSubMinuteBucket,
         limit: 10,
       };
+      const heightOptions = height ? {height} : {autoHeightResize: true};
+
       return {
+        ...heightOptions,
         ...focusAreaBrush.options,
         forwardedRef: mergeRefs([forwardedRef, chartRef]),
         series: seriesToShow,
         renderer: seriesToShow.length > 20 ? ('canvas' as const) : ('svg' as const),
         isGroupedByDate: true,
-        height: 300,
+        height,
         colors: seriesToShow.map(s => s.color),
         grid: {top: 20, bottom: 20, left: 15, right: 25},
         tooltip: {
@@ -166,6 +171,7 @@ export const MetricChart = forwardRef<ReactEchartsRef, ChartProps>(
       operation,
       seriesToShow,
       unit,
+      height,
     ]);
 
     return (
@@ -230,11 +236,10 @@ function getWidthFactor(bucketSize: number) {
 
 const ChartWrapper = styled('div')`
   position: relative;
-  height: 300px;
 `;
 
 const FogOfWarOverlay = styled('div')<{width?: number}>`
-  height: 244px;
+  height: calc(100% - 56px);
   width: ${p => p.width}%;
   position: absolute;
   right: 21px;

+ 4 - 4
static/app/views/ddm/chartBrush.tsx

@@ -36,10 +36,10 @@ type BrushEndResult = Parameters<EChartBrushEndHandler>[0];
 export function useFocusAreaBrush(
   chartRef: RefObject<ReactEchartsRef>,
   focusArea: FocusArea | null,
-  onAdd: (area: FocusArea) => void,
-  onRemove: () => void,
-  onZoom: (range: DateTimeObject) => void,
-  {widgetIndex, isDisabled = false, useFullYAxis = false}: UseFocusAreaBrushOptions
+  {widgetIndex, isDisabled = false, useFullYAxis = false}: UseFocusAreaBrushOptions,
+  onAdd: (area: FocusArea) => void = () => {},
+  onRemove: () => void = () => {},
+  onZoom: (range: DateTimeObject) => void = () => {}
 ) {
   const hasFocusArea = useMemo(
     () => focusArea && focusArea.widgetIndex === widgetIndex,

+ 29 - 23
static/app/views/ddm/widget.tsx

@@ -36,34 +36,36 @@ import {SummaryTable} from 'sentry/views/ddm/summaryTable';
 
 import {MIN_WIDGET_WIDTH} from './constants';
 
+type MetricWidgetProps = {
+  datetime: PageFilters['datetime'];
+  environments: PageFilters['environments'];
+  onChange: (index: number, data: Partial<MetricWidgetQueryParams>) => void;
+  projects: PageFilters['projects'];
+  widget: MetricWidgetQueryParams;
+  addFocusArea?: (area: FocusArea) => void;
+  focusArea?: FocusArea | null;
+  hasSiblings?: boolean;
+  index?: number;
+  isSelected?: boolean;
+  onSelect?: (index: number) => void;
+  removeFocusArea?: () => void;
+};
+
 export const MetricWidget = memo(
   ({
     widget,
     datetime,
     projects,
     environments,
-    index,
-    isSelected,
+    index = 0,
+    isSelected = false,
     onSelect,
     onChange,
-    hasSiblings,
+    hasSiblings = false,
     addFocusArea,
     removeFocusArea,
-    focusArea,
-  }: {
-    addFocusArea: (area: FocusArea) => void;
-    datetime: PageFilters['datetime'];
-    environments: PageFilters['environments'];
-    focusArea: FocusArea | null;
-    hasSiblings: boolean;
-    index: number;
-    isSelected: boolean;
-    onChange: (index: number, data: Partial<MetricWidgetQueryParams>) => void;
-    onSelect: (index: number) => void;
-    projects: PageFilters['projects'];
-    removeFocusArea: () => void;
-    widget: MetricWidgetQueryParams;
-  }) => {
+    focusArea = null,
+  }: MetricWidgetProps) => {
     const handleChange = useCallback(
       (data: Partial<MetricWidgetQueryParams>) => {
         onChange(index, data);
@@ -114,7 +116,7 @@ export const MetricWidget = memo(
         // show the selection border only if we have more widgets than one
         isHighlighted={isSelected && !!hasSiblings}
         isHighlightable={!!hasSiblings}
-        onClick={() => onSelect(index)}
+        onClick={() => onSelect?.(index)}
       >
         <PanelBody>
           <MetricWidgetHeader>
@@ -150,6 +152,7 @@ export const MetricWidget = memo(
               addFocusArea={addFocusArea}
               focusArea={focusArea}
               removeFocusArea={removeFocusArea}
+              chartHeight={300}
               {...widget}
             />
           ) : (
@@ -167,12 +170,13 @@ export const MetricWidget = memo(
   }
 );
 
-interface MetricWidgetProps extends MetricWidgetQueryParams {
-  addFocusArea: (area: FocusArea) => void;
+interface MetricWidgetBodyProps extends MetricWidgetQueryParams {
   focusArea: FocusArea | null;
   onChange: (data: Partial<MetricWidgetQueryParams>) => void;
-  removeFocusArea: () => void;
   widgetIndex: number;
+  addFocusArea?: (area: FocusArea) => void;
+  chartHeight?: number;
+  removeFocusArea?: () => void;
 }
 
 const MetricWidgetBody = memo(
@@ -185,8 +189,9 @@ const MetricWidgetBody = memo(
     addFocusArea,
     focusArea,
     removeFocusArea,
+    chartHeight,
     ...metricsQuery
-  }: MetricWidgetProps & PageFilters) => {
+  }: MetricWidgetBodyProps & PageFilters) => {
     const {mri, op, query, groupBy, projects, environments, datetime} = metricsQuery;
 
     const {data, isLoading, isError, error} = useMetricsDataZoom(
@@ -281,6 +286,7 @@ const MetricWidgetBody = memo(
           addFocusArea={addFocusArea}
           focusArea={focusArea}
           removeFocusArea={removeFocusArea}
+          height={chartHeight}
         />
         {metricsQuery.showSummaryTable && (
           <SummaryTable