mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-17 15:36:48 +00:00
feat: change Bar color opacity and make stacking as default (#9026)
This commit is contained in:
parent
0658c561b9
commit
9d999feabb
@ -3168,7 +3168,6 @@ export const getStatusCodeBarChartWidgetData = (
|
|||||||
},
|
},
|
||||||
description: '',
|
description: '',
|
||||||
id: '315b15fa-ff0c-442f-89f8-2bf4fb1af2f2',
|
id: '315b15fa-ff0c-442f-89f8-2bf4fb1af2f2',
|
||||||
isStacked: false,
|
|
||||||
panelTypes: PANEL_TYPES.BAR,
|
panelTypes: PANEL_TYPES.BAR,
|
||||||
title: '',
|
title: '',
|
||||||
opacity: '',
|
opacity: '',
|
||||||
|
|||||||
@ -53,7 +53,6 @@ const mockProps: WidgetGraphComponentProps = {
|
|||||||
description: '',
|
description: '',
|
||||||
fillSpans: false,
|
fillSpans: false,
|
||||||
id: '17f905f6-d355-46bd-a78e-cbc87e6f58cc',
|
id: '17f905f6-d355-46bd-a78e-cbc87e6f58cc',
|
||||||
isStacked: false,
|
|
||||||
mergeAllActiveQueries: false,
|
mergeAllActiveQueries: false,
|
||||||
nullZeroValues: 'zero',
|
nullZeroValues: 'zero',
|
||||||
opacity: '1',
|
opacity: '1',
|
||||||
|
|||||||
@ -38,7 +38,6 @@ export const getWidgetQueryBuilder = ({
|
|||||||
}: GetWidgetQueryPropsReturn): Widgets => ({
|
}: GetWidgetQueryPropsReturn): Widgets => ({
|
||||||
description: description || '',
|
description: description || '',
|
||||||
id: id || uuid(),
|
id: id || uuid(),
|
||||||
isStacked: false,
|
|
||||||
nullZeroValues: nullZeroValues || '',
|
nullZeroValues: nullZeroValues || '',
|
||||||
opacity: '1',
|
opacity: '1',
|
||||||
panelTypes,
|
panelTypes,
|
||||||
|
|||||||
@ -14,7 +14,6 @@ export const getWidgetQueryBuilder = ({
|
|||||||
}: GetWidgetQueryBuilderProps): Widgets => ({
|
}: GetWidgetQueryBuilderProps): Widgets => ({
|
||||||
description: '',
|
description: '',
|
||||||
id: id || v4(),
|
id: id || v4(),
|
||||||
isStacked: false,
|
|
||||||
nullZeroValues: '',
|
nullZeroValues: '',
|
||||||
opacity: '0',
|
opacity: '0',
|
||||||
panelTypes,
|
panelTypes,
|
||||||
|
|||||||
@ -535,8 +535,6 @@ interface RightContainerProps {
|
|||||||
setTitle: Dispatch<SetStateAction<string>>;
|
setTitle: Dispatch<SetStateAction<string>>;
|
||||||
description: string;
|
description: string;
|
||||||
setDescription: Dispatch<SetStateAction<string>>;
|
setDescription: Dispatch<SetStateAction<string>>;
|
||||||
stacked: boolean;
|
|
||||||
setStacked: Dispatch<SetStateAction<boolean>>;
|
|
||||||
opacity: string;
|
opacity: string;
|
||||||
setOpacity: Dispatch<SetStateAction<string>>;
|
setOpacity: Dispatch<SetStateAction<string>>;
|
||||||
selectedNullZeroValue: string;
|
selectedNullZeroValue: string;
|
||||||
|
|||||||
@ -6,7 +6,48 @@
|
|||||||
// - Handling multiple rows correctly
|
// - Handling multiple rows correctly
|
||||||
// - Handling widgets with different heights
|
// - Handling widgets with different heights
|
||||||
|
|
||||||
import { placeWidgetAtBottom, placeWidgetBetweenRows } from '../utils';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
|
import { DashboardProvider } from 'providers/Dashboard/Dashboard';
|
||||||
|
import { PreferenceContextProvider } from 'providers/preferences/context/PreferenceContextProvider';
|
||||||
|
import { I18nextProvider } from 'react-i18next';
|
||||||
|
import { useSearchParams } from 'react-router-dom-v5-compat';
|
||||||
|
import i18n from 'ReactI18';
|
||||||
|
import { render } from 'tests/test-utils';
|
||||||
|
|
||||||
|
import NewWidget from '..';
|
||||||
|
import {
|
||||||
|
getDefaultWidgetData,
|
||||||
|
placeWidgetAtBottom,
|
||||||
|
placeWidgetBetweenRows,
|
||||||
|
} from '../utils';
|
||||||
|
|
||||||
|
const MOCK_SEARCH_PARAMS =
|
||||||
|
'?graphType=bar&widgetId=b473eef0-8eb5-4dd3-8089-c1817734084f&compositeQuery=%7B"id"%3A"f026c678-9abf-42af-a3dc-f73dc8cbb810"%2C"builder"%3A%7B"queryData"%3A%5B%7B"dataSource"%3A"metrics"%2C"queryName"%3A"A"%2C"aggregateOperator"%3A"count"%2C"aggregateAttribute"%3A%7B"id"%3A"----"%2C"dataType"%3A""%2C"key"%3A""%2C"type"%3A""%7D%2C"timeAggregation"%3A"rate"%2C"spaceAggregation"%3A"sum"%2C"filter"%3A%7B"expression"%3A""%7D%2C"aggregations"%3A%5B%7B"metricName"%3A""%2C"temporality"%3A""%2C"timeAggregation"%3A"count"%2C"spaceAggregation"%3A"sum"%2C"reduceTo"%3A"avg"%7D%5D%2C"functions"%3A%5B%5D%2C"filters"%3A%7B"items"%3A%5B%5D%2C"op"%3A"AND"%7D%2C"expression"%3A"A"%2C"disabled"%3Afalse%2C"stepInterval"%3Anull%2C"having"%3A%5B%5D%2C"limit"%3Anull%2C"orderBy"%3A%5B%5D%2C"groupBy"%3A%5B%5D%2C"legend"%3A""%2C"reduceTo"%3A"avg"%2C"source"%3A""%7D%5D%2C"queryFormulas"%3A%5B%5D%2C"queryTraceOperator"%3A%5B%5D%7D%2C"clickhouse_sql"%3A%5B%7B"name"%3A"A"%2C"legend"%3A""%2C"disabled"%3Afalse%2C"query"%3A""%7D%5D%2C"promql"%3A%5B%7B"name"%3A"A"%2C"query"%3A""%2C"legend"%3A""%2C"disabled"%3Afalse%7D%5D%2C"queryType"%3A"builder"%7D&relativeTime=30m';
|
||||||
|
// Mocks
|
||||||
|
jest.mock('uplot', () => ({
|
||||||
|
paths: { spline: jest.fn(), bars: jest.fn() },
|
||||||
|
default: jest.fn(() => ({ paths: { spline: jest.fn(), bars: jest.fn() } })),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('react-router-dom', () => ({
|
||||||
|
...jest.requireActual('react-router-dom'),
|
||||||
|
useLocation: (): { pathname: string; search: string } => ({
|
||||||
|
pathname: '',
|
||||||
|
search: MOCK_SEARCH_PARAMS,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('hooks/useSafeNavigate', () => ({
|
||||||
|
useSafeNavigate: (): { safeNavigate: jest.Mock } => ({
|
||||||
|
safeNavigate: jest.fn(),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('react-router-dom-v5-compat', () => ({
|
||||||
|
...jest.requireActual('react-router-dom-v5-compat'),
|
||||||
|
useSearchParams: jest.fn(),
|
||||||
|
useNavigationType: jest.fn(() => 'PUSH'),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('placeWidgetAtBottom', () => {
|
describe('placeWidgetAtBottom', () => {
|
||||||
it('should place widget at (0,0) when layout is empty', () => {
|
it('should place widget at (0,0) when layout is empty', () => {
|
||||||
@ -216,3 +257,55 @@ describe('placeWidgetBetweenRows', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getDefaultWidgetData', () => {
|
||||||
|
it('should set stackedBarChart to true by default for new panel creation', () => {
|
||||||
|
const widgetId = 'test-widget-123';
|
||||||
|
const panelType = PANEL_TYPES.BAR;
|
||||||
|
|
||||||
|
const result = getDefaultWidgetData(widgetId, panelType);
|
||||||
|
|
||||||
|
expect(result.stackedBarChart).toBe(true);
|
||||||
|
expect(result.id).toBe(widgetId);
|
||||||
|
expect(result.panelTypes).toBe(panelType);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Stacking bar in new panel', () => {
|
||||||
|
it('New panel should have stack bar - true by default', () => {
|
||||||
|
// Mock useSearchParams to return the expected values
|
||||||
|
(useSearchParams as jest.Mock).mockReturnValue([
|
||||||
|
new URLSearchParams(MOCK_SEARCH_PARAMS),
|
||||||
|
jest.fn(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const { container, getByText, getByRole } = render(
|
||||||
|
<I18nextProvider i18n={i18n}>
|
||||||
|
<DashboardProvider>
|
||||||
|
<PreferenceContextProvider>
|
||||||
|
<NewWidget
|
||||||
|
selectedGraph={PANEL_TYPES.BAR}
|
||||||
|
fillSpans={undefined}
|
||||||
|
yAxisUnit={undefined}
|
||||||
|
/>
|
||||||
|
</PreferenceContextProvider>
|
||||||
|
</DashboardProvider>
|
||||||
|
</I18nextProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Verify label is present
|
||||||
|
expect(getByText('Stack series')).toBeInTheDocument();
|
||||||
|
|
||||||
|
// Verify section exists
|
||||||
|
const section = container.querySelector('section > .stack-chart');
|
||||||
|
expect(section).toBeInTheDocument();
|
||||||
|
|
||||||
|
// Verify switch is present and enabled (ant-switch-checked)
|
||||||
|
const switchBtn = section?.querySelector('.ant-switch');
|
||||||
|
expect(switchBtn).toBeInTheDocument();
|
||||||
|
expect(switchBtn).toHaveClass('ant-switch-checked');
|
||||||
|
|
||||||
|
// (Optional) More semantic: verify by role
|
||||||
|
expect(getByRole('switch')).toBeChecked();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@ -178,10 +178,6 @@ function NewWidget({
|
|||||||
selectedWidget?.yAxisUnit || 'none',
|
selectedWidget?.yAxisUnit || 'none',
|
||||||
);
|
);
|
||||||
|
|
||||||
const [stacked, setStacked] = useState<boolean>(
|
|
||||||
selectedWidget?.isStacked || false,
|
|
||||||
);
|
|
||||||
|
|
||||||
const [stackedBarChart, setStackedBarChart] = useState<boolean>(
|
const [stackedBarChart, setStackedBarChart] = useState<boolean>(
|
||||||
selectedWidget?.stackedBarChart || false,
|
selectedWidget?.stackedBarChart || false,
|
||||||
);
|
);
|
||||||
@ -258,7 +254,6 @@ function NewWidget({
|
|||||||
query: currentQuery,
|
query: currentQuery,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
isStacked: stacked,
|
|
||||||
opacity,
|
opacity,
|
||||||
nullZeroValues: selectedNullZeroValue,
|
nullZeroValues: selectedNullZeroValue,
|
||||||
yAxisUnit,
|
yAxisUnit,
|
||||||
@ -292,7 +287,6 @@ function NewWidget({
|
|||||||
selectedTracesFields,
|
selectedTracesFields,
|
||||||
softMax,
|
softMax,
|
||||||
softMin,
|
softMin,
|
||||||
stacked,
|
|
||||||
thresholds,
|
thresholds,
|
||||||
title,
|
title,
|
||||||
yAxisUnit,
|
yAxisUnit,
|
||||||
@ -494,7 +488,6 @@ function NewWidget({
|
|||||||
...(selectedWidget || ({} as Widgets)),
|
...(selectedWidget || ({} as Widgets)),
|
||||||
description: selectedWidget?.description || '',
|
description: selectedWidget?.description || '',
|
||||||
timePreferance: selectedTime.enum,
|
timePreferance: selectedTime.enum,
|
||||||
isStacked: selectedWidget?.isStacked || false,
|
|
||||||
opacity: selectedWidget?.opacity || '1',
|
opacity: selectedWidget?.opacity || '1',
|
||||||
nullZeroValues: selectedWidget?.nullZeroValues || 'zero',
|
nullZeroValues: selectedWidget?.nullZeroValues || 'zero',
|
||||||
title: selectedWidget?.title,
|
title: selectedWidget?.title,
|
||||||
@ -524,7 +517,6 @@ function NewWidget({
|
|||||||
...(selectedWidget || ({} as Widgets)),
|
...(selectedWidget || ({} as Widgets)),
|
||||||
description: selectedWidget?.description || '',
|
description: selectedWidget?.description || '',
|
||||||
timePreferance: selectedTime.enum,
|
timePreferance: selectedTime.enum,
|
||||||
isStacked: selectedWidget?.isStacked || false,
|
|
||||||
opacity: selectedWidget?.opacity || '1',
|
opacity: selectedWidget?.opacity || '1',
|
||||||
nullZeroValues: selectedWidget?.nullZeroValues || 'zero',
|
nullZeroValues: selectedWidget?.nullZeroValues || 'zero',
|
||||||
title: selectedWidget?.title,
|
title: selectedWidget?.title,
|
||||||
@ -818,8 +810,6 @@ function NewWidget({
|
|||||||
setTitle={setTitle}
|
setTitle={setTitle}
|
||||||
description={description}
|
description={description}
|
||||||
setDescription={setDescription}
|
setDescription={setDescription}
|
||||||
stacked={stacked}
|
|
||||||
setStacked={setStacked}
|
|
||||||
stackedBarChart={stackedBarChart}
|
stackedBarChart={stackedBarChart}
|
||||||
setStackedBarChart={setStackedBarChart}
|
setStackedBarChart={setStackedBarChart}
|
||||||
opacity={opacity}
|
opacity={opacity}
|
||||||
|
|||||||
@ -543,7 +543,6 @@ export const getDefaultWidgetData = (
|
|||||||
id,
|
id,
|
||||||
title: '',
|
title: '',
|
||||||
description: '',
|
description: '',
|
||||||
isStacked: false,
|
|
||||||
nullZeroValues: '',
|
nullZeroValues: '',
|
||||||
opacity: '',
|
opacity: '',
|
||||||
panelTypes: name,
|
panelTypes: name,
|
||||||
@ -554,6 +553,7 @@ export const getDefaultWidgetData = (
|
|||||||
timePreferance: 'GLOBAL_TIME',
|
timePreferance: 'GLOBAL_TIME',
|
||||||
softMax: null,
|
softMax: null,
|
||||||
softMin: null,
|
softMin: null,
|
||||||
|
stackedBarChart: true,
|
||||||
selectedLogFields: defaultLogsSelectedColumns.map((field) => ({
|
selectedLogFields: defaultLogsSelectedColumns.map((field) => ({
|
||||||
...field,
|
...field,
|
||||||
type: field.fieldContext ?? '',
|
type: field.fieldContext ?? '',
|
||||||
|
|||||||
@ -2,7 +2,6 @@ export const tablePanelWidgetQuery = {
|
|||||||
id: '727533b0-7718-4f99-a1db-a1875649325c',
|
id: '727533b0-7718-4f99-a1db-a1875649325c',
|
||||||
title: '',
|
title: '',
|
||||||
description: '',
|
description: '',
|
||||||
isStacked: false,
|
|
||||||
nullZeroValues: 'zero',
|
nullZeroValues: 'zero',
|
||||||
opacity: '1',
|
opacity: '1',
|
||||||
panelTypes: 'table',
|
panelTypes: 'table',
|
||||||
|
|||||||
@ -2,7 +2,6 @@ export const valuePanelWidget = {
|
|||||||
id: 'b8b93086-ef01-47bf-9044-1e7abd583be4',
|
id: 'b8b93086-ef01-47bf-9044-1e7abd583be4',
|
||||||
title: 'signoz latency in ms',
|
title: 'signoz latency in ms',
|
||||||
description: '',
|
description: '',
|
||||||
isStacked: false,
|
|
||||||
nullZeroValues: 'zero',
|
nullZeroValues: 'zero',
|
||||||
opacity: '1',
|
opacity: '1',
|
||||||
panelTypes: 'value',
|
panelTypes: 'value',
|
||||||
|
|||||||
@ -236,7 +236,6 @@ export const WidgetHeaderProps: any = {
|
|||||||
description: '',
|
description: '',
|
||||||
fillSpans: false,
|
fillSpans: false,
|
||||||
id: 'add65f0d-7662-4024-af51-da567759235d',
|
id: 'add65f0d-7662-4024-af51-da567759235d',
|
||||||
isStacked: false,
|
|
||||||
mergeAllActiveQueries: false,
|
mergeAllActiveQueries: false,
|
||||||
nullZeroValues: 'zero',
|
nullZeroValues: 'zero',
|
||||||
opacity: '1',
|
opacity: '1',
|
||||||
|
|||||||
@ -52,7 +52,6 @@ export const addEmptyWidgetInDashboardJSONWithQuery = (
|
|||||||
id: widgetId,
|
id: widgetId,
|
||||||
query,
|
query,
|
||||||
description: '',
|
description: '',
|
||||||
isStacked: false,
|
|
||||||
nullZeroValues: '',
|
nullZeroValues: '',
|
||||||
opacity: '',
|
opacity: '',
|
||||||
title: '',
|
title: '',
|
||||||
|
|||||||
@ -86,7 +86,7 @@ const getSeries = ({
|
|||||||
? hiddenGraph[i]
|
? hiddenGraph[i]
|
||||||
: true,
|
: true,
|
||||||
label,
|
label,
|
||||||
fill: panelType && panelType === PANEL_TYPES.BAR ? `${color}40` : undefined,
|
fill: panelType && panelType === PANEL_TYPES.BAR ? `${color}` : undefined,
|
||||||
stroke: color,
|
stroke: color,
|
||||||
width: 2,
|
width: 2,
|
||||||
spanGaps: true,
|
spanGaps: true,
|
||||||
|
|||||||
@ -14,7 +14,7 @@ describe('Get Series Data', () => {
|
|||||||
expect(seriesData.length).toBe(5);
|
expect(seriesData.length).toBe(5);
|
||||||
expect(seriesData[1].label).toBe('firstLegend');
|
expect(seriesData[1].label).toBe('firstLegend');
|
||||||
expect(seriesData[1].show).toBe(true);
|
expect(seriesData[1].show).toBe(true);
|
||||||
expect(seriesData[1].fill).toBe('#C7158540');
|
expect(seriesData[1].fill).toBe('#C71585');
|
||||||
expect(seriesData[1].width).toBe(2);
|
expect(seriesData[1].width).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,6 @@ export const getWidgetQueryBuilder = ({
|
|||||||
}: GetWidgetQueryPropsReturn): Widgets => ({
|
}: GetWidgetQueryPropsReturn): Widgets => ({
|
||||||
description: description || '',
|
description: description || '',
|
||||||
id: id || uuid(),
|
id: id || uuid(),
|
||||||
isStacked: false,
|
|
||||||
nullZeroValues: nullZeroValues || '',
|
nullZeroValues: nullZeroValues || '',
|
||||||
opacity: '1',
|
opacity: '1',
|
||||||
panelTypes,
|
panelTypes,
|
||||||
|
|||||||
@ -104,7 +104,6 @@ export interface ColumnUnit {
|
|||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
}
|
}
|
||||||
export interface IBaseWidget {
|
export interface IBaseWidget {
|
||||||
isStacked: boolean;
|
|
||||||
id: string;
|
id: string;
|
||||||
panelTypes: PANEL_TYPES;
|
panelTypes: PANEL_TYPES;
|
||||||
title: ReactNode;
|
title: ReactNode;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user