Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NETOBSERV-1319 single graph focus #405

Merged
merged 7 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion web/locales/en/plugin__netobserv-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"Scope": "Scope",
"Long labels can reduce visibility.": "Long labels can reduce visibility.",
"Truncate labels": "Truncate labels",
"Single graph focus": "Single graph focus",
"Display options": "Display options",
"Conversation": "Conversation",
"Flow": "Flow",
Expand Down Expand Up @@ -208,12 +209,14 @@
"Custom time range": "Custom time range",
"Reset": "Reset",
"Select a custom time range. Flows are selected based on their End Time value.": "Select a custom time range. Flows are selected based on their End Time value.",
"Show all graphs": "Show all graphs",
"Focus on this graph": "Focus on this graph",
"No results found": "No results found",
"Clear or reset filters and try again.": "Clear or reset filters and try again.",
"Unable to get overview": "Unable to get overview",
"Average latency": "Average latency",
"Average RTT": "Average RTT",
"Total flow count": "Total flow count",
"Unable to get overview": "Unable to get overview",
"Show total traffic for the selected filters": "Show total traffic for the selected filters",
"Show total": "Show total",
"Show other traffic grouped in a separate series": "Show other traffic grouped in a separate series",
Expand Down
4 changes: 4 additions & 0 deletions web/src/components/dropdowns/overview-display-dropdown.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@
#scope>.pf-c-dropdown__menu {
top: 0;
left: 100%;
}

