mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 18:15:25 +08:00
Grafana-UI: BarGauge docs (#27188)
* Grafana-UI: Add mdx file * Grafana-UI: remove _BarGauge.scss * Grafana-UI: Update snapshot * Grafana-UI: Fix tests * Grafana-UI: Use selector
This commit is contained in:
@ -1,8 +1,9 @@
|
|||||||
import { e2e } from '@grafana/e2e';
|
import { e2e } from '@grafana/e2e';
|
||||||
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
|
|
||||||
e2e.scenario({
|
e2e.scenario({
|
||||||
describeName: 'Bar Gauge Panel',
|
describeName: 'Bar Gauge Panel',
|
||||||
itName: 'Bar Guage rendering e2e tests',
|
itName: 'Bar Gauge rendering e2e tests',
|
||||||
addScenarioDataSource: false,
|
addScenarioDataSource: false,
|
||||||
addScenarioDashBoard: false,
|
addScenarioDashBoard: false,
|
||||||
skipScenario: false,
|
skipScenario: false,
|
||||||
@ -11,7 +12,7 @@ e2e.scenario({
|
|||||||
e2e.flows.openDashboard({ uid: 'O6f11TZWk' });
|
e2e.flows.openDashboard({ uid: 'O6f11TZWk' });
|
||||||
|
|
||||||
e2e()
|
e2e()
|
||||||
.get('#panel-6 .bar-gauge__value')
|
.get(`#panel-6 [aria-label^="${selectors.components.Panels.Visualization.BarGauge.value}"]`)
|
||||||
.should('have.css', 'color', 'rgb(242, 73, 92)')
|
.should('have.css', 'color', 'rgb(242, 73, 92)')
|
||||||
.contains('100');
|
.contains('100');
|
||||||
},
|
},
|
||||||
|
@ -33,6 +33,9 @@ export const Components = {
|
|||||||
labels: () => 'div.flot-x-axis > div.flot-tick-label',
|
labels: () => 'div.flot-x-axis > div.flot-tick-label',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
BarGauge: {
|
||||||
|
value: 'Bar gauge value',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Drawer: {
|
Drawer: {
|
||||||
|
40
packages/grafana-ui/src/components/BarGauge/BarGauge.mdx
Normal file
40
packages/grafana-ui/src/components/BarGauge/BarGauge.mdx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks';
|
||||||
|
import { BarGauge } from './BarGauge';
|
||||||
|
|
||||||
|
<Meta title="MDX|BarGauge" component={BarGauge} />
|
||||||
|
|
||||||
|
# BarGauge
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
```tsx
|
||||||
|
import { BarGauge, BarGaugeDisplayMode } from '@grafana/ui';
|
||||||
|
import { VizOrientation, ThresholdsMode, Field, FieldType, getDisplayProcessor } from '@grafana/data';
|
||||||
|
|
||||||
|
const field: Partial<Field> = {
|
||||||
|
type: FieldType.number,
|
||||||
|
config: {
|
||||||
|
min: minValue,
|
||||||
|
max: maxValue,
|
||||||
|
thresholds: {
|
||||||
|
mode: ThresholdsMode.Absolute,
|
||||||
|
steps: [
|
||||||
|
{ value: -Infinity, color: 'green' },
|
||||||
|
{ value: threshold1Value, color: threshold1Color },
|
||||||
|
{ value: threshold2Value, color: threshold2Color },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
field.display = getDisplayProcessor({ field });
|
||||||
|
|
||||||
|
const value = {
|
||||||
|
text: value.toString(),
|
||||||
|
title: title,
|
||||||
|
numeric: value,
|
||||||
|
};
|
||||||
|
|
||||||
|
//...
|
||||||
|
<BarGauge value={70} field={field.config} display={field.display} value={value} orientation={VizOrientation.Vertical} displayMode={BarGaugeDisplayMode.Basic}/>
|
||||||
|
```
|
||||||
|
|
||||||
|
<Props of={BarGauge} />
|
@ -4,6 +4,7 @@ import { VizOrientation, ThresholdsMode, Field, FieldType, getDisplayProcessor }
|
|||||||
import { Props } from './BarGauge';
|
import { Props } from './BarGauge';
|
||||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||||
import { renderComponentWithTheme } from '../../utils/storybook/withTheme';
|
import { renderComponentWithTheme } from '../../utils/storybook/withTheme';
|
||||||
|
import mdx from './BarGauge.mdx';
|
||||||
|
|
||||||
const getKnobs = () => {
|
const getKnobs = () => {
|
||||||
return {
|
return {
|
||||||
@ -22,6 +23,11 @@ export default {
|
|||||||
title: 'Visualizations/BarGauge',
|
title: 'Visualizations/BarGauge',
|
||||||
component: BarGauge,
|
component: BarGauge,
|
||||||
decorators: [withCenteredStory],
|
decorators: [withCenteredStory],
|
||||||
|
parameters: {
|
||||||
|
docs: {
|
||||||
|
page: mdx,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function addBarGaugeStory(overrides: Partial<Props>) {
|
function addBarGaugeStory(overrides: Partial<Props>) {
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
FieldConfig,
|
FieldConfig,
|
||||||
FieldColorMode,
|
FieldColorMode,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { FormattedValueDisplay } from '../FormattedValueDisplay/FormattedValueDisplay';
|
import { FormattedValueDisplay } from '../FormattedValueDisplay/FormattedValueDisplay';
|
||||||
@ -115,7 +116,11 @@ export class BarGauge extends PureComponent<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={styles.wrapper}>
|
<div style={styles.wrapper}>
|
||||||
<FormattedValueDisplay className="bar-gauge__value" value={value} style={styles.value} />
|
<FormattedValueDisplay
|
||||||
|
aria-label={selectors.components.Panels.Visualization.BarGauge.value}
|
||||||
|
value={value}
|
||||||
|
style={styles.value}
|
||||||
|
/>
|
||||||
{showUnfilled && <div style={styles.emptyBar} />}
|
{showUnfilled && <div style={styles.emptyBar} />}
|
||||||
<div style={styles.bar} />
|
<div style={styles.bar} />
|
||||||
</div>
|
</div>
|
||||||
@ -235,7 +240,11 @@ export class BarGauge extends PureComponent<Props> {
|
|||||||
return (
|
return (
|
||||||
<div style={containerStyles}>
|
<div style={containerStyles}>
|
||||||
{cells}
|
{cells}
|
||||||
<FormattedValueDisplay className="bar-gauge__value" value={value} style={valueStyles} />
|
<FormattedValueDisplay
|
||||||
|
aria-label={selectors.components.Panels.Visualization.BarGauge.value}
|
||||||
|
value={value}
|
||||||
|
style={valueStyles}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
.bar-gauge {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-gauge__value {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
@ -23,7 +23,7 @@ exports[`BarGauge Render with basic options should render 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<FormattedDisplayValue
|
<FormattedDisplayValue
|
||||||
className="bar-gauge__value"
|
aria-label="Bar gauge value"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"alignItems": "center",
|
"alignItems": "center",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { FC, CSSProperties } from 'react';
|
import React, { FC, CSSProperties, HTMLProps } from 'react';
|
||||||
import { FormattedValue } from '@grafana/data';
|
import { FormattedValue } from '@grafana/data';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props extends Omit<HTMLProps<HTMLDivElement>, 'className' | 'value' | 'style'> {
|
||||||
className?: string;
|
className?: string;
|
||||||
value: FormattedValue;
|
value: FormattedValue;
|
||||||
style: CSSProperties;
|
style: CSSProperties;
|
||||||
@ -17,14 +17,14 @@ function fontSizeReductionFactor(fontSize: number) {
|
|||||||
return 0.6;
|
return 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FormattedValueDisplay: FC<Props> = ({ value, className, style }) => {
|
export const FormattedValueDisplay: FC<Props> = ({ value, className, style, ...htmlProps }) => {
|
||||||
const fontSize = style.fontSize as number;
|
const fontSize = style.fontSize as number;
|
||||||
const reductionFactor = fontSizeReductionFactor(fontSize);
|
const reductionFactor = fontSizeReductionFactor(fontSize);
|
||||||
const hasPrefix = (value.prefix ?? '').length > 0;
|
const hasPrefix = (value.prefix ?? '').length > 0;
|
||||||
const hasSuffix = (value.suffix ?? '').length > 0;
|
const hasSuffix = (value.suffix ?? '').length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className} style={style}>
|
<div className={className} style={style} {...htmlProps}>
|
||||||
<div>
|
<div>
|
||||||
{hasPrefix && <span>{value.prefix}</span>}
|
{hasPrefix && <span>{value.prefix}</span>}
|
||||||
<span>{value.text}</span>
|
<span>{value.text}</span>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
@import 'BarGauge/BarGauge';
|
|
||||||
@import 'ButtonCascader/ButtonCascader';
|
@import 'ButtonCascader/ButtonCascader';
|
||||||
@import 'ColorPicker/ColorPicker';
|
@import 'ColorPicker/ColorPicker';
|
||||||
@import 'CustomScrollbar/CustomScrollbar';
|
@import 'CustomScrollbar/CustomScrollbar';
|
||||||
|
@ -12,10 +12,13 @@ import {
|
|||||||
toDataFrame,
|
toDataFrame,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { BarGaugeDisplayMode } from '@grafana/ui';
|
import { BarGaugeDisplayMode } from '@grafana/ui';
|
||||||
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
|
|
||||||
import { BarGaugePanel } from './BarGaugePanel';
|
import { BarGaugePanel } from './BarGaugePanel';
|
||||||
import { BarGaugeOptions } from './types';
|
import { BarGaugeOptions } from './types';
|
||||||
|
|
||||||
|
const valueSelector = selectors.components.Panels.Visualization.BarGauge.value;
|
||||||
|
|
||||||
describe('BarGaugePanel', () => {
|
describe('BarGaugePanel', () => {
|
||||||
describe('when empty result is rendered', () => {
|
describe('when empty result is rendered', () => {
|
||||||
const wrapper = createBarGaugePanelWithData({
|
const wrapper = createBarGaugePanelWithData({
|
||||||
@ -25,7 +28,7 @@ describe('BarGaugePanel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should render with title "No data"', () => {
|
it('should render with title "No data"', () => {
|
||||||
const displayValue = wrapper.find('div.bar-gauge__value').text();
|
const displayValue = wrapper.find(`div[aria-label="${valueSelector}"]`).text();
|
||||||
expect(displayValue).toBe('No data');
|
expect(displayValue).toBe('No data');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -46,7 +49,7 @@ describe('BarGaugePanel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should render with title "No data"', () => {
|
it('should render with title "No data"', () => {
|
||||||
const displayValue = wrapper.find('div.bar-gauge__value').text();
|
const displayValue = wrapper.find(`div[aria-label="${valueSelector}"]`).text();
|
||||||
expect(displayValue).toBe('100');
|
expect(displayValue).toBe('100');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user