import {Fragment, useCallback, useMemo} from 'react'; import styled from '@emotion/styled'; import {ArithmeticBuilder} from 'sentry/components/arithmeticBuilder'; import type {Expression} from 'sentry/components/arithmeticBuilder/expression'; import {isTokenFunction} from 'sentry/components/arithmeticBuilder/token'; import type {SelectKey, SelectOption} from 'sentry/components/compactSelect'; import {CompactSelect} from 'sentry/components/compactSelect'; import {Button} from 'sentry/components/core/button'; import {Tooltip} from 'sentry/components/tooltip'; import {IconAdd} from 'sentry/icons'; import {IconDelete} from 'sentry/icons/iconDelete'; import {t} from 'sentry/locale'; import {parseFunction} from 'sentry/utils/discover/fields'; import {ALLOWED_EXPLORE_VISUALIZE_AGGREGATES} from 'sentry/utils/fields'; import { useExploreVisualizes, useSetExploreVisualizes, } from 'sentry/views/explore/contexts/pageParamsContext'; import type {Visualize} from 'sentry/views/explore/contexts/pageParamsContext/visualizes'; import { DEFAULT_VISUALIZATION, DEFAULT_VISUALIZATION_FIELD, MAX_VISUALIZES, } from 'sentry/views/explore/contexts/pageParamsContext/visualizes'; import {useVisualizeFields} from 'sentry/views/explore/hooks/useVisualizeFields'; import {ChartType} from 'sentry/views/insights/common/components/chart'; import { ToolbarFooter, ToolbarFooterButton, ToolbarHeader, ToolbarHeaderButton, ToolbarLabel, ToolbarRow, ToolbarSection, } from './styles'; interface ToolbarVisualizeProps { equationSupport?: boolean; } export function ToolbarVisualize({equationSupport}: ToolbarVisualizeProps) { const visualizes = useExploreVisualizes(); const setVisualizes = useSetExploreVisualizes(); const addChart = useCallback(() => { setVisualizes( [...visualizes, {yAxes: [DEFAULT_VISUALIZATION], chartType: ChartType.LINE}], [DEFAULT_VISUALIZATION_FIELD] ); }, [setVisualizes, visualizes]); const addOverlay = useCallback( (group: number) => { const newVisualizes = visualizes.slice(); newVisualizes[group]!.yAxes.push(DEFAULT_VISUALIZATION); setVisualizes(newVisualizes, [DEFAULT_VISUALIZATION_FIELD]); }, [setVisualizes, visualizes] ); const deleteOverlay = useCallback( (group: number, index: number) => { const newVisualizes: Visualize[] = visualizes .map((visualize, orgGroup) => { if (group !== orgGroup) { return visualize; } return { ...visualize, yAxes: visualize.yAxes.filter((_, orgIndex) => index !== orgIndex), }; }) .filter(visualize => visualize.yAxes.length > 0); setVisualizes(newVisualizes); }, [setVisualizes, visualizes] ); const canDelete = visualizes.map(visualize => visualize.yAxes.length).reduce((a, b) => a + b, 0) > 1; const shouldRenderLabel = visualizes.length > 1; return ( {t('Visualize')} } onClick={addChart} aria-label={t('Add Chart')} borderless disabled={visualizes.length >= MAX_VISUALIZES} />
{visualizes.map((visualize, group) => { return ( {visualize.yAxes.map((yAxis, index) => ( {equationSupport ? ( ) : ( )} ))} } onClick={() => addOverlay(group)} priority="link" aria-label={t('Add Series')} > {t('Add Series')} ); })}
); } interface VisualizeDropdownProps { canDelete: boolean; deleteOverlay: (group: number, index: number) => void; group: number; index: number; setVisualizes: (visualizes: Visualize[], fields?: string[]) => void; visualizes: Visualize[]; yAxis: string; label?: string; } function VisualizeDropdown({ canDelete, deleteOverlay, group, index, setVisualizes, visualizes, yAxis, label, }: VisualizeDropdownProps) { const yAxes: string[] = useMemo(() => { return visualizes.flatMap(visualize => visualize.yAxes); }, [visualizes]); const fieldOptions: Array> = useVisualizeFields({yAxes}); const aggregateOptions: Array> = useMemo(() => { return ALLOWED_EXPLORE_VISUALIZE_AGGREGATES.map(aggregate => { return { label: aggregate, value: aggregate, textValue: aggregate, }; }); }, []); const parsedVisualize = useMemo(() => parseFunction(yAxis)!, [yAxis]); const setChartField = useCallback( ({value}: SelectOption) => { const newVisualizes = visualizes.slice(); newVisualizes[group]!.yAxes[index] = `${parsedVisualize.name}(${value})`; setVisualizes(newVisualizes, [String(value)]); }, [group, index, parsedVisualize, setVisualizes, visualizes] ); const setChartAggregate = useCallback( ({value}: SelectOption) => { const newVisualizes = visualizes.slice(); newVisualizes[group]!.yAxes[index] = `${value}(${parsedVisualize.arguments[0]})`; setVisualizes(newVisualizes); }, [group, index, parsedVisualize, setVisualizes, visualizes] ); return ( {label && {label}}