123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- import {Fragment} from 'react';
- import styled from '@emotion/styled';
- import JSXNode from 'sentry/components/stories/jsxNode';
- import JSXProperty from 'sentry/components/stories/jsxProperty';
- import SideBySide from 'sentry/components/stories/sideBySide';
- import SizingWindow from 'sentry/components/stories/sizingWindow';
- import storyBook from 'sentry/stories/storyBook';
- import {BigNumberWidget} from 'sentry/views/dashboards/widgets/bigNumberWidget/bigNumberWidget';
- export default storyBook(BigNumberWidget, story => {
- story('Getting Started', () => {
- return (
- <Fragment>
- <p>
- <JSXNode name="BigNumberWidget" /> is a Dashboard Widget Component. It displays
- a single large value. Used in places like Dashboards Big Number widgets, Project
- Details pages, and Organization Stats pages.
- </p>
- </Fragment>
- );
- });
- story('Visualization', () => {
- return (
- <Fragment>
- <p>
- The visualization of <JSXNode name="BigNumberWidget" /> a large number, just
- like it says on the tin. Depending on the data passed to it, it intelligently
- rounds and humanizes the results. If the number is humanized, hovering over the
- visualization shows a tooltip with the full value.
- </p>
- <p>
- <JSXNode name="BigNumberWidget" /> also supports string values. This is not
- commonly used, but it's capable of rendering timestamps and in fact most fields
- defined in our field renderer pipeline
- </p>
- <SideBySide>
- <SmallSizingWindow>
- <BigNumberWidget
- title="EPS"
- description="Number of events per second"
- data={[
- {
- 'eps()': 0.01087819860850493,
- },
- ]}
- meta={{
- fields: {
- 'eps()': 'rate',
- },
- units: {
- 'eps()': '1/second',
- },
- }}
- thresholds={{
- max_values: {
- max1: 1,
- max2: 2,
- },
- unit: '1/second',
- }}
- />
- </SmallSizingWindow>
- <SmallSizingWindow>
- <BigNumberWidget
- title="Count"
- data={[
- {
- 'count()': 178451214,
- },
- ]}
- meta={{
- fields: {
- 'count()': 'integer',
- },
- units: {
- 'count()': null,
- },
- }}
- />
- </SmallSizingWindow>
- <SmallSizingWindow>
- <BigNumberWidget
- title="Query Duration"
- description="p95(span.duration)"
- data={[
- {
- 'p95(span.duration)': 17.28,
- },
- ]}
- meta={{
- fields: {
- 'p95(span.duration)': 'duration',
- },
- units: {
- 'p95(spa.duration)': 'milliseconds',
- },
- }}
- />
- </SmallSizingWindow>
- <SmallSizingWindow>
- <BigNumberWidget
- title="Latest Timestamp"
- description=""
- data={[
- {
- 'max(timestamp)': '2024-10-17T16:08:07+00:00',
- },
- ]}
- meta={{
- fields: {
- 'max(timestamp)': 'date',
- },
- units: {
- 'max(timestamp)': null,
- },
- }}
- />
- </SmallSizingWindow>
- </SideBySide>
- <p>
- The <code>maximumValue</code> prop allows setting the maximum displayable value.
- e.g., imagine a widget that displays a count. A count of more than a million is
- too expensive for the API to compute, so the API returns a maximum of 1,000,000.
- If the API returns exactly 1,000,000, that means the actual number is unknown,
- something higher than the max. Setting{' '}
- <JSXProperty name="maximumValue" value={1000000} /> will show >1m.
- </p>
- <SideBySide>
- <NormalWidget>
- <BigNumberWidget
- title="Count"
- data={[
- {
- 'count()': 1000000,
- },
- ]}
- maximumValue={1000000}
- meta={{
- fields: {
- 'count()': 'integer',
- },
- }}
- />
- </NormalWidget>
- </SideBySide>
- </Fragment>
- );
- });
- story('State', () => {
- return (
- <Fragment>
- <p>
- <JSXNode name="BigNumberWidget" /> supports the usual loading and error states.
- The loading state shows a simple placeholder. The error state also shows an
- optional "Retry" button.
- </p>
- <SideBySide>
- <NormalWidget>
- <BigNumberWidget title="Loading Count" isLoading />
- </NormalWidget>
- <NormalWidget>
- <BigNumberWidget title="Missing Count" data={[{}]} />
- </NormalWidget>
- <NormalWidget>
- <BigNumberWidget
- title="Count Error"
- error={new Error('Something went wrong!')}
- />
- </NormalWidget>
- <NormalWidget>
- <BigNumberWidget
- title="Data Error"
- error={new Error('Something went wrong!')}
- onRetry={() => {}}
- />
- </NormalWidget>
- </SideBySide>
- </Fragment>
- );
- });
- story('Previous Period Data', () => {
- return (
- <Fragment>
- <p>
- <JSXNode name="BigNumberWidget" /> shows the difference of the current data and
- the previous period data as the difference between the two values, in small text
- next to the main value.
- </p>
- <p>
- The <code>preferredPolarity</code> prop controls the color of the comparison
- string. Setting <JSXProperty name="preferredPolarity" value={'+'} /> mean that a
- higher number is <i>better</i> and will paint increases in the value green. Vice
- versa with negative polarity. Omitting a preferred polarity will prevent
- colorization.
- </p>
- <SideBySide>
- <NormalWidget>
- <BigNumberWidget
- title="eps()"
- data={[
- {
- 'eps()': 17.1087819860850493,
- },
- ]}
- previousPeriodData={[
- {
- 'eps()': 15.0088607819850493,
- },
- ]}
- meta={{
- fields: {
- 'eps()': 'rate',
- },
- units: {
- 'eps()': '1/second',
- },
- }}
- />
- </NormalWidget>
- <NormalWidget>
- <BigNumberWidget
- title="http_rate(500)"
- data={[
- {
- 'http_rate(500)': 0.14227123,
- },
- ]}
- previousPeriodData={[
- {
- 'http_rate(500)': 0.1728139,
- },
- ]}
- preferredPolarity="-"
- meta={{
- fields: {
- 'http_rate(500)': 'percentage',
- },
- }}
- />
- </NormalWidget>
- <NormalWidget>
- <BigNumberWidget
- title="http_rate(200)"
- data={[
- {
- 'http_rate(200)': 0.14227123,
- },
- ]}
- previousPeriodData={[
- {
- 'http_rate(200)': 0.1728139,
- },
- ]}
- preferredPolarity="+"
- meta={{
- fields: {
- 'http_rate(200)': 'percentage',
- },
- }}
- />
- </NormalWidget>
- </SideBySide>
- </Fragment>
- );
- });
- story('Thresholds', () => {
- const meta = {
- fields: {
- 'eps()': 'rate',
- },
- units: {
- 'eps()': '1/second',
- },
- };
- const thresholds = {
- max_values: {
- max1: 20,
- max2: 50,
- },
- unit: '1/second',
- };
- return (
- <Fragment>
- <p>
- <JSXNode name="BigNumberWidget" /> supports a <code>thresholds</code> prop. If
- specified, the value of the data in the widget will be evaluated against these
- thresholds, and indicated using a colorful circle next to the value.
- </p>
- <SideBySide>
- <NormalWidget>
- <BigNumberWidget
- title="eps()"
- data={[
- {
- 'eps()': 7.1,
- },
- ]}
- meta={meta}
- thresholds={thresholds}
- preferredPolarity="+"
- />
- </NormalWidget>
- <NormalWidget>
- <BigNumberWidget
- title="eps()"
- data={[
- {
- 'eps()': 27.781,
- },
- ]}
- meta={meta}
- thresholds={thresholds}
- preferredPolarity="-"
- />
- </NormalWidget>
- <NormalWidget>
- <BigNumberWidget
- title="eps()"
- data={[
- {
- 'eps()': 78.1,
- },
- ]}
- meta={meta}
- thresholds={thresholds}
- preferredPolarity="+"
- />
- </NormalWidget>
- </SideBySide>
- <p>
- The thresholds respect the preferred polarity. By default, the preferred
- polarity is positive (higher numbers are good).
- </p>
- <SideBySide>
- <NormalWidget>
- <BigNumberWidget
- title="eps()"
- data={[
- {
- 'eps()': 7.1,
- },
- ]}
- meta={meta}
- thresholds={thresholds}
- preferredPolarity="-"
- />
- </NormalWidget>
- <NormalWidget>
- <BigNumberWidget
- title="eps()"
- data={[
- {
- 'eps()': 27.781,
- },
- ]}
- meta={meta}
- thresholds={thresholds}
- preferredPolarity="-"
- />
- </NormalWidget>
- <NormalWidget>
- <BigNumberWidget
- title="eps()"
- data={[
- {
- 'eps()': 78.1,
- },
- ]}
- meta={meta}
- thresholds={thresholds}
- preferredPolarity="-"
- />
- </NormalWidget>
- </SideBySide>
- </Fragment>
- );
- });
- });
- const SmallSizingWindow = styled(SizingWindow)`
- width: auto;
- height: 200px;
- `;
- const NormalWidget = styled('div')`
- width: 250px;
- `;
|