#overview-display-dropdown {
min-width: 230px;
}
39 changes: 36 additions & 3 deletions web/src/components/dropdowns/overview-display-dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FlexItem, Select, Tooltip } from '@patternfly/react-core';
import { FlexItem, Select, Switch, Tooltip } from '@patternfly/react-core';
import { InfoAltIcon } from '@patternfly/react-icons';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
Expand All @@ -18,7 +18,18 @@ export const OverviewDisplayOptions: React.FC<{
setMetricScope: (s: FlowScope) => void;
truncateLength: TruncateLength;
setTruncateLength: (v: TruncateLength) => void;
}> = ({ metricType, setMetricType, metricScope, setMetricScope, truncateLength, setTruncateLength }) => {
focus: boolean;
setFocus: (v: boolean) => void;
}> = ({
metricType,
setMetricType,
metricScope,
setMetricScope,
truncateLength,
setTruncateLength,
focus,
setFocus
}) => {
const { t } = useTranslation('plugin__netobserv-plugin');

return (
Expand Down Expand Up @@ -61,6 +72,15 @@ export const OverviewDisplayOptions: React.FC<{
<TruncateDropdown id="truncate" selected={truncateLength} setTruncateLength={setTruncateLength} />
</div>
</div>
<div className="pf-c-select__menu-group">
<Switch
id="focus-switch"
className="display-dropdown-padding"
label={t('Single graph focus')}
isChecked={focus}
onChange={setFocus}
/>
</div>
</>
);
};
Expand All @@ -72,7 +92,18 @@ export const OverviewDisplayDropdown: React.FC<{
setMetricScope: (s: FlowScope) => void;
truncateLength: TruncateLength;
setTruncateLength: (v: TruncateLength) => void;
}> = ({ metricType, setMetricType, metricScope, setMetricScope, truncateLength, setTruncateLength }) => {
focus: boolean;
setFocus: (v: boolean) => void;
}> = ({
metricType,
setMetricType,
metricScope,
setMetricScope,
truncateLength,
setTruncateLength,
focus,
setFocus
}) => {
const { t } = useTranslation('plugin__netobserv-plugin');
const [isOpen, setOpen] = React.useState<boolean>(false);

Expand All @@ -91,6 +122,8 @@ export const OverviewDisplayDropdown: React.FC<{
setMetricScope={setMetricScope}
truncateLength={truncateLength}
setTruncateLength={setTruncateLength}
focus={focus}
setFocus={setFocus}
/>
}
/>
Expand Down
2 changes: 0 additions & 2 deletions web/src/components/metrics/__tests__/metrics-content.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { MetricsContent, MetricsContentProps } from '../metrics-content';
describe('<MetricsContent />', () => {
const props: MetricsContentProps = {
id: 'chart-test',
title: 'chart-test',
metricType: 'bytes',
metrics: metrics.map(m => ({ ...m, fullName: 'whatever', shortName: 'whatever', isInternal: false })),
smallerTexts: false,
Expand All @@ -18,7 +17,6 @@ describe('<MetricsContent />', () => {
it('should render component', async () => {
const wrapper = mount(<MetricsContent {...props} />);
expect(wrapper.find(MetricsContent)).toBeTruthy();
expect(wrapper.find(Chart).last().props().ariaTitle).toBe('chart-test');
});
it('should render bar', async () => {
const wrapper = mount(<MetricsContent {...props} showBar={true} />);
Expand Down
49 changes: 33 additions & 16 deletions web/src/components/metrics/dropped-donut.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getStat } from '../../model/topology';
import { LOCAL_STORAGE_OVERVIEW_DONUT_DIMENSION_KEY, useLocalStorage } from '../../utils/local-storage-hook';
import { getFormattedRateValue } from '../../utils/metrics';
import './metrics-content.css';
import { defaultDimensions, Dimensions, observe } from './metrics-helper';
import { defaultDimensions, Dimensions, observeDimensions } from './metrics-helper';

export type DroppedDonutProps = {
id: string;
Expand All @@ -18,6 +18,8 @@ export type DroppedDonutProps = {
totalMetric: NamedMetric;
showOthers: boolean;
smallerTexts?: boolean;
showLegend?: boolean;
animate?: boolean;
};

export const DroppedDonut: React.FC<DroppedDonutProps> = ({
Expand All @@ -28,7 +30,9 @@ export const DroppedDonut: React.FC<DroppedDonutProps> = ({
topKMetrics,
totalMetric,
showOthers,
smallerTexts
smallerTexts,
showLegend,
animate
}) => {
const { t } = useTranslation('plugin__netobserv-plugin');

Expand Down Expand Up @@ -65,11 +69,11 @@ export const DroppedDonut: React.FC<DroppedDonutProps> = ({

const containerRef = React.createRef<HTMLDivElement>();
const [dimensions, setDimensions] = useLocalStorage<Dimensions>(
LOCAL_STORAGE_OVERVIEW_DONUT_DIMENSION_KEY,
`${LOCAL_STORAGE_OVERVIEW_DONUT_DIMENSION_KEY}${showLegend ? '-legend' : ''}`,
defaultDimensions
);
React.useEffect(() => {
observe(containerRef, dimensions, setDimensions);
observeDimensions(containerRef, dimensions, setDimensions);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [containerRef, dimensions]);

Expand All @@ -78,23 +82,36 @@ export const DroppedDonut: React.FC<DroppedDonutProps> = ({
<ChartDonut
themeColor={ChartThemeColor.multiUnordered}
constrainToVisibleArea
legendData={legendData}
legendData={showLegend ? legendData : undefined}
legendOrientation="vertical"
legendPosition="right"
legendAllowWrap={true}
legendComponent={legentComponent}
labels={({ datum }) => datum.x}
//TODO: fix refresh on selection change to enable animation
//animate={true}
legendComponent={showLegend ? legentComponent : undefined}
animate={animate}
radius={showLegend ? dimensions.height / 3 : undefined}
innerRadius={showLegend ? dimensions.height / 4 : undefined}
width={dimensions.width}
height={dimensions.height}
data={sliced.map(m => ({ x: `${m.name}: ${getFormattedRateValue(m.value, metricType, t)}`, y: m.value }))}
padding={{
bottom: 20,
left: 20,
right: 400,
top: 20
}}
allowTooltip={showLegend}
data={sliced.map(m => ({
x: showLegend ? `${m.name}: ${getFormattedRateValue(m.value, metricType, t)}` : ' ',
y: m.value
}))}
padding={
showLegend
? {
bottom: 20,
left: 20,
right: 400,
top: 20
}
: {
bottom: 0,
left: 0,
right: 0,
top: 0
}
}
title={`${getFormattedRateValue(total, metricType, t)}`}
subTitle={t('Total dropped')}
/>
Expand Down
4 changes: 2 additions & 2 deletions web/src/components/metrics/histogram.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
getDomainDisplayText,
getDomainFromRange,
getHistogramRangeFromLimit,
observe,
observeDimensions,
toHistogramDatapoints,
toNamedMetric
} from './metrics-helper';
Expand Down Expand Up @@ -84,7 +84,7 @@ export const Histogram: React.FC<{

const [dimensions, setDimensions] = React.useState<Dimensions>({ width: 3000, height: 150 });
React.useEffect(() => {
observe(containerRef, dimensions, setDimensions);
observeDimensions(containerRef, dimensions, setDimensions);
}, [containerRef, dimensions]);

const moveHistogramRange = React.useCallback(
Expand Down
49 changes: 33 additions & 16 deletions web/src/components/metrics/latency-donut.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getStat } from '../../model/topology';
import { LOCAL_STORAGE_OVERVIEW_DONUT_DIMENSION_KEY, useLocalStorage } from '../../utils/local-storage-hook';
import { getFormattedValue } from '../../utils/metrics';
import './metrics-content.css';
import { defaultDimensions, Dimensions, observe } from './metrics-helper';
import { defaultDimensions, Dimensions, observeDimensions } from './metrics-helper';

export type LatencyDonutProps = {
id: string;
Expand All @@ -19,6 +19,8 @@ export type LatencyDonutProps = {
othersName?: string;
smallerTexts?: boolean;
subTitle: string;
showLegend?: boolean;
animate?: boolean;
};

export const LatencyDonut: React.FC<LatencyDonutProps> = ({
Expand All @@ -30,7 +32,9 @@ export const LatencyDonut: React.FC<LatencyDonutProps> = ({
showOthers,
othersName,
smallerTexts,
subTitle
subTitle,
showLegend,
animate
}) => {
const { t } = useTranslation('plugin__netobserv-plugin');

Expand Down Expand Up @@ -68,11 +72,11 @@ export const LatencyDonut: React.FC<LatencyDonutProps> = ({

const containerRef = React.createRef<HTMLDivElement>();
const [dimensions, setDimensions] = useLocalStorage<Dimensions>(
LOCAL_STORAGE_OVERVIEW_DONUT_DIMENSION_KEY,
`${LOCAL_STORAGE_OVERVIEW_DONUT_DIMENSION_KEY}${showLegend ? '-legend' : ''}`,
defaultDimensions
);
React.useEffect(() => {
observe(containerRef, dimensions, setDimensions);
observeDimensions(containerRef, dimensions, setDimensions);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [containerRef, dimensions]);

Expand All @@ -81,23 +85,36 @@ export const LatencyDonut: React.FC<LatencyDonutProps> = ({
<ChartDonut
themeColor={ChartThemeColor.multiUnordered}
constrainToVisibleArea
legendData={legendData}
legendData={showLegend ? legendData : undefined}
legendOrientation="vertical"
legendPosition="right"
legendAllowWrap={true}
legendComponent={legentComponent}
labels={({ datum }) => datum.x}
//TODO: fix refresh on selection change to enable animation
//animate={true}
legendComponent={showLegend ? legentComponent : undefined}
animate={animate}
radius={showLegend ? dimensions.height / 3 : undefined}
innerRadius={showLegend ? dimensions.height / 4 : undefined}
width={dimensions.width}
height={dimensions.height}
data={sliced.map(m => ({ x: `${m.name}: ${getFormattedValue(m.value, metricType, 'sum', t)}`, y: m.value }))}
padding={{
bottom: 20,
left: 20,
right: 400,
top: 20
}}
allowTooltip={showLegend}
data={sliced.map(m => ({
x: showLegend ? `${m.name}: ${getFormattedValue(m.value, metricType, 'sum', t)}` : ' ',
y: m.value
}))}
padding={
showLegend
? {
bottom: 20,
left: 20,
right: 400,
top: 20
}
: {
bottom: 0,
left: 0,
right: 0,
top: 0
}
}
title={`${getFormattedValue(total, metricType, 'sum', t)}`}
subTitle={subTitle}
/>
Expand Down
Loading
Loading