mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 07:49:01 +08:00
feat: added logarithmic scale option for panels (#7413)
This commit is contained in:
parent
694c185373
commit
bc17a10550
@ -159,6 +159,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
.log-scale {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.panel-time-text {
|
||||
margin-top: 16px;
|
||||
color: var(--bg-vanilla-400);
|
||||
|
@ -61,6 +61,18 @@ export const panelTypeVsFillSpan: { [key in PANEL_TYPES]: boolean } = {
|
||||
[PANEL_TYPES.EMPTY_WIDGET]: false,
|
||||
} as const;
|
||||
|
||||
export const panelTypeVsLogScale: { [key in PANEL_TYPES]: boolean } = {
|
||||
[PANEL_TYPES.TIME_SERIES]: true,
|
||||
[PANEL_TYPES.VALUE]: false,
|
||||
[PANEL_TYPES.TABLE]: false,
|
||||
[PANEL_TYPES.LIST]: false,
|
||||
[PANEL_TYPES.PIE]: false,
|
||||
[PANEL_TYPES.BAR]: true,
|
||||
[PANEL_TYPES.HISTOGRAM]: false,
|
||||
[PANEL_TYPES.TRACE]: false,
|
||||
[PANEL_TYPES.EMPTY_WIDGET]: false,
|
||||
} as const;
|
||||
|
||||
export const panelTypeVsYAxisUnit: { [key in PANEL_TYPES]: boolean } = {
|
||||
[PANEL_TYPES.TIME_SERIES]: true,
|
||||
[PANEL_TYPES.VALUE]: true,
|
||||
|
@ -10,7 +10,7 @@ import GraphTypes, {
|
||||
} from 'container/NewDashboard/ComponentsSlider/menuItems';
|
||||
import useCreateAlerts from 'hooks/queryBuilder/useCreateAlerts';
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { ConciergeBell, Plus } from 'lucide-react';
|
||||
import { ConciergeBell, LineChart, Plus, Spline } from 'lucide-react';
|
||||
import {
|
||||
Dispatch,
|
||||
SetStateAction,
|
||||
@ -27,6 +27,7 @@ import {
|
||||
panelTypeVsColumnUnitPreferences,
|
||||
panelTypeVsCreateAlert,
|
||||
panelTypeVsFillSpan,
|
||||
panelTypeVsLogScale,
|
||||
panelTypeVsPanelTimePreferences,
|
||||
panelTypeVsSoftMinMax,
|
||||
panelTypeVsStackingChartPreferences,
|
||||
@ -41,6 +42,12 @@ import YAxisUnitSelector from './YAxisUnitSelector';
|
||||
const { TextArea } = Input;
|
||||
const { Option } = Select;
|
||||
|
||||
enum LogScale {
|
||||
LINEAR = 'linear',
|
||||
LOGARITHMIC = 'logarithmic',
|
||||
}
|
||||
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
function RightContainer({
|
||||
description,
|
||||
setDescription,
|
||||
@ -71,6 +78,8 @@ function RightContainer({
|
||||
setSoftMin,
|
||||
columnUnits,
|
||||
setColumnUnits,
|
||||
isLogScale,
|
||||
setIsLogScale,
|
||||
}: RightContainerProps): JSX.Element {
|
||||
const onChangeHandler = useCallback(
|
||||
(setFunc: Dispatch<SetStateAction<string>>, value: string) => {
|
||||
@ -87,6 +96,7 @@ function RightContainer({
|
||||
const allowThreshold = panelTypeVsThreshold[selectedGraph];
|
||||
const allowSoftMinMax = panelTypeVsSoftMinMax[selectedGraph];
|
||||
const allowFillSpans = panelTypeVsFillSpan[selectedGraph];
|
||||
const allowLogScale = panelTypeVsLogScale[selectedGraph];
|
||||
const allowYAxisUnit = panelTypeVsYAxisUnit[selectedGraph];
|
||||
const allowCreateAlerts = panelTypeVsCreateAlert[selectedGraph];
|
||||
const allowBucketConfig = panelTypeVsBucketConfig[selectedGraph];
|
||||
@ -293,6 +303,36 @@ function RightContainer({
|
||||
</section>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{allowLogScale && (
|
||||
<section className="log-scale">
|
||||
<Typography.Text className="typography">Y Axis Scale</Typography.Text>
|
||||
<Select
|
||||
onChange={(value): void => setIsLogScale(value === LogScale.LOGARITHMIC)}
|
||||
value={isLogScale ? LogScale.LOGARITHMIC : LogScale.LINEAR}
|
||||
style={{ width: '100%' }}
|
||||
className="panel-type-select"
|
||||
defaultValue={LogScale.LINEAR}
|
||||
>
|
||||
<Option value={LogScale.LINEAR}>
|
||||
<div className="select-option">
|
||||
<div className="icon">
|
||||
<LineChart size={16} />
|
||||
</div>
|
||||
<Typography.Text className="display">Linear</Typography.Text>
|
||||
</div>
|
||||
</Option>
|
||||
<Option value={LogScale.LOGARITHMIC}>
|
||||
<div className="select-option">
|
||||
<div className="icon">
|
||||
<Spline size={16} />
|
||||
</div>
|
||||
<Typography.Text className="display">Logarithmic</Typography.Text>
|
||||
</div>
|
||||
</Option>
|
||||
</Select>
|
||||
</section>
|
||||
)}
|
||||
</section>
|
||||
|
||||
{allowCreateAlerts && (
|
||||
@ -356,6 +396,8 @@ interface RightContainerProps {
|
||||
setColumnUnits: Dispatch<SetStateAction<ColumnUnit>>;
|
||||
setSoftMin: Dispatch<SetStateAction<number | null>>;
|
||||
setSoftMax: Dispatch<SetStateAction<number | null>>;
|
||||
isLogScale: boolean;
|
||||
setIsLogScale: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
RightContainer.defaultProps = {
|
||||
|
@ -170,6 +170,9 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
const [isFillSpans, setIsFillSpans] = useState<boolean>(
|
||||
selectedWidget?.fillSpans || false,
|
||||
);
|
||||
const [isLogScale, setIsLogScale] = useState<boolean>(
|
||||
selectedWidget?.isLogScale || false,
|
||||
);
|
||||
const [saveModal, setSaveModal] = useState(false);
|
||||
const [discardModal, setDiscardModal] = useState(false);
|
||||
|
||||
@ -234,6 +237,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
mergeAllActiveQueries: combineHistogram,
|
||||
selectedLogFields,
|
||||
selectedTracesFields,
|
||||
isLogScale,
|
||||
};
|
||||
});
|
||||
}, [
|
||||
@ -255,6 +259,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
bucketCount,
|
||||
combineHistogram,
|
||||
stackedBarChart,
|
||||
isLogScale,
|
||||
]);
|
||||
|
||||
const closeModal = (): void => {
|
||||
@ -369,6 +374,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
graphType: getGraphType(selectedGraph || selectedWidget.panelTypes),
|
||||
query: stagedQuery,
|
||||
fillGaps: selectedWidget.fillSpans || false,
|
||||
isLogScale: selectedWidget.isLogScale || false,
|
||||
formatForWeb:
|
||||
getGraphTypeForFormat(selectedGraph || selectedWidget.panelTypes) ===
|
||||
PANEL_TYPES.TABLE,
|
||||
@ -379,6 +385,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
stagedQuery,
|
||||
selectedTime,
|
||||
selectedWidget.fillSpans,
|
||||
selectedWidget.isLogScale,
|
||||
globalSelectedInterval,
|
||||
]);
|
||||
|
||||
@ -442,6 +449,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
softMin: selectedWidget?.softMin || 0,
|
||||
softMax: selectedWidget?.softMax || 0,
|
||||
fillSpans: selectedWidget?.fillSpans,
|
||||
isLogScale: selectedWidget?.isLogScale || false,
|
||||
bucketWidth: selectedWidget?.bucketWidth || 0,
|
||||
bucketCount: selectedWidget?.bucketCount || 0,
|
||||
mergeAllActiveQueries: selectedWidget?.mergeAllActiveQueries || false,
|
||||
@ -468,6 +476,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
softMin: selectedWidget?.softMin || 0,
|
||||
softMax: selectedWidget?.softMax || 0,
|
||||
fillSpans: selectedWidget?.fillSpans,
|
||||
isLogScale: selectedWidget?.isLogScale || false,
|
||||
bucketWidth: selectedWidget?.bucketWidth || 0,
|
||||
bucketCount: selectedWidget?.bucketCount || 0,
|
||||
mergeAllActiveQueries: selectedWidget?.mergeAllActiveQueries || false,
|
||||
@ -730,6 +739,8 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
selectedWidget={selectedWidget}
|
||||
isFillSpans={isFillSpans}
|
||||
setIsFillSpans={setIsFillSpans}
|
||||
isLogScale={isLogScale}
|
||||
setIsLogScale={setIsLogScale}
|
||||
softMin={softMin}
|
||||
setSoftMin={setSoftMin}
|
||||
softMax={softMax}
|
||||
|
@ -137,6 +137,7 @@ function UplotPanelWrapper({
|
||||
uPlot.tzDate(new Date(timestamp * 1e3), timezone.value),
|
||||
timezone: timezone.value,
|
||||
customSeries,
|
||||
isLogScale: widget?.isLogScale,
|
||||
}),
|
||||
[
|
||||
widget?.id,
|
||||
@ -161,6 +162,7 @@ function UplotPanelWrapper({
|
||||
customTooltipElement,
|
||||
timezone.value,
|
||||
customSeries,
|
||||
widget?.isLogScale,
|
||||
],
|
||||
);
|
||||
|
||||
|
@ -58,6 +58,7 @@ export interface GetUPlotChartOptions {
|
||||
tzDate?: (timestamp: number) => Date;
|
||||
timezone?: string;
|
||||
customSeries?: (data: QueryData[]) => uPlot.Series[];
|
||||
isLogScale?: boolean;
|
||||
}
|
||||
|
||||
/** the function converts series A , series B , series C to
|
||||
@ -164,6 +165,7 @@ export const getUPlotChartOptions = ({
|
||||
tzDate,
|
||||
timezone,
|
||||
customSeries,
|
||||
isLogScale,
|
||||
}: GetUPlotChartOptions): uPlot.Options => {
|
||||
const timeScaleProps = getXAxisScale(minTimeScale, maxTimeScale);
|
||||
|
||||
@ -220,6 +222,7 @@ export const getUPlotChartOptions = ({
|
||||
softMax,
|
||||
softMin,
|
||||
}),
|
||||
distr: isLogScale ? 3 : 1,
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
@ -387,6 +390,6 @@ export const getUPlotChartOptions = ({
|
||||
hiddenGraph,
|
||||
isDarkMode,
|
||||
}),
|
||||
axes: getAxes({ isDarkMode, yAxisUnit, panelType }),
|
||||
axes: getAxes({ isDarkMode, yAxisUnit, panelType, isLogScale }),
|
||||
};
|
||||
};
|
||||
|
@ -17,16 +17,19 @@ const getAxes = ({
|
||||
isDarkMode,
|
||||
yAxisUnit,
|
||||
panelType,
|
||||
isLogScale,
|
||||
}: {
|
||||
isDarkMode: boolean;
|
||||
yAxisUnit?: string;
|
||||
panelType?: PANEL_TYPES;
|
||||
isLogScale?: boolean;
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
}): any => [
|
||||
{
|
||||
stroke: isDarkMode ? 'white' : 'black', // Color of the axis line
|
||||
grid: {
|
||||
stroke: getGridColor(isDarkMode), // Color of the grid lines
|
||||
width: 0.2, // Width of the grid lines,
|
||||
width: isLogScale ? 0.1 : 0.2, // Width of the grid lines,
|
||||
show: true,
|
||||
},
|
||||
ticks: {
|
||||
@ -45,17 +48,20 @@ const getAxes = ({
|
||||
stroke: isDarkMode ? 'white' : 'black', // Color of the axis line
|
||||
grid: {
|
||||
stroke: getGridColor(isDarkMode), // Color of the grid lines
|
||||
width: 0.2, // Width of the grid lines
|
||||
width: isLogScale ? 0.1 : 0.2, // Width of the grid lines
|
||||
},
|
||||
ticks: {
|
||||
// stroke: isDarkMode ? 'white' : 'black', // Color of the tick lines
|
||||
width: 0.3, // Width of the tick lines
|
||||
show: true,
|
||||
},
|
||||
...(isLogScale ? { space: 20 } : {}),
|
||||
values: (_, t): string[] =>
|
||||
t.map((v) => {
|
||||
if (v === null || v === undefined || Number.isNaN(v)) {
|
||||
return '';
|
||||
}
|
||||
const value = getToolTipValue(v.toString(), yAxisUnit);
|
||||
|
||||
return `${value}`;
|
||||
}),
|
||||
gap: 5,
|
||||
|
@ -108,6 +108,7 @@ export interface IBaseWidget {
|
||||
columnUnits?: ColumnUnit;
|
||||
selectedLogFields: IField[] | null;
|
||||
selectedTracesFields: BaseAutocompleteData[] | null;
|
||||
isLogScale?: boolean;
|
||||
}
|
||||
export interface Widgets extends IBaseWidget {
|
||||
query: Query;
|
||||
|
Loading…
x
Reference in New Issue
Block a user