mirror of
https://github.com/grafana/grafana.git
synced 2025-01-27 16:57:14 -06:00
Add datalinks support to PieChart v2 (#31642)
* Remove default value for multiSelect * Add data links support for PieChart v2 * Temporarily fix story * Refactor PieSlice, deduplicate colors * Add field config to context menu of pie chart * Add custom key to legend This is a bit hacky. When there are multiple DisplayValues with the same title the react keys collide and LegendListItems are not cleared correctly. * Forgot to add the interface * Fix missing tooltip in edit mode
This commit is contained in:
parent
477a54ae54
commit
e7757b0175
@ -186,7 +186,6 @@ export class PanelOptionsEditorBuilder<TOptions> extends OptionsUIRegistryBuilde
|
|||||||
) {
|
) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
defaultValue: config.defaultValue ?? [],
|
|
||||||
id: config.path,
|
id: config.path,
|
||||||
editor: standardEditorsRegistry.get('multi-select').editor as any,
|
editor: standardEditorsRegistry.get('multi-select').editor as any,
|
||||||
});
|
});
|
||||||
|
@ -12,7 +12,7 @@ interface DataLinksContextMenuProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DataLinksContextMenuApi {
|
export interface DataLinksContextMenuApi {
|
||||||
openMenu?: React.MouseEventHandler<HTMLElement>;
|
openMenu?: React.MouseEventHandler<HTMLOrSVGElement>;
|
||||||
targetClassName?: string;
|
targetClassName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import { object, select, number, boolean } from '@storybook/addon-knobs';
|
import { object, select, number, boolean } from '@storybook/addon-knobs';
|
||||||
import { PieChart, PieChartType } from '@grafana/ui';
|
import { PieChart, PieChartType } from '@grafana/ui';
|
||||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||||
|
import { FieldConfig } from '@grafana/data';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Visualizations/PieChart',
|
title: 'Visualizations/PieChart',
|
||||||
@ -9,14 +10,25 @@ export default {
|
|||||||
component: PieChart,
|
component: PieChart,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fieldConfig: FieldConfig = {
|
||||||
|
displayName: '',
|
||||||
|
min: 0,
|
||||||
|
max: 10,
|
||||||
|
decimals: 10,
|
||||||
|
thresholds: {} as any,
|
||||||
|
noValue: 'no value',
|
||||||
|
unit: 'km/s',
|
||||||
|
links: {} as any,
|
||||||
|
};
|
||||||
|
|
||||||
const getKnobs = () => {
|
const getKnobs = () => {
|
||||||
return {
|
return {
|
||||||
datapoints: object('datapoints', [
|
datapoints: object('datapoints', [
|
||||||
{ numeric: 100, text: '100', title: 'USA' },
|
{ field: fieldConfig, hasLinks: false, name: 'USA', display: { numeric: 100, text: '100', title: 'USA' } },
|
||||||
{ numeric: 200, text: '200', title: 'Canada' },
|
{ field: fieldConfig, hasLinks: false, name: 'Canada', display: { numeric: 200, text: '200', title: 'Canada' } },
|
||||||
{ numeric: 20, text: '20', title: 'Sweden' },
|
{ field: fieldConfig, hasLinks: false, name: 'Sweden', display: { numeric: 20, text: '20', title: 'Sweden' } },
|
||||||
{ numeric: 50, text: '50', title: 'Spain' },
|
{ field: fieldConfig, hasLinks: false, name: 'Spain', display: { numeric: 50, text: '50', title: 'Spain' } },
|
||||||
{ numeric: 70, text: '70', title: 'Germeny' },
|
{ field: fieldConfig, hasLinks: false, name: 'Germany', display: { numeric: 70, text: '70', title: 'Germeny' } },
|
||||||
]),
|
]),
|
||||||
width: number('Width', 500),
|
width: number('Width', 500),
|
||||||
height: number('Height', 500),
|
height: number('Height', 500),
|
||||||
@ -30,11 +42,11 @@ const getKnobs = () => {
|
|||||||
export const basic = () => {
|
export const basic = () => {
|
||||||
const { datapoints, pieType, width, height } = getKnobs();
|
const { datapoints, pieType, width, height } = getKnobs();
|
||||||
|
|
||||||
return <PieChart width={width} height={height} values={datapoints} pieType={pieType} />;
|
return <PieChart width={width} height={height} fieldDisplayValues={datapoints} pieType={pieType} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const donut = () => {
|
export const donut = () => {
|
||||||
const { datapoints, width, height } = getKnobs();
|
const { datapoints, width, height } = getKnobs();
|
||||||
|
|
||||||
return <PieChart width={width} height={height} values={datapoints} pieType={PieChartType.Donut} />;
|
return <PieChart width={width} height={height} fieldDisplayValues={datapoints} pieType={PieChartType.Donut} />;
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React, { FC } from 'react';
|
import React, { FC, ReactNode } from 'react';
|
||||||
import { DisplayValue, FALLBACK_COLOR, formattedValueToString, GrafanaTheme } from '@grafana/data';
|
import { DisplayValue, FALLBACK_COLOR, FieldDisplay, formattedValueToString, GrafanaTheme } from '@grafana/data';
|
||||||
import { useStyles, useTheme } from '../../themes/ThemeContext';
|
import { useStyles, useTheme } from '../../themes/ThemeContext';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
import Pie, { PieArcDatum } from '@visx/shape/lib/shapes/Pie';
|
import Pie, { PieArcDatum, ProvidedProps } from '@visx/shape/lib/shapes/Pie';
|
||||||
import { Group } from '@visx/group';
|
import { Group } from '@visx/group';
|
||||||
import { RadialGradient } from '@visx/gradient';
|
import { RadialGradient } from '@visx/gradient';
|
||||||
import { localPoint } from '@visx/event';
|
import { localPoint } from '@visx/event';
|
||||||
@ -12,6 +12,8 @@ import { css } from 'emotion';
|
|||||||
import { VizLegend, VizLegendItem } from '..';
|
import { VizLegend, VizLegendItem } from '..';
|
||||||
import { VizLayout } from '../VizLayout/VizLayout';
|
import { VizLayout } from '../VizLayout/VizLayout';
|
||||||
import { LegendDisplayMode, VizLegendOptions } from '../VizLegend/types';
|
import { LegendDisplayMode, VizLegendOptions } from '../VizLegend/types';
|
||||||
|
import { DataLinksContextMenu } from '../DataLinks/DataLinksContextMenu';
|
||||||
|
import { UseTooltipParams } from '@visx/tooltip/lib/hooks/useTooltip';
|
||||||
|
|
||||||
export enum PieChartLabels {
|
export enum PieChartLabels {
|
||||||
Name = 'name',
|
Name = 'name',
|
||||||
@ -27,7 +29,7 @@ export enum PieChartLegendValues {
|
|||||||
interface SvgProps {
|
interface SvgProps {
|
||||||
height: number;
|
height: number;
|
||||||
width: number;
|
width: number;
|
||||||
values: DisplayValue[];
|
fieldDisplayValues: FieldDisplay[];
|
||||||
pieType: PieChartType;
|
pieType: PieChartType;
|
||||||
displayLabels?: PieChartLabels[];
|
displayLabels?: PieChartLabels[];
|
||||||
useGradients?: boolean;
|
useGradients?: boolean;
|
||||||
@ -54,24 +56,26 @@ const defaultLegendOptions: PieChartLegendOptions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const PieChart: FC<Props> = ({
|
export const PieChart: FC<Props> = ({
|
||||||
values,
|
fieldDisplayValues,
|
||||||
legendOptions = defaultLegendOptions,
|
legendOptions = defaultLegendOptions,
|
||||||
onSeriesColorChange,
|
onSeriesColorChange,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
...restProps
|
...restProps
|
||||||
}) => {
|
}) => {
|
||||||
const getLegend = (values: DisplayValue[], legendOptions: PieChartLegendOptions) => {
|
const getLegend = (fields: FieldDisplay[], legendOptions: PieChartLegendOptions) => {
|
||||||
if (legendOptions.displayMode === LegendDisplayMode.Hidden) {
|
if (legendOptions.displayMode === LegendDisplayMode.Hidden) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
const values = fields.map((v) => v.display);
|
||||||
const total = values.reduce((acc, item) => item.numeric + acc, 0);
|
const total = values.reduce((acc, item) => item.numeric + acc, 0);
|
||||||
|
|
||||||
const legendItems = values.map<VizLegendItem>((value) => {
|
const legendItems = values.map<VizLegendItem>((value, idx) => {
|
||||||
return {
|
return {
|
||||||
label: value.title ?? '',
|
label: value.title ?? '',
|
||||||
color: value.color ?? FALLBACK_COLOR,
|
color: value.color ?? FALLBACK_COLOR,
|
||||||
yAxis: 1,
|
yAxis: 1,
|
||||||
|
getItemKey: () => (value.title ?? '') + idx,
|
||||||
getDisplayValues: () => {
|
getDisplayValues: () => {
|
||||||
const valuesToShow = legendOptions.values ?? [];
|
const valuesToShow = legendOptions.values ?? [];
|
||||||
let displayValues = [];
|
let displayValues = [];
|
||||||
@ -108,16 +112,18 @@ export const PieChart: FC<Props> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VizLayout width={width} height={height} legend={getLegend(values, legendOptions)}>
|
<VizLayout width={width} height={height} legend={getLegend(fieldDisplayValues, legendOptions)}>
|
||||||
{(vizWidth: number, vizHeight: number) => {
|
{(vizWidth: number, vizHeight: number) => {
|
||||||
return <PieChartSvg width={vizWidth} height={vizHeight} values={values} {...restProps} />;
|
return (
|
||||||
|
<PieChartSvg width={vizWidth} height={vizHeight} fieldDisplayValues={fieldDisplayValues} {...restProps} />
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
</VizLayout>
|
</VizLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PieChartSvg: FC<SvgProps> = ({
|
export const PieChartSvg: FC<SvgProps> = ({
|
||||||
values,
|
fieldDisplayValues,
|
||||||
pieType,
|
pieType,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
@ -127,44 +133,37 @@ export const PieChartSvg: FC<SvgProps> = ({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const componentInstanceId = useComponentInstanceId('PieChart');
|
const componentInstanceId = useComponentInstanceId('PieChart');
|
||||||
const styles = useStyles(getStyles);
|
const styles = useStyles(getStyles);
|
||||||
const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip<DisplayValue>();
|
const tooltip = useTooltip<DisplayValue>();
|
||||||
const { containerRef, TooltipInPortal } = useTooltipInPortal({
|
const { containerRef, TooltipInPortal } = useTooltipInPortal({
|
||||||
detectBounds: true,
|
detectBounds: true,
|
||||||
scroll: true,
|
scroll: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (values.length < 0) {
|
if (fieldDisplayValues.length < 0) {
|
||||||
return <div>No data</div>;
|
return <div>No data</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getValue = (d: DisplayValue) => d.numeric;
|
const getValue = (d: FieldDisplay) => d.display.numeric;
|
||||||
const getGradientId = (color: string) => `${componentInstanceId}-${color}`;
|
const getGradientId = (color: string) => `${componentInstanceId}-${color}`;
|
||||||
const getGradientColor = (color: string) => {
|
const getGradientColor = (color: string) => {
|
||||||
return `url(#${getGradientId(color)})`;
|
return `url(#${getGradientId(color)})`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMouseMoveOverArc = (event: any, datum: any) => {
|
|
||||||
const coords = localPoint(event.target.ownerSVGElement, event);
|
|
||||||
showTooltip({
|
|
||||||
tooltipLeft: coords!.x,
|
|
||||||
tooltipTop: coords!.y,
|
|
||||||
tooltipData: datum,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const showLabel = displayLabels.length > 0;
|
const showLabel = displayLabels.length > 0;
|
||||||
const total = values.reduce((acc, item) => item.numeric + acc, 0);
|
const total = fieldDisplayValues.reduce((acc, item) => item.display.numeric + acc, 0);
|
||||||
const layout = getPieLayout(width, height, pieType);
|
const layout = getPieLayout(width, height, pieType);
|
||||||
|
const colors = [
|
||||||
|
...new Set(fieldDisplayValues.map((fieldDisplayValue) => fieldDisplayValue.display.color ?? FALLBACK_COLOR)),
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<svg width={layout.size} height={layout.size} ref={containerRef}>
|
<svg width={layout.size} height={layout.size} ref={containerRef}>
|
||||||
<Group top={layout.position} left={layout.position}>
|
<Group top={layout.position} left={layout.position}>
|
||||||
{values.map((value) => {
|
{colors.map((color) => {
|
||||||
const color = value.color ?? FALLBACK_COLOR;
|
|
||||||
return (
|
return (
|
||||||
<RadialGradient
|
<RadialGradient
|
||||||
key={value.color}
|
key={color}
|
||||||
id={getGradientId(color)}
|
id={getGradientId(color)}
|
||||||
from={getGradientColorFrom(color, theme)}
|
from={getGradientColorFrom(color, theme)}
|
||||||
to={getGradientColorTo(color, theme)}
|
to={getGradientColorTo(color, theme)}
|
||||||
@ -178,7 +177,7 @@ export const PieChartSvg: FC<SvgProps> = ({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<Pie
|
<Pie
|
||||||
data={values}
|
data={fieldDisplayValues}
|
||||||
pieValue={getValue}
|
pieValue={getValue}
|
||||||
outerRadius={layout.outerRadius}
|
outerRadius={layout.outerRadius}
|
||||||
innerRadius={layout.innerRadius}
|
innerRadius={layout.innerRadius}
|
||||||
@ -187,47 +186,95 @@ export const PieChartSvg: FC<SvgProps> = ({
|
|||||||
>
|
>
|
||||||
{(pie) => {
|
{(pie) => {
|
||||||
return pie.arcs.map((arc) => {
|
return pie.arcs.map((arc) => {
|
||||||
return (
|
const color = arc.data.display.color ?? FALLBACK_COLOR;
|
||||||
<g
|
const label = showLabel ? (
|
||||||
key={arc.data.title}
|
<PieLabel
|
||||||
className={styles.svgArg}
|
arc={arc}
|
||||||
onMouseMove={(event) => onMouseMoveOverArc(event, arc.data)}
|
outerRadius={layout.outerRadius}
|
||||||
onMouseOut={hideTooltip}
|
innerRadius={layout.innerRadius}
|
||||||
>
|
displayLabels={displayLabels}
|
||||||
<path
|
total={total}
|
||||||
d={pie.path({ ...arc })!}
|
color={theme.colors.text}
|
||||||
fill={useGradients ? getGradientColor(arc.data.color ?? FALLBACK_COLOR) : arc.data.color}
|
/>
|
||||||
stroke={theme.colors.panelBg}
|
) : undefined;
|
||||||
strokeWidth={1}
|
if (arc.data.hasLinks && arc.data.getLinks) {
|
||||||
/>
|
return (
|
||||||
{showLabel && (
|
<DataLinksContextMenu config={arc.data.field} key={arc.index} links={arc.data.getLinks}>
|
||||||
<PieLabel
|
{(api) => (
|
||||||
arc={arc}
|
<PieSlice
|
||||||
outerRadius={layout.outerRadius}
|
tooltip={tooltip}
|
||||||
innerRadius={layout.innerRadius}
|
arc={arc}
|
||||||
displayLabels={displayLabels}
|
pie={pie}
|
||||||
total={total}
|
fill={getGradientColor(color)}
|
||||||
color={theme.colors.text}
|
openMenu={api.openMenu}
|
||||||
/>
|
>
|
||||||
)}
|
{label}
|
||||||
</g>
|
</PieSlice>
|
||||||
);
|
)}
|
||||||
|
</DataLinksContextMenu>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<PieSlice key={arc.index} tooltip={tooltip} arc={arc} pie={pie} fill={getGradientColor(color)}>
|
||||||
|
{label}
|
||||||
|
</PieSlice>
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
</Pie>
|
</Pie>
|
||||||
</Group>
|
</Group>
|
||||||
</svg>
|
</svg>
|
||||||
{tooltipOpen && (
|
{tooltip.tooltipOpen && (
|
||||||
<TooltipInPortal key={Math.random()} top={tooltipTop} left={tooltipLeft}>
|
<TooltipInPortal
|
||||||
{tooltipData!.title} {formattedValueToString(tooltipData!)}
|
key={Math.random()}
|
||||||
|
top={tooltip.tooltipTop}
|
||||||
|
className={styles.tooltipPortal}
|
||||||
|
left={tooltip.tooltipLeft}
|
||||||
|
>
|
||||||
|
{tooltip.tooltipData!.title} {formattedValueToString(tooltip.tooltipData!)}
|
||||||
</TooltipInPortal>
|
</TooltipInPortal>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PieSlice: FC<{
|
||||||
|
children: ReactNode;
|
||||||
|
arc: PieArcDatum<FieldDisplay>;
|
||||||
|
pie: ProvidedProps<FieldDisplay>;
|
||||||
|
fill: string;
|
||||||
|
tooltip: UseTooltipParams<DisplayValue>;
|
||||||
|
openMenu?: (event: React.MouseEvent<SVGElement>) => void;
|
||||||
|
}> = ({ arc, children, pie, openMenu, fill, tooltip }) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const styles = useStyles(getStyles);
|
||||||
|
|
||||||
|
const onMouseMoveOverArc = (event: any, datum: any) => {
|
||||||
|
const coords = localPoint(event.target.ownerSVGElement, event);
|
||||||
|
tooltip.showTooltip({
|
||||||
|
tooltipLeft: coords!.x,
|
||||||
|
tooltipTop: coords!.y,
|
||||||
|
tooltipData: datum,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<g
|
||||||
|
key={arc.data.display.title}
|
||||||
|
className={styles.svgArg}
|
||||||
|
onMouseMove={(event) => onMouseMoveOverArc(event, arc.data.display)}
|
||||||
|
onMouseOut={tooltip.hideTooltip}
|
||||||
|
onClick={openMenu}
|
||||||
|
>
|
||||||
|
<path d={pie.path({ ...arc })!} fill={fill} stroke={theme.colors.panelBg} strokeWidth={1} />
|
||||||
|
{children}
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const PieLabel: FC<{
|
const PieLabel: FC<{
|
||||||
arc: PieArcDatum<DisplayValue>;
|
arc: PieArcDatum<FieldDisplay>;
|
||||||
outerRadius: number;
|
outerRadius: number;
|
||||||
innerRadius: number;
|
innerRadius: number;
|
||||||
displayLabels: PieChartLabels[];
|
displayLabels: PieChartLabels[];
|
||||||
@ -259,17 +306,17 @@ const PieLabel: FC<{
|
|||||||
>
|
>
|
||||||
{displayLabels.includes(PieChartLabels.Name) && (
|
{displayLabels.includes(PieChartLabels.Name) && (
|
||||||
<tspan x={labelX} dy="1.2em">
|
<tspan x={labelX} dy="1.2em">
|
||||||
{arc.data.title}
|
{arc.data.display.title}
|
||||||
</tspan>
|
</tspan>
|
||||||
)}
|
)}
|
||||||
{displayLabels.includes(PieChartLabels.Value) && (
|
{displayLabels.includes(PieChartLabels.Value) && (
|
||||||
<tspan x={labelX} dy="1.2em">
|
<tspan x={labelX} dy="1.2em">
|
||||||
{formattedValueToString(arc.data)}
|
{formattedValueToString(arc.data.display)}
|
||||||
</tspan>
|
</tspan>
|
||||||
)}
|
)}
|
||||||
{displayLabels.includes(PieChartLabels.Percent) && (
|
{displayLabels.includes(PieChartLabels.Percent) && (
|
||||||
<tspan x={labelX} dy="1.2em">
|
<tspan x={labelX} dy="1.2em">
|
||||||
{((arc.data.numeric / total) * 100).toFixed(0) + '%'}
|
{((arc.data.display.numeric / total) * 100).toFixed(0) + '%'}
|
||||||
</tspan>
|
</tspan>
|
||||||
)}
|
)}
|
||||||
</text>
|
</text>
|
||||||
@ -277,7 +324,7 @@ const PieLabel: FC<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function getLabelPos(arc: PieArcDatum<DisplayValue>, outerRadius: number, innerRadius: number) {
|
function getLabelPos(arc: PieArcDatum<FieldDisplay>, outerRadius: number, innerRadius: number) {
|
||||||
const r = (outerRadius + innerRadius) / 2;
|
const r = (outerRadius + innerRadius) / 2;
|
||||||
const a = (+arc.startAngle + +arc.endAngle) / 2 - Math.PI / 2;
|
const a = (+arc.startAngle + +arc.endAngle) / 2 - Math.PI / 2;
|
||||||
return [Math.cos(a) * r, Math.sin(a) * r];
|
return [Math.cos(a) * r, Math.sin(a) * r];
|
||||||
@ -337,5 +384,8 @@ const getStyles = (theme: GrafanaTheme) => {
|
|||||||
transform: scale3d(1.03, 1.03, 1);
|
transform: scale3d(1.03, 1.03, 1);
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
tooltipPortal: css`
|
||||||
|
z-index: 1050;
|
||||||
|
`,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -29,7 +29,7 @@ export const VizLegendList: React.FunctionComponent<Props> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getItemKey = (item: VizLegendItem) => `${item.label}`;
|
const getItemKey = (item: VizLegendItem) => `${item.getItemKey ? item.getItemKey() : item.label}`;
|
||||||
|
|
||||||
switch (placement) {
|
switch (placement) {
|
||||||
case 'right': {
|
case 'right': {
|
||||||
|
@ -20,6 +20,7 @@ export interface LegendProps extends VizLegendBaseProps, VizLegendTableProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface VizLegendItem {
|
export interface VizLegendItem {
|
||||||
|
getItemKey?: () => string;
|
||||||
label: string;
|
label: string;
|
||||||
color: string;
|
color: string;
|
||||||
yAxis: number;
|
yAxis: number;
|
||||||
|
@ -23,20 +23,20 @@ export const PieChartPanel: React.FC<Props> = ({
|
|||||||
[fieldConfig, onFieldConfigChange]
|
[fieldConfig, onFieldConfigChange]
|
||||||
);
|
);
|
||||||
|
|
||||||
const values = getFieldDisplayValues({
|
const fieldDisplayValues = getFieldDisplayValues({
|
||||||
fieldConfig,
|
fieldConfig,
|
||||||
reduceOptions: options.reduceOptions,
|
reduceOptions: options.reduceOptions,
|
||||||
data: data.series,
|
data: data.series,
|
||||||
theme: useTheme(),
|
theme: useTheme(),
|
||||||
replaceVariables: replaceVariables,
|
replaceVariables: replaceVariables,
|
||||||
timeZone,
|
timeZone,
|
||||||
}).map((v) => v.display);
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PieChart
|
<PieChart
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
values={values}
|
fieldDisplayValues={fieldDisplayValues}
|
||||||
onSeriesColorChange={onSeriesColorChange}
|
onSeriesColorChange={onSeriesColorChange}
|
||||||
pieType={options.pieType}
|
pieType={options.pieType}
|
||||||
displayLabels={options.displayLabels}
|
displayLabels={options.displayLabels}
|
||||||
|
Loading…
Reference in New Issue
Block a user