diff --git a/packages/grafana-ui/src/components/PieChart/PieChart.story.tsx b/packages/grafana-ui/src/components/PieChart/PieChart.story.tsx deleted file mode 100644 index b189a356d77..00000000000 --- a/packages/grafana-ui/src/components/PieChart/PieChart.story.tsx +++ /dev/null @@ -1,317 +0,0 @@ -import React from 'react'; -import { Meta, Story } from '@storybook/react'; -import { PieChart, PieChartProps, PieChartType, TooltipDisplayMode } from '@grafana/ui'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { - FieldColorModeId, - FieldConfigSource, - FieldType, - InterpolateFunction, - ReduceDataOptions, - ThresholdsMode, - toDataFrame, -} from '@grafana/data'; -import { LegendDisplayMode, LegendPlacement } from '../VizLegend/models.gen'; -import { PieChartLabels, PieChartLegendValues } from './types'; - -const fieldConfig: FieldConfigSource = { - defaults: { - thresholds: { - mode: ThresholdsMode.Percentage, - steps: [{ color: 'green', value: 0 }], - }, - color: { - mode: FieldColorModeId.PaletteClassic, - }, - }, - overrides: [], -}; -const reduceOptions: ReduceDataOptions = { calcs: [] }; -const replaceVariables: InterpolateFunction = (v) => v; -const data = [ - { - fields: [ - { - name: 'time', - type: FieldType.time, - config: { - color: { - mode: 'palette-classic', - }, - }, - values: [1620110299324, 1620110329324], - state: { - displayName: null, - seriesIndex: 0, - }, - }, - { - name: 'Cellar', - type: FieldType.number, - config: { - color: { - mode: 'palette-classic', - }, - }, - values: [27.008127592438484, 27.287423219155304], - state: { - displayName: 'Cellar', - seriesIndex: 1, - }, - }, - ], - }, - { - fields: [ - { - name: 'time', - type: FieldType.time, - config: { - color: { - mode: 'palette-classic', - }, - }, - values: [1620110299324, 1620110329324], - state: { - displayName: null, - seriesIndex: 1, - }, - }, - { - name: 'Living room', - type: FieldType.number, - config: { - color: { - mode: 'palette-classic', - }, - }, - values: [65.97347908625065, 65.6588311671438], - state: { - displayName: 'Living room', - seriesIndex: 2, - }, - }, - ], - }, - { - fields: [ - { - name: 'time', - type: FieldType.time, - config: { - color: { - mode: 'palette-classic', - }, - }, - values: [1620110299324, 1620110329324], - state: { - displayName: null, - seriesIndex: 2, - }, - }, - { - name: 'Porch', - type: FieldType.number, - config: { - color: { - mode: 'palette-classic', - }, - }, - values: [42.01219662436388, 42.48471312850685], - state: { - displayName: 'Porch', - seriesIndex: 3, - }, - }, - ], - }, - { - fields: [ - { - name: 'time', - type: FieldType.time, - config: { - color: { - mode: 'palette-classic', - }, - }, - values: [1620110299324, 1620110329324], - state: { - displayName: null, - seriesIndex: 3, - }, - }, - { - name: 'Bedroom', - type: FieldType.number, - config: { - color: { - mode: 'palette-classic', - }, - }, - values: [34.28143812581964, 34.37741979130198], - state: { - displayName: 'Bedroom', - seriesIndex: 4, - }, - }, - ], - }, - { - fields: [ - { - name: 'time', - type: FieldType.time, - config: { - color: { - mode: 'palette-classic', - }, - mappings: [], - }, - values: [1620110299324, 1620110329324], - state: { - displayName: null, - seriesIndex: 4, - }, - }, - { - name: 'Guest room', - type: FieldType.number, - config: { - color: { - mode: 'palette-classic', - }, - }, - values: [57.855438763786104, 57.521663794462654], - state: { - displayName: 'Guest room', - seriesIndex: 5, - }, - }, - ], - }, -]; - -export default { - title: 'Visualizations/PieChart', - decorators: [withCenteredStory], - component: PieChart, - args: { - width: 500, - height: 500, - fieldConfig, - data, - }, - argTypes: { - tooltipMode: { - control: { - type: 'select', - options: Object.values(TooltipDisplayMode), - }, - }, - legendDisplayMode: { - control: { - type: 'select', - options: Object.values(LegendDisplayMode), - }, - }, - legendPlacement: { - control: { - type: 'select', - options: ['bottom', 'right'], - }, - }, - legendValues: { - control: { - type: 'check', - options: Object.values(PieChartLegendValues), - }, - }, - displayLabels: { - control: { - type: 'check', - options: Object.values(PieChartLabels), - }, - }, - height: { - control: { type: 'range', min: 300, max: 1000, step: 50 }, - }, - width: { - control: { type: 'range', min: 300, max: 1000, step: 50 }, - }, - }, - parameters: { - controls: { - exclude: [ - 'reduceOptions', - 'replaceVariables', - 'tooltipOptions', - 'onSeriesColorChange', - 'legendOptions', - 'timeZone', - ], - }, - }, -} as Meta; - -interface PieChartStoryProps extends PieChartProps { - tooltipMode: TooltipDisplayMode; - legendDisplayMode: LegendDisplayMode; - legendPlacement: LegendPlacement; - legendValues: PieChartLegendValues[]; -} - -const Template: Story = ({ - tooltipMode, - legendDisplayMode, - legendPlacement, - legendValues, - data, - ...args -}) => { - const tooltipOpts = { - mode: tooltipMode, - }; - - const legendOptions = { - displayMode: legendDisplayMode, - placement: legendPlacement, - values: legendValues, - calcs: [], - }; - - const dataPoints = data.map((d) => toDataFrame(d)); - - return ( - - ); -}; - -export const basic = Template.bind({}); - -basic.args = { - pieType: PieChartType.Pie, - tooltipMode: TooltipDisplayMode.Single, - legendDisplayMode: LegendDisplayMode.List, - legendPlacement: 'bottom', - legendValues: [PieChartLegendValues.Value], - displayLabels: [PieChartLabels.Name], -}; - -export const donut = Template.bind({}); - -donut.args = { - pieType: PieChartType.Donut, - tooltipMode: TooltipDisplayMode.Single, - legendDisplayMode: LegendDisplayMode.List, - legendPlacement: 'bottom', - legendValues: [PieChartLegendValues.Value], - displayLabels: [PieChartLabels.Name], -}; diff --git a/packages/grafana-ui/src/components/PieChart/types.ts b/packages/grafana-ui/src/components/PieChart/types.ts deleted file mode 100644 index fc61e5fad17..00000000000 --- a/packages/grafana-ui/src/components/PieChart/types.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { DataFrame, FieldConfigSource, FieldDisplay, InterpolateFunction, ReduceDataOptions } from '@grafana/data'; -import { VizTooltipOptions } from '../VizTooltip'; -import { VizLegendOptions } from '..'; - -/** - * @beta - */ -export interface PieChartSvgProps { - height: number; - width: number; - fieldDisplayValues: FieldDisplay[]; - pieType: PieChartType; - highlightedTitle?: string; - displayLabels?: PieChartLabels[]; - useGradients?: boolean; - tooltipOptions: VizTooltipOptions; -} - -/** - * @beta - */ -export interface PieChartProps { - height: number; - width: number; - pieType: PieChartType; - displayLabels?: PieChartLabels[]; - useGradients?: boolean; - legendOptions?: PieChartLegendOptions; - tooltipOptions: VizTooltipOptions; - reduceOptions: ReduceDataOptions; - fieldConfig: FieldConfigSource; - replaceVariables: InterpolateFunction; - data: DataFrame[]; - timeZone?: string; -} - -/** - * @beta - */ -export enum PieChartType { - Pie = 'pie', - Donut = 'donut', -} - -/** - * @beta - */ -export enum PieChartLegendValues { - Value = 'value', - Percent = 'percent', -} - -/** - * @beta - */ -export enum PieChartLabels { - Name = 'name', - Value = 'value', - Percent = 'percent', -} - -/** - * @beta - */ -export interface PieChartLegendOptions extends VizLegendOptions { - values: PieChartLegendValues[]; -} diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index e5ae22e130e..fedd63f9b74 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -18,14 +18,6 @@ export { ColorPicker, SeriesColorPicker } from './ColorPicker/ColorPicker'; export { ColorValueEditor, ColorValueEditorProps } from './OptionsUI/color'; export { SeriesColorPickerPopover, SeriesColorPickerPopoverWithTheme } from './ColorPicker/SeriesColorPickerPopover'; export { EmptySearchResult } from './EmptySearchResult/EmptySearchResult'; -export { PieChart } from './PieChart/PieChart'; -export { - PieChartType, - PieChartProps, - PieChartLabels, - PieChartLegendOptions, - PieChartLegendValues, -} from './PieChart/types'; export { UnitPicker } from './UnitPicker/UnitPicker'; export { StatsPicker } from './StatsPicker/StatsPicker'; export { RefreshPicker, defaultIntervals } from './RefreshPicker/RefreshPicker'; @@ -105,7 +97,7 @@ export { usePanelContext, } from './PanelChrome'; export { VizLayout, VizLayoutComponentType, VizLayoutLegendProps, VizLayoutProps } from './VizLayout/VizLayout'; -export { VizLegendItem } from './VizLegend/types'; +export { VizLegendItem, SeriesVisibilityChangeBehavior } from './VizLegend/types'; export { LegendPlacement, LegendDisplayMode, VizLegendOptions } from './VizLegend/models.gen'; export { VizLegend } from './VizLegend/VizLegend'; diff --git a/packages/grafana-ui/src/components/PieChart/PieChart.tsx b/public/app/plugins/panel/piechart/PieChart.tsx similarity index 68% rename from packages/grafana-ui/src/components/PieChart/PieChart.tsx rename to public/app/plugins/panel/piechart/PieChart.tsx index 4c2bc2dd8d6..015f1caf76c 100644 --- a/packages/grafana-ui/src/components/PieChart/PieChart.tsx +++ b/public/app/plugins/panel/piechart/PieChart.tsx @@ -1,176 +1,43 @@ -import React, { FC, useEffect, useState } from 'react'; +import React, { FC } from 'react'; + +import { FieldDisplay, FALLBACK_COLOR, formattedValueToString, GrafanaTheme2 } from '@grafana/data'; import { - DataHoverClearEvent, - DataHoverEvent, - FALLBACK_COLOR, - FieldDisplay, - formattedValueToString, - getFieldDisplayValues, - GrafanaTheme2, -} from '@grafana/data'; -import { selectors } from '@grafana/e2e-selectors'; -import { useStyles2, useTheme2 } from '../../themes/ThemeContext'; -import tinycolor from 'tinycolor2'; + VizTooltipOptions, + useTheme2, + useStyles2, + SeriesTableRowProps, + DataLinksContextMenu, + SeriesTable, +} from '@grafana/ui'; +import { PieChartType, PieChartLabels } from './types'; +import { useTooltip, useTooltipInPortal } from '@visx/tooltip'; import Pie, { PieArcDatum, ProvidedProps } from '@visx/shape/lib/shapes/Pie'; -import { Group } from '@visx/group'; +import { UseTooltipParams } from '@visx/tooltip/lib/hooks/useTooltip'; import { RadialGradient } from '@visx/gradient'; import { localPoint } from '@visx/event'; -import { useTooltip, useTooltipInPortal } from '@visx/tooltip'; -import { useComponentInstanceId } from '../../utils/useComponetInstanceId'; +import { Group } from '@visx/group'; +import tinycolor from 'tinycolor2'; import { css } from '@emotion/css'; -import { VizLegend, VizLegendItem } from '..'; -import { VizLayout } from '../VizLayout/VizLayout'; -import { LegendDisplayMode } from '../VizLegend/models.gen'; -import { DataLinksContextMenu } from '../DataLinks/DataLinksContextMenu'; -import { UseTooltipParams } from '@visx/tooltip/lib/hooks/useTooltip'; -import { - PieChartLabels, - PieChartLegendOptions, - PieChartLegendValues, - PieChartProps, - PieChartSvgProps, - PieChartType, -} from './types'; -import { getTooltipContainerStyles } from '../../themes/mixins'; -import { SeriesTable, SeriesTableRowProps, VizTooltipOptions } from '../VizTooltip'; -import { usePanelContext } from '../PanelChrome'; -import { Subscription } from 'rxjs'; -import { SeriesVisibilityChangeBehavior } from '../VizLegend/types'; -const defaultLegendOptions: PieChartLegendOptions = { - displayMode: LegendDisplayMode.List, - placement: 'right', - calcs: [], - values: [PieChartLegendValues.Percent], -}; +import { useComponentInstanceId } from '@grafana/ui/src/utils/useComponetInstanceId'; +import { getTooltipContainerStyles } from '@grafana/ui/src/themes/mixins'; +import { selectors } from '@grafana/e2e-selectors'; /** * @beta */ -export function PieChart(props: PieChartProps) { - const { - data, - timeZone, - reduceOptions, - fieldConfig, - replaceVariables, - tooltipOptions, - width, - height, - ...restProps - } = props; - - const theme = useTheme2(); - const highlightedTitle = useSliceHighlightState(); - const fieldDisplayValues = getFieldDisplayValues({ - fieldConfig, - reduceOptions, - data, - theme: theme, - replaceVariables, - timeZone, - }); - - return ( - - {(vizWidth: number, vizHeight: number) => { - return ( - - ); - }} - - ); +interface PieChartProps { + height: number; + width: number; + fieldDisplayValues: FieldDisplay[]; + pieType: PieChartType; + highlightedTitle?: string; + displayLabels?: PieChartLabels[]; + useGradients?: boolean; // not used? + tooltipOptions: VizTooltipOptions; } -function getLegend(props: PieChartProps, displayValues: FieldDisplay[]) { - const { legendOptions = defaultLegendOptions } = props; - - if (legendOptions.displayMode === LegendDisplayMode.Hidden) { - return undefined; - } - const total = displayValues - .filter((item) => { - return !item.field.custom.hideFrom.viz; - }) - .reduce((acc, item) => item.display.numeric + acc, 0); - - const legendItems = displayValues.map((value, idx) => { - const hidden = value.field.custom.hideFrom.viz; - const display = value.display; - return { - label: display.title ?? '', - color: display.color ?? FALLBACK_COLOR, - yAxis: 1, - disabled: hidden, - getItemKey: () => (display.title ?? '') + idx, - getDisplayValues: () => { - const valuesToShow = legendOptions.values ?? []; - let displayValues = []; - - if (valuesToShow.includes(PieChartLegendValues.Value)) { - displayValues.push({ numeric: display.numeric, text: formattedValueToString(display), title: 'Value' }); - } - - if (valuesToShow.includes(PieChartLegendValues.Percent)) { - const fractionOfTotal = hidden ? 0 : display.numeric / total; - const percentOfTotal = fractionOfTotal * 100; - - displayValues.push({ - numeric: fractionOfTotal, - percent: percentOfTotal, - text: hidden ? '-' : percentOfTotal.toFixed(0) + '%', - title: valuesToShow.length > 1 ? 'Percent' : undefined, - }); - } - - return displayValues; - }, - }; - }); - - return ( - - ); -} - -function useSliceHighlightState() { - const [highlightedTitle, setHighlightedTitle] = useState(); - const { eventBus } = usePanelContext(); - - useEffect(() => { - const setHighlightedSlice = (event: DataHoverEvent) => { - setHighlightedTitle(event.payload.dataId); - }; - - const resetHighlightedSlice = (event: DataHoverClearEvent) => { - setHighlightedTitle(undefined); - }; - - const subs = new Subscription() - .add(eventBus.getStream(DataHoverEvent).subscribe({ next: setHighlightedSlice })) - .add(eventBus.getStream(DataHoverClearEvent).subscribe({ next: resetHighlightedSlice })); - - return () => { - subs.unsubscribe(); - }; - }, [setHighlightedTitle, eventBus]); - - return highlightedTitle; -} - -export const PieChartSvg: FC = ({ +export const PieChart: FC = ({ fieldDisplayValues, pieType, width, diff --git a/public/app/plugins/panel/piechart/PieChartOptionsBox.tsx b/public/app/plugins/panel/piechart/PieChartOptionsBox.tsx deleted file mode 100644 index 1921c7196a8..00000000000 --- a/public/app/plugins/panel/piechart/PieChartOptionsBox.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { PureComponent } from 'react'; -import { LegacyForms, InlineFormLabel, PieChartType } from '@grafana/ui'; -import { PanelEditorProps } from '@grafana/data'; -import { PieChartOptions } from './types'; - -const { Select } = LegacyForms; -const labelWidth = 8; - -const pieChartOptions = [ - { value: PieChartType.Pie, label: 'Pie' }, - { value: PieChartType.Donut, label: 'Donut' }, -]; - -export class PieChartOptionsBox extends PureComponent> { - onPieTypeChange = (pieType: any) => this.props.onOptionsChange({ ...this.props.options, pieType: pieType.value }); - - render() { - const { options } = this.props; - const { pieType } = options; - - return ( - <> -
- Type -