mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-10 22:18:59 +08:00
feat: y-axis units for pre-defined and dashboard graphs
This commit is contained in:
parent
f2ace729fd
commit
0b6f31420b
@ -22,10 +22,11 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^4.6.2",
|
"@ant-design/icons": "^4.6.2",
|
||||||
|
"@grafana/data": "^8.4.3",
|
||||||
"@testing-library/jest-dom": "^5.11.4",
|
"@testing-library/jest-dom": "^5.11.4",
|
||||||
"@testing-library/react": "^11.1.0",
|
"@testing-library/react": "^11.1.0",
|
||||||
"@testing-library/user-event": "^12.1.10",
|
"@testing-library/user-event": "^12.1.10",
|
||||||
"antd": "^4.16.13",
|
"antd": "4.19.2",
|
||||||
"axios": "^0.21.0",
|
"axios": "^0.21.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"babel-jest": "^26.6.0",
|
"babel-jest": "^26.6.0",
|
||||||
@ -63,6 +64,7 @@
|
|||||||
"react-vis": "^1.11.7",
|
"react-vis": "^1.11.7",
|
||||||
"redux": "^4.0.5",
|
"redux": "^4.0.5",
|
||||||
"redux-thunk": "^2.3.0",
|
"redux-thunk": "^2.3.0",
|
||||||
|
"stream": "^0.0.2",
|
||||||
"style-loader": "1.3.0",
|
"style-loader": "1.3.0",
|
||||||
"styled-components": "^5.2.1",
|
"styled-components": "^5.2.1",
|
||||||
"terser-webpack-plugin": "^5.2.5",
|
"terser-webpack-plugin": "^5.2.5",
|
||||||
|
@ -28,6 +28,8 @@ import { AppState } from 'store/reducers';
|
|||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
|
|
||||||
import { useXAxisTimeUnit } from './xAxisConfig';
|
import { useXAxisTimeUnit } from './xAxisConfig';
|
||||||
|
import { getYAxisFormattedValue } from './yAxisConfig';
|
||||||
|
|
||||||
Chart.register(
|
Chart.register(
|
||||||
LineElement,
|
LineElement,
|
||||||
PointElement,
|
PointElement,
|
||||||
@ -55,6 +57,7 @@ const Graph = ({
|
|||||||
isStacked,
|
isStacked,
|
||||||
onClickHandler,
|
onClickHandler,
|
||||||
name,
|
name,
|
||||||
|
yAxisUnit = 'short',
|
||||||
}: GraphProps): JSX.Element => {
|
}: GraphProps): JSX.Element => {
|
||||||
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||||
const chartRef = useRef<HTMLCanvasElement>(null);
|
const chartRef = useRef<HTMLCanvasElement>(null);
|
||||||
@ -132,6 +135,12 @@ const Graph = ({
|
|||||||
display: true,
|
display: true,
|
||||||
color: getGridColor(),
|
color: getGridColor(),
|
||||||
},
|
},
|
||||||
|
ticks: {
|
||||||
|
// Include a dollar sign in the ticks
|
||||||
|
callback: function (value, index, ticks) {
|
||||||
|
return getYAxisFormattedValue(value, yAxisUnit);
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
stacked: {
|
stacked: {
|
||||||
display: isStacked === undefined ? false : 'auto',
|
display: isStacked === undefined ? false : 'auto',
|
||||||
@ -179,6 +188,7 @@ interface GraphProps {
|
|||||||
label?: string[];
|
label?: string[];
|
||||||
onClickHandler?: graphOnClickHandler;
|
onClickHandler?: graphOnClickHandler;
|
||||||
name: string;
|
name: string;
|
||||||
|
yAxisUnit?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type graphOnClickHandler = (
|
export type graphOnClickHandler = (
|
||||||
|
16
frontend/src/components/Graph/yAxisConfig.ts
Normal file
16
frontend/src/components/Graph/yAxisConfig.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { formattedValueToString, getValueFormat } from '@grafana/data';
|
||||||
|
|
||||||
|
export const getYAxisFormattedValue = (
|
||||||
|
value: number,
|
||||||
|
format: string,
|
||||||
|
decimal?: number,
|
||||||
|
): string => {
|
||||||
|
try {
|
||||||
|
return formattedValueToString(
|
||||||
|
getValueFormat(format)(value, undefined, undefined, undefined),
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
return `${value}`;
|
||||||
|
};
|
@ -16,6 +16,7 @@ const GridGraphComponent = ({
|
|||||||
isStacked,
|
isStacked,
|
||||||
onClickHandler,
|
onClickHandler,
|
||||||
name,
|
name,
|
||||||
|
yAxisUnit,
|
||||||
}: GridGraphComponentProps): JSX.Element | null => {
|
}: GridGraphComponentProps): JSX.Element | null => {
|
||||||
const location = history.location.pathname;
|
const location = history.location.pathname;
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ const GridGraphComponent = ({
|
|||||||
xAxisType: 'time',
|
xAxisType: 'time',
|
||||||
onClickHandler: onClickHandler,
|
onClickHandler: onClickHandler,
|
||||||
name,
|
name,
|
||||||
|
yAxisUnit: yAxisUnit,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -72,6 +74,7 @@ export interface GridGraphComponentProps {
|
|||||||
isStacked?: boolean;
|
isStacked?: boolean;
|
||||||
onClickHandler?: graphOnClickHandler;
|
onClickHandler?: graphOnClickHandler;
|
||||||
name: string;
|
name: string;
|
||||||
|
yAxisUnit?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GridGraphComponent;
|
export default GridGraphComponent;
|
||||||
|
@ -32,6 +32,7 @@ const FullView = ({
|
|||||||
onClickHandler,
|
onClickHandler,
|
||||||
noDataGraph = false,
|
noDataGraph = false,
|
||||||
name,
|
name,
|
||||||
|
yAxisUnit,
|
||||||
}: FullViewProps): JSX.Element => {
|
}: FullViewProps): JSX.Element => {
|
||||||
const { minTime, maxTime, selectedTime: globalSelectedTime } = useSelector<
|
const { minTime, maxTime, selectedTime: globalSelectedTime } = useSelector<
|
||||||
AppState,
|
AppState,
|
||||||
@ -221,6 +222,7 @@ const FullView = ({
|
|||||||
title: widget.title,
|
title: widget.title,
|
||||||
onClickHandler: onClickHandler,
|
onClickHandler: onClickHandler,
|
||||||
name,
|
name,
|
||||||
|
yAxisUnit,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{/* </GraphContainer> */}
|
{/* </GraphContainer> */}
|
||||||
@ -241,6 +243,7 @@ interface FullViewProps {
|
|||||||
onClickHandler?: graphOnClickHandler;
|
onClickHandler?: graphOnClickHandler;
|
||||||
noDataGraph?: boolean;
|
noDataGraph?: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
|
yAxisUnit?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FullView;
|
export default FullView;
|
||||||
|
@ -30,6 +30,7 @@ const GridCardGraph = ({
|
|||||||
deleteWidget,
|
deleteWidget,
|
||||||
isDeleted,
|
isDeleted,
|
||||||
name,
|
name,
|
||||||
|
yAxisUnit
|
||||||
}: GridCardGraphProps): JSX.Element => {
|
}: GridCardGraphProps): JSX.Element => {
|
||||||
const [state, setState] = useState<GridCardGraphState>({
|
const [state, setState] = useState<GridCardGraphState>({
|
||||||
loading: true,
|
loading: true,
|
||||||
@ -149,7 +150,7 @@ const GridCardGraph = ({
|
|||||||
destroyOnClose
|
destroyOnClose
|
||||||
>
|
>
|
||||||
<FullViewContainer>
|
<FullViewContainer>
|
||||||
<FullView name={name + 'expanded'} widget={widget} />
|
<FullView name={name + 'expanded'} widget={widget} yAxisUnit={yAxisUnit} />
|
||||||
</FullViewContainer>
|
</FullViewContainer>
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
@ -199,6 +200,7 @@ const GridCardGraph = ({
|
|||||||
opacity: widget.opacity,
|
opacity: widget.opacity,
|
||||||
title: widget.title,
|
title: widget.title,
|
||||||
name,
|
name,
|
||||||
|
yAxisUnit,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
@ -222,6 +224,7 @@ interface GridCardGraphProps extends DispatchProps {
|
|||||||
widget: Widgets;
|
widget: Widgets;
|
||||||
isDeleted: React.MutableRefObject<boolean>;
|
isDeleted: React.MutableRefObject<boolean>;
|
||||||
name: string;
|
name: string;
|
||||||
|
yAxisUnit: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = (
|
const mapDispatchToProps = (
|
||||||
|
@ -38,7 +38,6 @@ const GridGraph = (): JSX.Element => {
|
|||||||
const [selectedDashboard] = dashboards;
|
const [selectedDashboard] = dashboards;
|
||||||
const { data } = selectedDashboard;
|
const { data } = selectedDashboard;
|
||||||
const { widgets } = data;
|
const { widgets } = data;
|
||||||
|
|
||||||
const [layouts, setLayout] = useState<LayoutProps[]>([]);
|
const [layouts, setLayout] = useState<LayoutProps[]>([]);
|
||||||
|
|
||||||
const AddWidgetWrapper = useCallback(() => <AddWidget />, []);
|
const AddWidgetWrapper = useCallback(() => <AddWidget />, []);
|
||||||
@ -64,6 +63,7 @@ const GridGraph = (): JSX.Element => {
|
|||||||
name={e.id + index + 'non-expanded'}
|
name={e.id + index + 'non-expanded'}
|
||||||
isDeleted={isDeleted}
|
isDeleted={isDeleted}
|
||||||
widget={widgets[index]}
|
widget={widgets[index]}
|
||||||
|
yAxisUnit={e.yAxisUnit}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@ -73,7 +73,11 @@ const GridGraph = (): JSX.Element => {
|
|||||||
...e,
|
...e,
|
||||||
y: 0,
|
y: 0,
|
||||||
Component: (): JSX.Element => (
|
Component: (): JSX.Element => (
|
||||||
<Graph name={e.i + index} isDeleted={isDeleted} widget={widgets[index]} />
|
<Graph
|
||||||
|
name={e.i + index}
|
||||||
|
isDeleted={isDeleted}
|
||||||
|
widget={widgets[index]}
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,7 @@ const Application = ({ getWidget }: DashboardProps): JSX.Element => {
|
|||||||
urlParams.set(METRICS_PAGE_QUERY_PARAM.endTime, tPlusOne.toString());
|
urlParams.set(METRICS_PAGE_QUERY_PARAM.endTime, tPlusOne.toString());
|
||||||
|
|
||||||
history.replace(
|
history.replace(
|
||||||
`${
|
`${ROUTES.TRACE
|
||||||
ROUTES.TRACE
|
|
||||||
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"],"status":["ok","error"]}&filterToFetchData=["duration","status","serviceName"]&userSelectedFilter={"status":["error","ok"],"serviceName":["${servicename}"]}&isSelectedFilterSkipped=true`,
|
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"],"status":["ok","error"]}&filterToFetchData=["duration","status","serviceName"]&userSelectedFilter={"status":["error","ok"],"serviceName":["${servicename}"]}&isSelectedFilterSkipped=true`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -88,8 +87,7 @@ const Application = ({ getWidget }: DashboardProps): JSX.Element => {
|
|||||||
urlParams.set(METRICS_PAGE_QUERY_PARAM.endTime, tPlusOne.toString());
|
urlParams.set(METRICS_PAGE_QUERY_PARAM.endTime, tPlusOne.toString());
|
||||||
|
|
||||||
history.replace(
|
history.replace(
|
||||||
`${
|
`${ROUTES.TRACE
|
||||||
ROUTES.TRACE
|
|
||||||
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"],"status":["error"]}&filterToFetchData=["duration","status","serviceName"]&userSelectedFilter={"status":["error"],"serviceName":["${servicename}"]}&isSelectedFilterSkipped=true`,
|
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"],"status":["error"]}&filterToFetchData=["duration","status","serviceName"]&userSelectedFilter={"status":["error"],"serviceName":["${servicename}"]}&isSelectedFilterSkipped=true`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -159,6 +157,7 @@ const Application = ({ getWidget }: DashboardProps): JSX.Element => {
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
}}
|
}}
|
||||||
|
yAxisUnit="ms"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
@ -191,6 +190,7 @@ const Application = ({ getWidget }: DashboardProps): JSX.Element => {
|
|||||||
legend: 'Request per second',
|
legend: 'Request per second',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
|
yAxisUnit="short"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
@ -225,6 +225,7 @@ const Application = ({ getWidget }: DashboardProps): JSX.Element => {
|
|||||||
legend: 'Error Percentage (%)',
|
legend: 'Error Percentage (%)',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
|
yAxisUnit="%"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -26,6 +26,7 @@ const DBCall = ({ getWidget }: DBCallProps): JSX.Element => {
|
|||||||
legend: '{{db_system}}',
|
legend: '{{db_system}}',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
|
yAxisUnit="short"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
@ -45,6 +46,7 @@ const DBCall = ({ getWidget }: DBCallProps): JSX.Element => {
|
|||||||
legend: '',
|
legend: '',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
|
yAxisUnit="ms"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -26,6 +26,7 @@ const External = ({ getWidget }: ExternalProps): JSX.Element => {
|
|||||||
legend: '{{http_url}}',
|
legend: '{{http_url}}',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
|
yAxisUnit="%"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
@ -45,6 +46,7 @@ const External = ({ getWidget }: ExternalProps): JSX.Element => {
|
|||||||
legend: 'Average Duration',
|
legend: 'Average Duration',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
|
yAxisUnit="ms"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
@ -66,6 +68,7 @@ const External = ({ getWidget }: ExternalProps): JSX.Element => {
|
|||||||
legend: '{{http_url}}',
|
legend: '{{http_url}}',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
|
yAxisUnit="short"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
@ -85,6 +88,7 @@ const External = ({ getWidget }: ExternalProps): JSX.Element => {
|
|||||||
legend: '{{http_url}}',
|
legend: '{{http_url}}',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
|
yAxisUnit="ms"
|
||||||
/>
|
/>
|
||||||
</GraphContainer>
|
</GraphContainer>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -10,7 +10,7 @@ import DashboardReducer from 'types/reducer/dashboards';
|
|||||||
|
|
||||||
import { NotFoundContainer } from './styles';
|
import { NotFoundContainer } from './styles';
|
||||||
|
|
||||||
const WidgetGraph = ({ selectedGraph }: WidgetGraphProps): JSX.Element => {
|
const WidgetGraph = ({ selectedGraph,yAxisUnit }: WidgetGraphProps): JSX.Element => {
|
||||||
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
||||||
(state) => state.dashboards,
|
(state) => state.dashboards,
|
||||||
);
|
);
|
||||||
@ -51,6 +51,7 @@ const WidgetGraph = ({ selectedGraph }: WidgetGraphProps): JSX.Element => {
|
|||||||
data={chartDataSet}
|
data={chartDataSet}
|
||||||
GRAPH_TYPES={selectedGraph}
|
GRAPH_TYPES={selectedGraph}
|
||||||
name={widgetId || 'legend_widget'}
|
name={widgetId || 'legend_widget'}
|
||||||
|
yAxisUnit={yAxisUnit}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,7 @@ import { NewWidgetProps } from '../../index';
|
|||||||
import { AlertIconContainer, Container, NotFoundContainer } from './styles';
|
import { AlertIconContainer, Container, NotFoundContainer } from './styles';
|
||||||
import WidgetGraphComponent from './WidgetGraph';
|
import WidgetGraphComponent from './WidgetGraph';
|
||||||
|
|
||||||
const WidgetGraph = ({ selectedGraph }: WidgetGraphProps): JSX.Element => {
|
const WidgetGraph = ({ selectedGraph, yAxisUnit }: WidgetGraphProps): JSX.Element => {
|
||||||
const { dashboards, isQueryFired } = useSelector<AppState, DashboardReducer>(
|
const { dashboards, isQueryFired } = useSelector<AppState, DashboardReducer>(
|
||||||
(state) => state.dashboards,
|
(state) => state.dashboards,
|
||||||
);
|
);
|
||||||
@ -47,7 +47,7 @@ const WidgetGraph = ({ selectedGraph }: WidgetGraphProps): JSX.Element => {
|
|||||||
</NotFoundContainer>
|
</NotFoundContainer>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isQueryFired && <WidgetGraphComponent selectedGraph={selectedGraph} />}
|
{isQueryFired && <WidgetGraphComponent selectedGraph={selectedGraph} yAxisUnit={yAxisUnit} />}
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -9,10 +9,11 @@ import WidgetGraph from './WidgetGraph';
|
|||||||
const LeftContainer = ({
|
const LeftContainer = ({
|
||||||
selectedGraph,
|
selectedGraph,
|
||||||
selectedTime,
|
selectedTime,
|
||||||
|
yAxisUnit,
|
||||||
}: LeftContainerProps): JSX.Element => {
|
}: LeftContainerProps): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<WidgetGraph selectedGraph={selectedGraph} />
|
<WidgetGraph selectedGraph={selectedGraph} yAxisUnit={yAxisUnit}/>
|
||||||
|
|
||||||
<QueryContainer>
|
<QueryContainer>
|
||||||
<QuerySection selectedTime={selectedTime} />
|
<QuerySection selectedTime={selectedTime} />
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
import { AutoComplete, Col, Input, Typography } from 'antd';
|
||||||
|
import { find } from 'lodash-es';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { flattenedCategories } from './dataFormatCategories';
|
||||||
|
|
||||||
|
const findCategoryById = (searchValue) =>
|
||||||
|
find(flattenedCategories, (option) => option.id == searchValue);
|
||||||
|
const findCategoryByName = (searchValue) =>
|
||||||
|
find(flattenedCategories, (option) => option.name == searchValue);
|
||||||
|
|
||||||
|
const YAxisUnitSelector = ({ defaultValue, onSelect }): JSX.Element => {
|
||||||
|
const onSelectHandler = (selectedValue: string): void => {
|
||||||
|
onSelect(findCategoryByName(selectedValue)?.id);
|
||||||
|
};
|
||||||
|
const options = flattenedCategories.map((options) => ({
|
||||||
|
value: options.name,
|
||||||
|
}));
|
||||||
|
return (
|
||||||
|
<Col style={{ marginTop: '1rem' }}>
|
||||||
|
<div style={{ margin: '0.5rem 0' }}>
|
||||||
|
<Typography.Text>Y Axis Unit</Typography.Text>
|
||||||
|
</div>
|
||||||
|
<AutoComplete
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
options={options}
|
||||||
|
defaultValue={findCategoryById(defaultValue)?.name}
|
||||||
|
onSelect={onSelectHandler}
|
||||||
|
filterOption={(inputValue, option): boolean =>
|
||||||
|
option!.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Input size="large" placeholder="Unit" allowClear />
|
||||||
|
</AutoComplete>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default YAxisUnitSelector;
|
@ -0,0 +1,390 @@
|
|||||||
|
import { flattenDeep } from 'lodash-es';
|
||||||
|
|
||||||
|
export const dataTypeCategories = [
|
||||||
|
{
|
||||||
|
name: 'Time',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Hertz (1/s)', id: 'hertz' },
|
||||||
|
{ name: 'nanoseconds (ns)', id: 'ns' },
|
||||||
|
{ name: 'microseconds (µs)', id: 'µs' },
|
||||||
|
{ name: 'milliseconds (ms)', id: 'ms' },
|
||||||
|
{ name: 'seconds (s)', id: 's' },
|
||||||
|
{ name: 'minutes (m)', id: 'm' },
|
||||||
|
{ name: 'hours (h)', id: 'h' },
|
||||||
|
{ name: 'days (d)', id: 'd' },
|
||||||
|
{ name: 'duration (ms)', id: 'dtdurationms' },
|
||||||
|
{ name: 'duration (s)', id: 'dtdurations' },
|
||||||
|
{ name: 'duration (hh:mm:ss)', id: 'dthms' },
|
||||||
|
{ name: 'duration (d hh:mm:ss)', id: 'dtdhms' },
|
||||||
|
{ name: 'Timeticks (s/100)', id: 'timeticks' },
|
||||||
|
{ name: 'clock (ms)', id: 'clockms' },
|
||||||
|
{ name: 'clock (s)', id: 'clocks' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Throughput',
|
||||||
|
formats: [
|
||||||
|
{ name: 'counts/sec (cps)', id: 'cps' },
|
||||||
|
{ name: 'ops/sec (ops)', id: 'ops' },
|
||||||
|
{ name: 'requests/sec (rps)', id: 'reqps' },
|
||||||
|
{ name: 'reads/sec (rps)', id: 'rps' },
|
||||||
|
{ name: 'writes/sec (wps)', id: 'wps' },
|
||||||
|
{ name: 'I/O ops/sec (iops)', id: 'iops' },
|
||||||
|
{ name: 'counts/min (cpm)', id: 'cpm' },
|
||||||
|
{ name: 'ops/min (opm)', id: 'opm' },
|
||||||
|
{ name: 'reads/min (rpm)', id: 'rpm' },
|
||||||
|
{ name: 'writes/min (wpm)', id: 'wpm' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Data',
|
||||||
|
formats: [
|
||||||
|
{ name: 'bytes(IEC)', id: 'bytes' },
|
||||||
|
{ name: 'bytes(SI)', id: 'decbytes' },
|
||||||
|
{ name: 'bits(IEC)', id: 'bits' },
|
||||||
|
{ name: 'bits(SI)', id: 'decbits' },
|
||||||
|
{ name: 'kibibytes', id: 'kbytes' },
|
||||||
|
{ name: 'kilobytes', id: 'deckbytes' },
|
||||||
|
{ name: 'mebibytes', id: 'mbytes' },
|
||||||
|
{ name: 'megabytes', id: 'decmbytes' },
|
||||||
|
{ name: 'gibibytes', id: 'gbytes' },
|
||||||
|
{ name: 'gigabytes', id: 'decgbytes' },
|
||||||
|
{ name: 'tebibytes', id: 'tbytes' },
|
||||||
|
{ name: 'terabytes', id: 'dectbytes' },
|
||||||
|
{ name: 'pebibytes', id: 'pbytes' },
|
||||||
|
{ name: 'petabytes', id: 'decpbytes' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Data rate',
|
||||||
|
formats: [
|
||||||
|
{ name: 'packets/sec', id: 'pps' },
|
||||||
|
{ name: 'bytes/sec(IEC)', id: 'binBps' },
|
||||||
|
{ name: 'bytes/sec(SI)', id: 'Bps' },
|
||||||
|
{ name: 'bits/sec(IEC)', id: 'binbps' },
|
||||||
|
{ name: 'bits/sec(SI)', id: 'bps' },
|
||||||
|
{ name: 'kibibytes/sec', id: 'KiBs' },
|
||||||
|
{ name: 'kibibits/sec', id: 'Kibits' },
|
||||||
|
{ name: 'kilobytes/sec', id: 'KBs' },
|
||||||
|
{ name: 'kilobits/sec', id: 'Kbits' },
|
||||||
|
{ name: 'mebibytes/sec', id: 'MiBs' },
|
||||||
|
{ name: 'mebibits/sec', id: 'Mibits' },
|
||||||
|
{ name: 'megabytes/sec', id: 'MBs' },
|
||||||
|
{ name: 'megabits/sec', id: 'Mbits' },
|
||||||
|
{ name: 'gibibytes/sec', id: 'GiBs' },
|
||||||
|
{ name: 'gibibits/sec', id: 'Gibits' },
|
||||||
|
{ name: 'gigabytes/sec', id: 'GBs' },
|
||||||
|
{ name: 'gigabits/sec', id: 'Gbits' },
|
||||||
|
{ name: 'tebibytes/sec', id: 'TiBs' },
|
||||||
|
{ name: 'tebibits/sec', id: 'Tibits' },
|
||||||
|
{ name: 'terabytes/sec', id: 'TBs' },
|
||||||
|
{ name: 'terabits/sec', id: 'Tbits' },
|
||||||
|
{ name: 'pebibytes/sec', id: 'PiBs' },
|
||||||
|
{ name: 'pebibits/sec', id: 'Pibits' },
|
||||||
|
{ name: 'petabytes/sec', id: 'PBs' },
|
||||||
|
{ name: 'petabits/sec', id: 'Pbits' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hash rate',
|
||||||
|
formats: [
|
||||||
|
{ name: 'hashes/sec', id: 'Hs' },
|
||||||
|
{ name: 'kilohashes/sec', id: 'KHs' },
|
||||||
|
{ name: 'megahashes/sec', id: 'MHs' },
|
||||||
|
{ name: 'gigahashes/sec', id: 'GHs' },
|
||||||
|
{ name: 'terahashes/sec', id: 'THs' },
|
||||||
|
{ name: 'petahashes/sec', id: 'PHs' },
|
||||||
|
{ name: 'exahashes/sec', id: 'EHs' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'Acceleration',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Meters/sec²', id: 'accMS2' },
|
||||||
|
{ name: 'Feet/sec²', id: 'accFS2' },
|
||||||
|
{ name: 'G unit', id: 'accG' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Angle',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Degrees (°)', id: 'degree' },
|
||||||
|
{ name: 'Radians', id: 'radian' },
|
||||||
|
{ name: 'Gradian', id: 'grad' },
|
||||||
|
{ name: 'Arc Minutes', id: 'arcmin' },
|
||||||
|
{ name: 'Arc Seconds', id: 'arcsec' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Area',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Square Meters (m²)', id: 'areaM2' },
|
||||||
|
{ name: 'Square Feet (ft²)', id: 'areaF2' },
|
||||||
|
{ name: 'Square Miles (mi²)', id: 'areaMI2' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Computation',
|
||||||
|
formats: [
|
||||||
|
{ name: 'FLOP/s', id: 'flops' },
|
||||||
|
{ name: 'MFLOP/s', id: 'mflops' },
|
||||||
|
{ name: 'GFLOP/s', id: 'gflops' },
|
||||||
|
{ name: 'TFLOP/s', id: 'tflops' },
|
||||||
|
{ name: 'PFLOP/s', id: 'pflops' },
|
||||||
|
{ name: 'EFLOP/s', id: 'eflops' },
|
||||||
|
{ name: 'ZFLOP/s', id: 'zflops' },
|
||||||
|
{ name: 'YFLOP/s', id: 'yflops' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Concentration',
|
||||||
|
formats: [
|
||||||
|
{ name: 'parts-per-million (ppm)', id: 'ppm' },
|
||||||
|
{ name: 'parts-per-billion (ppb)', id: 'conppb' },
|
||||||
|
{ name: 'nanogram per cubic meter (ng/m³)', id: 'conngm3' },
|
||||||
|
{ name: 'nanogram per normal cubic meter (ng/Nm³)', id: 'conngNm3' },
|
||||||
|
{ name: 'microgram per cubic meter (μg/m³)', id: 'conμgm3' },
|
||||||
|
{ name: 'microgram per normal cubic meter (μg/Nm³)', id: 'conμgNm3' },
|
||||||
|
{ name: 'milligram per cubic meter (mg/m³)', id: 'conmgm3' },
|
||||||
|
{ name: 'milligram per normal cubic meter (mg/Nm³)', id: 'conmgNm3' },
|
||||||
|
{ name: 'gram per cubic meter (g/m³)', id: 'congm3' },
|
||||||
|
{ name: 'gram per normal cubic meter (g/Nm³)', id: 'congNm3' },
|
||||||
|
{ name: 'milligrams per decilitre (mg/dL)', id: 'conmgdL' },
|
||||||
|
{ name: 'millimoles per litre (mmol/L)', id: 'conmmolL' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Currency',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Dollars ($)', id: 'currencyUSD' },
|
||||||
|
{ name: 'Pounds (£)', id: 'currencyGBP' },
|
||||||
|
{ name: 'Euro (€)', id: 'currencyEUR' },
|
||||||
|
{ name: 'Yen (¥)', id: 'currencyJPY' },
|
||||||
|
{ name: 'Rubles (₽)', id: 'currencyRUB' },
|
||||||
|
{ name: 'Hryvnias (₴)', id: 'currencyUAH' },
|
||||||
|
{ name: 'Real (R$)', id: 'currencyBRL' },
|
||||||
|
{ name: 'Danish Krone (kr)', id: 'currencyDKK' },
|
||||||
|
{ name: 'Icelandic Króna (kr)', id: 'currencyISK' },
|
||||||
|
{ name: 'Norwegian Krone (kr)', id: 'currencyNOK' },
|
||||||
|
{ name: 'Swedish Krona (kr)', id: 'currencySEK' },
|
||||||
|
{ name: 'Czech koruna (czk)', id: 'currencyCZK' },
|
||||||
|
{ name: 'Swiss franc (CHF)', id: 'currencyCHF' },
|
||||||
|
{ name: 'Polish Złoty (PLN)', id: 'currencyPLN' },
|
||||||
|
{ name: 'Bitcoin (฿)', id: 'currencyBTC' },
|
||||||
|
{ name: 'Milli Bitcoin (฿)', id: 'currencymBTC' },
|
||||||
|
{ name: 'Micro Bitcoin (฿)', id: 'currencyμBTC' },
|
||||||
|
{ name: 'South African Rand (R)', id: 'currencyZAR' },
|
||||||
|
{ name: 'Indian Rupee (₹)', id: 'currencyINR' },
|
||||||
|
{ name: 'South Korean Won (₩)', id: 'currencyKRW' },
|
||||||
|
{ name: 'Indonesian Rupiah (Rp)', id: 'currencyIDR' },
|
||||||
|
{ name: 'Philippine Peso (PHP)', id: 'currencyPHP' },
|
||||||
|
{ name: 'Vietnamese Dong (VND)', id: 'currencyVND' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'Date & time',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Datetime ISO', id: 'dateTimeAsIso' },
|
||||||
|
{
|
||||||
|
name: 'Datetime ISO (No date if today)',
|
||||||
|
id: 'dateTimeAsIsoNoDateIfToday',
|
||||||
|
},
|
||||||
|
{ name: 'Datetime US', id: 'dateTimeAsUS' },
|
||||||
|
{ name: 'Datetime US (No date if today)', id: 'dateTimeAsUSNoDateIfToday' },
|
||||||
|
{ name: 'Datetime local', id: 'dateTimeAsLocal' },
|
||||||
|
{
|
||||||
|
name: 'Datetime local (No date if today)',
|
||||||
|
id: 'dateTimeAsLocalNoDateIfToday',
|
||||||
|
},
|
||||||
|
{ name: 'Datetime default', id: 'dateTimeAsSystem' },
|
||||||
|
{ name: 'From Now', id: 'dateTimeFromNow' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Energy',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Watt (W)', id: 'watt' },
|
||||||
|
{ name: 'Kilowatt (kW)', id: 'kwatt' },
|
||||||
|
{ name: 'Megawatt (MW)', id: 'megwatt' },
|
||||||
|
{ name: 'Gigawatt (GW)', id: 'gwatt' },
|
||||||
|
{ name: 'Milliwatt (mW)', id: 'mwatt' },
|
||||||
|
{ name: 'Watt per square meter (W/m²)', id: 'Wm2' },
|
||||||
|
{ name: 'Volt-Ampere (VA)', id: 'voltamp' },
|
||||||
|
{ name: 'Kilovolt-Ampere (kVA)', id: 'kvoltamp' },
|
||||||
|
{ name: 'Volt-Ampere reactive (VAr)', id: 'voltampreact' },
|
||||||
|
{ name: 'Kilovolt-Ampere reactive (kVAr)', id: 'kvoltampreact' },
|
||||||
|
{ name: 'Watt-hour (Wh)', id: 'watth' },
|
||||||
|
{ name: 'Watt-hour per Kilogram (Wh/kg)', id: 'watthperkg' },
|
||||||
|
{ name: 'Kilowatt-hour (kWh)', id: 'kwatth' },
|
||||||
|
{ name: 'Kilowatt-min (kWm)', id: 'kwattm' },
|
||||||
|
{ name: 'Ampere-hour (Ah)', id: 'amph' },
|
||||||
|
{ name: 'Kiloampere-hour (kAh)', id: 'kamph' },
|
||||||
|
{ name: 'Milliampere-hour (mAh)', id: 'mamph' },
|
||||||
|
{ name: 'Joule (J)', id: 'joule' },
|
||||||
|
{ name: 'Electron volt (eV)', id: 'ev' },
|
||||||
|
{ name: 'Ampere (A)', id: 'amp' },
|
||||||
|
{ name: 'Kiloampere (kA)', id: 'kamp' },
|
||||||
|
{ name: 'Milliampere (mA)', id: 'mamp' },
|
||||||
|
{ name: 'Volt (V)', id: 'volt' },
|
||||||
|
{ name: 'Kilovolt (kV)', id: 'kvolt' },
|
||||||
|
{ name: 'Millivolt (mV)', id: 'mvolt' },
|
||||||
|
{ name: 'Decibel-milliwatt (dBm)', id: 'dBm' },
|
||||||
|
{ name: 'Ohm (Ω)', id: 'ohm' },
|
||||||
|
{ name: 'Kiloohm (kΩ)', id: 'kohm' },
|
||||||
|
{ name: 'Megaohm (MΩ)', id: 'Mohm' },
|
||||||
|
{ name: 'Farad (F)', id: 'farad' },
|
||||||
|
{ name: 'Microfarad (µF)', id: 'µfarad' },
|
||||||
|
{ name: 'Nanofarad (nF)', id: 'nfarad' },
|
||||||
|
{ name: 'Picofarad (pF)', id: 'pfarad' },
|
||||||
|
{ name: 'Femtofarad (fF)', id: 'ffarad' },
|
||||||
|
{ name: 'Henry (H)', id: 'henry' },
|
||||||
|
{ name: 'Millihenry (mH)', id: 'mhenry' },
|
||||||
|
{ name: 'Microhenry (µH)', id: 'µhenry' },
|
||||||
|
{ name: 'Lumens (Lm)', id: 'lumens' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Flow',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Gallons/min (gpm)', id: 'flowgpm' },
|
||||||
|
{ name: 'Cubic meters/sec (cms)', id: 'flowcms' },
|
||||||
|
{ name: 'Cubic feet/sec (cfs)', id: 'flowcfs' },
|
||||||
|
{ name: 'Cubic feet/min (cfm)', id: 'flowcfm' },
|
||||||
|
{ name: 'Litre/hour', id: 'litreh' },
|
||||||
|
{ name: 'Litre/min (L/min)', id: 'flowlpm' },
|
||||||
|
{ name: 'milliLitre/min (mL/min)', id: 'flowmlpm' },
|
||||||
|
{ name: 'Lux (lx)', id: 'lux' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Force',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Newton-meters (Nm)', id: 'forceNm' },
|
||||||
|
{ name: 'Kilonewton-meters (kNm)', id: 'forcekNm' },
|
||||||
|
{ name: 'Newtons (N)', id: 'forceN' },
|
||||||
|
{ name: 'Kilonewtons (kN)', id: 'forcekN' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Mass',
|
||||||
|
formats: [
|
||||||
|
{ name: 'milligram (mg)', id: 'massmg' },
|
||||||
|
{ name: 'gram (g)', id: 'massg' },
|
||||||
|
{ name: 'pound (lb)', id: 'masslb' },
|
||||||
|
{ name: 'kilogram (kg)', id: 'masskg' },
|
||||||
|
{ name: 'metric ton (t)', id: 'masst' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Length',
|
||||||
|
formats: [
|
||||||
|
{ name: 'millimeter (mm)', id: 'lengthmm' },
|
||||||
|
{ name: 'inch (in)', id: 'lengthin' },
|
||||||
|
{ name: 'feet (ft)', id: 'lengthft' },
|
||||||
|
{ name: 'meter (m)', id: 'lengthm' },
|
||||||
|
{ name: 'kilometer (km)', id: 'lengthkm' },
|
||||||
|
{ name: 'mile (mi)', id: 'lengthmi' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Pressure',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Millibars', id: 'pressurembar' },
|
||||||
|
{ name: 'Bars', id: 'pressurebar' },
|
||||||
|
{ name: 'Kilobars', id: 'pressurekbar' },
|
||||||
|
{ name: 'Pascals', id: 'pressurepa' },
|
||||||
|
{ name: 'Hectopascals', id: 'pressurehpa' },
|
||||||
|
{ name: 'Kilopascals', id: 'pressurekpa' },
|
||||||
|
{ name: 'Inches of mercury', id: 'pressurehg' },
|
||||||
|
{ name: 'PSI', id: 'pressurepsi' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Radiation',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Becquerel (Bq)', id: 'radbq' },
|
||||||
|
{ name: 'curie (Ci)', id: 'radci' },
|
||||||
|
{ name: 'Gray (Gy)', id: 'radgy' },
|
||||||
|
{ name: 'rad', id: 'radrad' },
|
||||||
|
{ name: 'Sievert (Sv)', id: 'radsv' },
|
||||||
|
{ name: 'milliSievert (mSv)', id: 'radmsv' },
|
||||||
|
{ name: 'microSievert (µSv)', id: 'radusv' },
|
||||||
|
{ name: 'rem', id: 'radrem' },
|
||||||
|
{ name: 'Exposure (C/kg)', id: 'radexpckg' },
|
||||||
|
{ name: 'roentgen (R)', id: 'radr' },
|
||||||
|
{ name: 'Sievert/hour (Sv/h)', id: 'radsvh' },
|
||||||
|
{ name: 'milliSievert/hour (mSv/h)', id: 'radmsvh' },
|
||||||
|
{ name: 'microSievert/hour (µSv/h)', id: 'radusvh' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Rotational Speed',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Revolutions per minute (rpm)', id: 'rotrpm' },
|
||||||
|
{ name: 'Hertz (Hz)', id: 'rothz' },
|
||||||
|
{ name: 'Radians per second (rad/s)', id: 'rotrads' },
|
||||||
|
{ name: 'Degrees per second (°/s)', id: 'rotdegs' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Temperature',
|
||||||
|
formats: [
|
||||||
|
{ name: 'Celsius (°C)', id: 'celsius' },
|
||||||
|
{ name: 'Fahrenheit (°F)', id: 'fahrenheit' },
|
||||||
|
{ name: 'Kelvin (K)', id: 'kelvin' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Velocity',
|
||||||
|
formats: [
|
||||||
|
{ name: 'meters/second (m/s)', id: 'velocityms' },
|
||||||
|
{ name: 'kilometers/hour (km/h)', id: 'velocitykmh' },
|
||||||
|
{ name: 'miles/hour (mph)', id: 'velocitymph' },
|
||||||
|
{ name: 'knot (kn)', id: 'velocityknot' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Volume',
|
||||||
|
formats: [
|
||||||
|
{ name: 'millilitre (mL)', id: 'mlitre' },
|
||||||
|
{ name: 'litre (L)', id: 'litre' },
|
||||||
|
{ name: 'cubic meter', id: 'm3' },
|
||||||
|
{ name: 'Normal cubic meter', id: 'Nm3' },
|
||||||
|
{ name: 'cubic decimeter', id: 'dm3' },
|
||||||
|
{ name: 'gallons', id: 'gallons' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Boolean',
|
||||||
|
formats: [
|
||||||
|
{ name: 'True / False', id: 'bool' },
|
||||||
|
{ name: 'Yes / No', id: 'bool_yes_no' },
|
||||||
|
{ name: 'On / Off', id: 'bool_on_off' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Misc',
|
||||||
|
formats: [
|
||||||
|
{ name: 'String', id: 'string' },
|
||||||
|
{ name: 'short', id: 'short' },
|
||||||
|
{ name: 'Percent (0-100)', id: 'percent' },
|
||||||
|
{ name: 'Percent (0.0-1.0)', id: 'percentunit' },
|
||||||
|
{ name: 'Humidity (%H)', id: 'humidity' },
|
||||||
|
{ name: 'Decibel', id: 'dB' },
|
||||||
|
{ name: 'Hexadecimal (0x)', id: 'hex0x' },
|
||||||
|
{ name: 'Hexadecimal', id: 'hex' },
|
||||||
|
{ name: 'Scientific notation', id: 'sci' },
|
||||||
|
{ name: 'Locale format', id: 'locale' },
|
||||||
|
{ name: 'Pixels', id: 'pixel' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
export const flattenedCategories = flattenDeep(
|
||||||
|
dataTypeCategories.map((category) => {
|
||||||
|
return category.formats;
|
||||||
|
}),
|
||||||
|
);
|
@ -10,7 +10,10 @@ import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
|||||||
import GraphTypes from 'container/NewDashboard/ComponentsSlider/menuItems';
|
import GraphTypes from 'container/NewDashboard/ComponentsSlider/menuItems';
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { dataTypeCategories } from './dataFormatCategories';
|
||||||
|
// import {ca} from '@grafana/data'
|
||||||
import { timePreferance } from './timeItems';
|
import { timePreferance } from './timeItems';
|
||||||
|
import YAxisUnitSelector from './YAxisUnitSelector';
|
||||||
|
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
import TimePreference from 'components/TimePreferenceDropDown';
|
import TimePreference from 'components/TimePreferenceDropDown';
|
||||||
@ -35,6 +38,8 @@ const RightContainer = ({
|
|||||||
selectedGraph,
|
selectedGraph,
|
||||||
setSelectedTime,
|
setSelectedTime,
|
||||||
selectedTime,
|
selectedTime,
|
||||||
|
yAxisUnit,
|
||||||
|
setYAxisUnit,
|
||||||
}: RightContainerProps): JSX.Element => {
|
}: RightContainerProps): JSX.Element => {
|
||||||
const onChangeHandler = useCallback(
|
const onChangeHandler = useCallback(
|
||||||
(setFunc: React.Dispatch<React.SetStateAction<string>>, value: string) => {
|
(setFunc: React.Dispatch<React.SetStateAction<string>>, value: string) => {
|
||||||
@ -144,6 +149,7 @@ const RightContainer = ({
|
|||||||
setSelectedTime,
|
setSelectedTime,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<YAxisUnitSelector defaultValue={yAxisUnit} onSelect={setYAxisUnit} />
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -162,6 +168,8 @@ interface RightContainerProps {
|
|||||||
selectedGraph: GRAPH_TYPES;
|
selectedGraph: GRAPH_TYPES;
|
||||||
setSelectedTime: React.Dispatch<React.SetStateAction<timePreferance>>;
|
setSelectedTime: React.Dispatch<React.SetStateAction<timePreferance>>;
|
||||||
selectedTime: timePreferance;
|
selectedTime: timePreferance;
|
||||||
|
yAxisUnit: string;
|
||||||
|
setYAxisUnit: React.Dispatch<React.SetStateAction<string>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default RightContainer;
|
export default RightContainer;
|
||||||
|
@ -17,7 +17,10 @@ import {
|
|||||||
SaveDashboard,
|
SaveDashboard,
|
||||||
SaveDashboardProps,
|
SaveDashboardProps,
|
||||||
} from 'store/actions/dashboard/saveDashboard';
|
} from 'store/actions/dashboard/saveDashboard';
|
||||||
import { UpdateQuery, UpdateQueryProps } from 'store/actions/dashboard/updateQuery';
|
import {
|
||||||
|
UpdateQuery,
|
||||||
|
UpdateQueryProps,
|
||||||
|
} from 'store/actions/dashboard/updateQuery';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import AppActions from 'types/actions';
|
import AppActions from 'types/actions';
|
||||||
import { GlobalTime } from 'types/actions/globalTime';
|
import { GlobalTime } from 'types/actions/globalTime';
|
||||||
@ -40,7 +43,7 @@ const NewWidget = ({
|
|||||||
applySettingsToPanel,
|
applySettingsToPanel,
|
||||||
saveSettingOfPanel,
|
saveSettingOfPanel,
|
||||||
getQueryResults,
|
getQueryResults,
|
||||||
updateQuery
|
updateQuery,
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
||||||
(state) => state.dashboards,
|
(state) => state.dashboards,
|
||||||
@ -74,6 +77,7 @@ const NewWidget = ({
|
|||||||
const [description, setDescription] = useState<string>(
|
const [description, setDescription] = useState<string>(
|
||||||
selectedWidget?.description || '',
|
selectedWidget?.description || '',
|
||||||
);
|
);
|
||||||
|
const [yAxisUnit, setYAxisUnit] = useState<string>(selectedWidget?.yAxisUnit);
|
||||||
|
|
||||||
const [stacked, setStacked] = useState<boolean>(
|
const [stacked, setStacked] = useState<boolean>(
|
||||||
selectedWidget?.isStacked || false,
|
selectedWidget?.isStacked || false,
|
||||||
@ -106,6 +110,7 @@ const NewWidget = ({
|
|||||||
opacity,
|
opacity,
|
||||||
timePreferance: selectedTime.enum,
|
timePreferance: selectedTime.enum,
|
||||||
title,
|
title,
|
||||||
|
yAxisUnit,
|
||||||
widgetId: query.get('widgetId') || '',
|
widgetId: query.get('widgetId') || '',
|
||||||
dashboardId: dashboardId,
|
dashboardId: dashboardId,
|
||||||
});
|
});
|
||||||
@ -127,11 +132,12 @@ const NewWidget = ({
|
|||||||
updateQuery({
|
updateQuery({
|
||||||
widgetId: selectedWidget?.id || '',
|
widgetId: selectedWidget?.id || '',
|
||||||
query: element.query || '',
|
query: element.query || '',
|
||||||
legend: element.legend || '',
|
legend: element.legend || '',
|
||||||
currentIndex: index
|
currentIndex: index,
|
||||||
|
yAxisUnit,
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
applySettingsToPanel({
|
applySettingsToPanel({
|
||||||
description,
|
description,
|
||||||
isStacked: stacked,
|
isStacked: stacked,
|
||||||
@ -140,8 +146,9 @@ const NewWidget = ({
|
|||||||
timePreferance: selectedTime.enum,
|
timePreferance: selectedTime.enum,
|
||||||
title,
|
title,
|
||||||
widgetId: selectedWidget?.id || '',
|
widgetId: selectedWidget?.id || '',
|
||||||
|
yAxisUnit
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const onClickDiscardHandler = useCallback(() => {
|
const onClickDiscardHandler = useCallback(() => {
|
||||||
push(generatePath(ROUTES.DASHBOARD, { dashboardId }));
|
push(generatePath(ROUTES.DASHBOARD, { dashboardId }));
|
||||||
@ -181,7 +188,7 @@ const NewWidget = ({
|
|||||||
|
|
||||||
<PanelContainer>
|
<PanelContainer>
|
||||||
<LeftContainerWrapper flex={5}>
|
<LeftContainerWrapper flex={5}>
|
||||||
<LeftContainer selectedTime={selectedTime} selectedGraph={selectedGraph} />
|
<LeftContainer selectedTime={selectedTime} selectedGraph={selectedGraph} yAxisUnit={yAxisUnit}/>
|
||||||
</LeftContainerWrapper>
|
</LeftContainerWrapper>
|
||||||
|
|
||||||
<RightContainerWrapper flex={1}>
|
<RightContainerWrapper flex={1}>
|
||||||
@ -194,12 +201,14 @@ const NewWidget = ({
|
|||||||
stacked,
|
stacked,
|
||||||
setStacked,
|
setStacked,
|
||||||
opacity,
|
opacity,
|
||||||
|
yAxisUnit,
|
||||||
setOpacity,
|
setOpacity,
|
||||||
selectedNullZeroValue,
|
selectedNullZeroValue,
|
||||||
setSelectedNullZeroValue,
|
setSelectedNullZeroValue,
|
||||||
selectedGraph,
|
selectedGraph,
|
||||||
setSelectedTime,
|
setSelectedTime,
|
||||||
selectedTime,
|
selectedTime,
|
||||||
|
setYAxisUnit,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</RightContainerWrapper>
|
</RightContainerWrapper>
|
||||||
@ -233,7 +242,7 @@ const mapDispatchToProps = (
|
|||||||
applySettingsToPanel: bindActionCreators(ApplySettingsToPanel, dispatch),
|
applySettingsToPanel: bindActionCreators(ApplySettingsToPanel, dispatch),
|
||||||
saveSettingOfPanel: bindActionCreators(SaveDashboard, dispatch),
|
saveSettingOfPanel: bindActionCreators(SaveDashboard, dispatch),
|
||||||
getQueryResults: bindActionCreators(GetQueryResults, dispatch),
|
getQueryResults: bindActionCreators(GetQueryResults, dispatch),
|
||||||
updateQuery: bindActionCreators(UpdateQuery, dispatch)
|
updateQuery: bindActionCreators(UpdateQuery, dispatch),
|
||||||
});
|
});
|
||||||
|
|
||||||
type Props = DispatchProps & NewWidgetProps;
|
type Props = DispatchProps & NewWidgetProps;
|
||||||
|
@ -10,9 +10,10 @@ import { getChartData, getChartDataforGroupBy } from './config';
|
|||||||
import { Container } from './styles';
|
import { Container } from './styles';
|
||||||
|
|
||||||
const TraceGraph = (): JSX.Element => {
|
const TraceGraph = (): JSX.Element => {
|
||||||
const { spansGraph, selectedGroupBy } = useSelector<AppState, TraceReducer>(
|
const { spansGraph, selectedGroupBy, yAxisUnit } = useSelector<
|
||||||
(state) => state.traces,
|
AppState,
|
||||||
);
|
TraceReducer
|
||||||
|
>((state) => state.traces);
|
||||||
|
|
||||||
const { loading, error, errorMessage, payload } = spansGraph;
|
const { loading, error, errorMessage, payload } = spansGraph;
|
||||||
|
|
||||||
@ -40,7 +41,12 @@ const TraceGraph = (): JSX.Element => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Graph data={ChartData} name="traceGraph" type="line" />
|
<Graph
|
||||||
|
data={ChartData}
|
||||||
|
name="traceGraph"
|
||||||
|
type="line"
|
||||||
|
yAxisUnit={yAxisUnit}
|
||||||
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
interface Dropdown {
|
interface Dropdown {
|
||||||
key: string;
|
key: string;
|
||||||
displayValue: string;
|
displayValue: string;
|
||||||
|
yAxisUnit?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const groupBy: Dropdown[] = [
|
export const groupBy: Dropdown[] = [
|
||||||
@ -60,32 +61,42 @@ export const groupBy: Dropdown[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const functions: Dropdown[] = [
|
export const functions: Dropdown[] = [
|
||||||
{ displayValue: 'Count', key: 'count' },
|
{ displayValue: 'Count', key: 'count', yAxisUnit: 'short' },
|
||||||
{ displayValue: 'Rate per sec', key: 'ratePerSec' },
|
{
|
||||||
{ displayValue: 'Sum(duration in ns)', key: 'sum' },
|
displayValue: 'Rate per sec',
|
||||||
{ displayValue: 'Avg(duration in ns)', key: 'avg' },
|
key: 'ratePerSec',
|
||||||
|
yAxisUnit: 'reqps',
|
||||||
|
},
|
||||||
|
{ displayValue: 'Sum(duration in ns)', key: 'sum', yAxisUnit: 'ns' },
|
||||||
|
{ displayValue: 'Avg(duration in ns)', key: 'avg', yAxisUnit: 'ns' },
|
||||||
{
|
{
|
||||||
displayValue: 'Max(duration in ns)',
|
displayValue: 'Max(duration in ns)',
|
||||||
key: 'max',
|
key: 'max',
|
||||||
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayValue: 'Min(duration in ns)',
|
displayValue: 'Min(duration in ns)',
|
||||||
key: 'min',
|
key: 'min',
|
||||||
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayValue: '50th percentile(duration in ns)',
|
displayValue: '50th percentile(duration in ns)',
|
||||||
key: 'p50',
|
key: 'p50',
|
||||||
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayValue: '90th percentile(duration in ns)',
|
displayValue: '90th percentile(duration in ns)',
|
||||||
key: 'p90',
|
key: 'p90',
|
||||||
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayValue: '95th percentile(duration in ns)',
|
displayValue: '95th percentile(duration in ns)',
|
||||||
key: 'p95',
|
key: 'p95',
|
||||||
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayValue: '99th percentile(duration in ns)',
|
displayValue: '99th percentile(duration in ns)',
|
||||||
key: 'p99',
|
key: 'p99',
|
||||||
|
yAxisUnit: 'ns',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -31,6 +31,7 @@ const TraceGraphFilter = () => {
|
|||||||
type: UPDATE_SELECTED_FUNCTION,
|
type: UPDATE_SELECTED_FUNCTION,
|
||||||
payload: {
|
payload: {
|
||||||
selectedFunction: selected.key,
|
selectedFunction: selected.key,
|
||||||
|
yAxisUnit: selected.yAxisUnit,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ export const UpdateQuery = (
|
|||||||
payload: {
|
payload: {
|
||||||
query: queryArray,
|
query: queryArray,
|
||||||
widgetId: props.widgetId,
|
widgetId: props.widgetId,
|
||||||
|
yAxisUnit: props.yAxisUnit,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -41,4 +42,5 @@ export interface UpdateQueryProps {
|
|||||||
query: string;
|
query: string;
|
||||||
legend: string;
|
legend: string;
|
||||||
currentIndex: number;
|
currentIndex: number;
|
||||||
|
yAxisUnit: string | undefined;
|
||||||
}
|
}
|
||||||
|
@ -402,7 +402,7 @@ const dashboard = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
case UPDATE_QUERY: {
|
case UPDATE_QUERY: {
|
||||||
const { query, widgetId } = action.payload;
|
const { query, widgetId, yAxisUnit } = action.payload;
|
||||||
const { dashboards } = state;
|
const { dashboards } = state;
|
||||||
const [selectedDashboard] = dashboards;
|
const [selectedDashboard] = dashboards;
|
||||||
const { data } = selectedDashboard;
|
const { data } = selectedDashboard;
|
||||||
@ -431,6 +431,7 @@ const dashboard = (
|
|||||||
{
|
{
|
||||||
...selectedWidget,
|
...selectedWidget,
|
||||||
query,
|
query,
|
||||||
|
yAxisUnit,
|
||||||
},
|
},
|
||||||
...afterWidget,
|
...afterWidget,
|
||||||
],
|
],
|
||||||
|
@ -40,6 +40,7 @@ const initialValue: TraceReducer = {
|
|||||||
},
|
},
|
||||||
selectedGroupBy: '',
|
selectedGroupBy: '',
|
||||||
selectedFunction: 'count',
|
selectedFunction: 'count',
|
||||||
|
yAxisUnit: '',
|
||||||
spansGraph: {
|
spansGraph: {
|
||||||
error: false,
|
error: false,
|
||||||
errorMessage: '',
|
errorMessage: '',
|
||||||
@ -139,6 +140,7 @@ const traceReducer = (
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
selectedFunction: action.payload.selectedFunction,
|
selectedFunction: action.payload.selectedFunction,
|
||||||
|
yAxisUnit: action.payload.yAxisUnit,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@ interface UpdateQuery {
|
|||||||
payload: {
|
payload: {
|
||||||
query: Query[];
|
query: Query[];
|
||||||
widgetId: string;
|
widgetId: string;
|
||||||
|
yAxisUnit: string | undefined;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +116,7 @@ export interface UpdateSelectedFunction {
|
|||||||
type: typeof UPDATE_SELECTED_FUNCTION;
|
type: typeof UPDATE_SELECTED_FUNCTION;
|
||||||
payload: {
|
payload: {
|
||||||
selectedFunction: TraceReducer['selectedFunction'];
|
selectedFunction: TraceReducer['selectedFunction'];
|
||||||
|
yAxisUnit: string | undefined;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ export interface TraceReducer {
|
|||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
payload: PayloadProps;
|
payload: PayloadProps;
|
||||||
};
|
};
|
||||||
|
yAxisUnit: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SpansAggregateData {
|
interface SpansAggregateData {
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user