mirror of
https://github.com/SigNoz/signoz.git
synced 2026-03-01 03:22:55 +00:00
Compare commits
7 Commits
testing-fe
...
chore/uplo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f11153cdec | ||
|
|
a380c4d6be | ||
|
|
a0f576e5fb | ||
|
|
98013ee3b9 | ||
|
|
97b94fc4f5 | ||
|
|
0f3f49b96a | ||
|
|
0928a30863 |
@@ -1,3 +1,4 @@
|
|||||||
|
import { Timezone } from 'components/CustomTimePicker/timezoneUtils';
|
||||||
import { PrecisionOption } from 'components/Graph/types';
|
import { PrecisionOption } from 'components/Graph/types';
|
||||||
import { LegendConfig, TooltipRenderArgs } from 'lib/uPlotV2/components/types';
|
import { LegendConfig, TooltipRenderArgs } from 'lib/uPlotV2/components/types';
|
||||||
import { UPlotConfigBuilder } from 'lib/uPlotV2/config/UPlotConfigBuilder';
|
import { UPlotConfigBuilder } from 'lib/uPlotV2/config/UPlotConfigBuilder';
|
||||||
@@ -8,7 +9,7 @@ interface BaseChartProps {
|
|||||||
height: number;
|
height: number;
|
||||||
showTooltip?: boolean;
|
showTooltip?: boolean;
|
||||||
showLegend?: boolean;
|
showLegend?: boolean;
|
||||||
timezone: string;
|
timezone?: Timezone;
|
||||||
canPinTooltip?: boolean;
|
canPinTooltip?: boolean;
|
||||||
yAxisUnit?: string;
|
yAxisUnit?: string;
|
||||||
decimalPrecision?: PrecisionOption;
|
decimalPrecision?: PrecisionOption;
|
||||||
|
|||||||
@@ -129,12 +129,12 @@ function BarPanel(props: PanelWrapperProps): JSX.Element {
|
|||||||
onDestroy={onPlotDestroy}
|
onDestroy={onPlotDestroy}
|
||||||
yAxisUnit={widget.yAxisUnit}
|
yAxisUnit={widget.yAxisUnit}
|
||||||
decimalPrecision={widget.decimalPrecision}
|
decimalPrecision={widget.decimalPrecision}
|
||||||
timezone={timezone.value}
|
|
||||||
data={chartData as uPlot.AlignedData}
|
data={chartData as uPlot.AlignedData}
|
||||||
width={containerDimensions.width}
|
width={containerDimensions.width}
|
||||||
height={containerDimensions.height}
|
height={containerDimensions.height}
|
||||||
layoutChildren={layoutChildren}
|
layoutChildren={layoutChildren}
|
||||||
isStackedBarChart={widget.stackedBarChart ?? false}
|
isStackedBarChart={widget.stackedBarChart ?? false}
|
||||||
|
timezone={timezone}
|
||||||
>
|
>
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
coordinates={coordinates}
|
coordinates={coordinates}
|
||||||
|
|||||||
@@ -5,12 +5,7 @@ import { getInitialStackedBands } from 'container/DashboardContainer/visualizati
|
|||||||
import { getLegend } from 'lib/dashboard/getQueryResults';
|
import { getLegend } from 'lib/dashboard/getQueryResults';
|
||||||
import getLabelName from 'lib/getLabelName';
|
import getLabelName from 'lib/getLabelName';
|
||||||
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
||||||
import {
|
import { DrawStyle } from 'lib/uPlotV2/config/types';
|
||||||
DrawStyle,
|
|
||||||
LineInterpolation,
|
|
||||||
LineStyle,
|
|
||||||
VisibilityMode,
|
|
||||||
} from 'lib/uPlotV2/config/types';
|
|
||||||
import { UPlotConfigBuilder } from 'lib/uPlotV2/config/UPlotConfigBuilder';
|
import { UPlotConfigBuilder } from 'lib/uPlotV2/config/UPlotConfigBuilder';
|
||||||
import { get } from 'lodash-es';
|
import { get } from 'lodash-es';
|
||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
import { Widgets } from 'types/api/dashboard/getAll';
|
||||||
@@ -63,7 +58,12 @@ export function prepareBarPanelConfig({
|
|||||||
const minStepInterval = Math.min(...Object.values(stepIntervals));
|
const minStepInterval = Math.min(...Object.values(stepIntervals));
|
||||||
|
|
||||||
const builder = buildBaseConfig({
|
const builder = buildBaseConfig({
|
||||||
widget,
|
widgetId: widget.id,
|
||||||
|
thresholds: widget.thresholds,
|
||||||
|
yAxisUnit: widget.yAxisUnit,
|
||||||
|
softMin: widget.softMin ?? undefined,
|
||||||
|
softMax: widget.softMax ?? undefined,
|
||||||
|
isLogScale: widget.isLogScale,
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
onClick,
|
onClick,
|
||||||
onDragSelect,
|
onDragSelect,
|
||||||
@@ -98,14 +98,8 @@ export function prepareBarPanelConfig({
|
|||||||
builder.addSeries({
|
builder.addSeries({
|
||||||
scaleKey: 'y',
|
scaleKey: 'y',
|
||||||
drawStyle: DrawStyle.Bar,
|
drawStyle: DrawStyle.Bar,
|
||||||
panelType: PANEL_TYPES.BAR,
|
|
||||||
label: label,
|
label: label,
|
||||||
colorMapping: widget.customLegendColors ?? {},
|
colorMapping: widget.customLegendColors ?? {},
|
||||||
spanGaps: false,
|
|
||||||
lineStyle: LineStyle.Solid,
|
|
||||||
lineInterpolation: LineInterpolation.Spline,
|
|
||||||
showPoints: VisibilityMode.Never,
|
|
||||||
pointSize: 5,
|
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
stepInterval: currentStepInterval,
|
stepInterval: currentStepInterval,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ function HistogramPanel(props: PanelWrapperProps): JSX.Element {
|
|||||||
yAxisUnit={widget.yAxisUnit}
|
yAxisUnit={widget.yAxisUnit}
|
||||||
decimalPrecision={widget.decimalPrecision}
|
decimalPrecision={widget.decimalPrecision}
|
||||||
syncMode={DashboardCursorSync.Crosshair}
|
syncMode={DashboardCursorSync.Crosshair}
|
||||||
timezone={timezone.value}
|
timezone={timezone}
|
||||||
data={chartData as uPlot.AlignedData}
|
data={chartData as uPlot.AlignedData}
|
||||||
width={containerDimensions.width}
|
width={containerDimensions.width}
|
||||||
height={containerDimensions.height}
|
height={containerDimensions.height}
|
||||||
|
|||||||
@@ -154,7 +154,12 @@ export function prepareHistogramPanelConfig({
|
|||||||
isDarkMode: boolean;
|
isDarkMode: boolean;
|
||||||
}): UPlotConfigBuilder {
|
}): UPlotConfigBuilder {
|
||||||
const builder = buildBaseConfig({
|
const builder = buildBaseConfig({
|
||||||
widget,
|
widgetId: widget.id,
|
||||||
|
thresholds: widget.thresholds,
|
||||||
|
yAxisUnit: widget.yAxisUnit,
|
||||||
|
softMin: widget.softMin ?? undefined,
|
||||||
|
softMax: widget.softMax ?? undefined,
|
||||||
|
isLogScale: widget.isLogScale,
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
apiResponse,
|
apiResponse,
|
||||||
panelMode,
|
panelMode,
|
||||||
@@ -191,10 +196,8 @@ export function prepareHistogramPanelConfig({
|
|||||||
builder.addSeries({
|
builder.addSeries({
|
||||||
label: '',
|
label: '',
|
||||||
scaleKey: 'y',
|
scaleKey: 'y',
|
||||||
drawStyle: DrawStyle.Bar,
|
drawStyle: DrawStyle.Histogram,
|
||||||
panelType: PANEL_TYPES.HISTOGRAM,
|
|
||||||
colorMapping: widget.customLegendColors ?? {},
|
colorMapping: widget.customLegendColors ?? {},
|
||||||
spanGaps: false,
|
|
||||||
barWidthFactor: 1,
|
barWidthFactor: 1,
|
||||||
pointSize: 5,
|
pointSize: 5,
|
||||||
lineColor: '#3f5ecc',
|
lineColor: '#3f5ecc',
|
||||||
@@ -216,10 +219,8 @@ export function prepareHistogramPanelConfig({
|
|||||||
builder.addSeries({
|
builder.addSeries({
|
||||||
label: label,
|
label: label,
|
||||||
scaleKey: 'y',
|
scaleKey: 'y',
|
||||||
drawStyle: DrawStyle.Bar,
|
drawStyle: DrawStyle.Histogram,
|
||||||
panelType: PANEL_TYPES.HISTOGRAM,
|
|
||||||
colorMapping: widget.customLegendColors ?? {},
|
colorMapping: widget.customLegendColors ?? {},
|
||||||
spanGaps: false,
|
|
||||||
barWidthFactor: 1,
|
barWidthFactor: 1,
|
||||||
pointSize: 5,
|
pointSize: 5,
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ function TimeSeriesPanel(props: PanelWrapperProps): JSX.Element {
|
|||||||
}}
|
}}
|
||||||
yAxisUnit={widget.yAxisUnit}
|
yAxisUnit={widget.yAxisUnit}
|
||||||
decimalPrecision={widget.decimalPrecision}
|
decimalPrecision={widget.decimalPrecision}
|
||||||
timezone={timezone.value}
|
timezone={timezone}
|
||||||
data={chartData as uPlot.AlignedData}
|
data={chartData as uPlot.AlignedData}
|
||||||
width={containerDimensions.width}
|
width={containerDimensions.width}
|
||||||
height={containerDimensions.height}
|
height={containerDimensions.height}
|
||||||
|
|||||||
@@ -82,7 +82,12 @@ export const prepareUPlotConfig = ({
|
|||||||
const minStepInterval = Math.min(...Object.values(stepIntervals));
|
const minStepInterval = Math.min(...Object.values(stepIntervals));
|
||||||
|
|
||||||
const builder = buildBaseConfig({
|
const builder = buildBaseConfig({
|
||||||
widget,
|
widgetId: widget.id,
|
||||||
|
thresholds: widget.thresholds,
|
||||||
|
yAxisUnit: widget.yAxisUnit,
|
||||||
|
softMin: widget.softMin ?? undefined,
|
||||||
|
softMax: widget.softMax ?? undefined,
|
||||||
|
isLogScale: widget.isLogScale,
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
onClick,
|
onClick,
|
||||||
onDragSelect,
|
onDragSelect,
|
||||||
@@ -120,7 +125,6 @@ export const prepareUPlotConfig = ({
|
|||||||
: VisibilityMode.Never,
|
: VisibilityMode.Never,
|
||||||
pointSize: 5,
|
pointSize: 5,
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
panelType: PANEL_TYPES.TIME_SERIES,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
|
import { ThresholdProps } from 'container/NewWidget/RightContainer/Threshold/types';
|
||||||
import { STEP_INTERVAL_MULTIPLIER } from 'lib/uPlotV2/constants';
|
import { STEP_INTERVAL_MULTIPLIER } from 'lib/uPlotV2/constants';
|
||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
|
||||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
|
|
||||||
import { PanelMode } from '../../types';
|
import { PanelMode } from '../../types';
|
||||||
import { buildBaseConfig } from '../baseConfigBuilder';
|
import { BaseConfigBuilderProps, buildBaseConfig } from '../baseConfigBuilder';
|
||||||
|
|
||||||
jest.mock(
|
jest.mock(
|
||||||
'container/DashboardContainer/visualization/panels/utils/legendVisibilityUtils',
|
'container/DashboardContainer/visualization/panels/utils/legendVisibilityUtils',
|
||||||
@@ -27,16 +27,17 @@ jest.mock('lib/uPlotLib/plugins/onClickPlugin', () => ({
|
|||||||
default: jest.fn().mockReturnValue({ name: 'onClickPlugin' }),
|
default: jest.fn().mockReturnValue({ name: 'onClickPlugin' }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const createWidget = (overrides: Partial<Widgets> = {}): Widgets =>
|
const createBaseConfigBuilderProps = (
|
||||||
({
|
overrides: Partial<BaseConfigBuilderProps> = {},
|
||||||
id: 'widget-1',
|
): Partial<BaseConfigBuilderProps> => ({
|
||||||
yAxisUnit: 'ms',
|
widgetId: 'widget-1',
|
||||||
isLogScale: false,
|
yAxisUnit: 'ms',
|
||||||
softMin: undefined,
|
isLogScale: false,
|
||||||
softMax: undefined,
|
softMin: undefined,
|
||||||
thresholds: [],
|
softMax: undefined,
|
||||||
...overrides,
|
thresholds: [],
|
||||||
} as Widgets);
|
...overrides,
|
||||||
|
});
|
||||||
|
|
||||||
const createApiResponse = (
|
const createApiResponse = (
|
||||||
overrides: Partial<MetricRangePayloadProps> = {},
|
overrides: Partial<MetricRangePayloadProps> = {},
|
||||||
@@ -47,7 +48,7 @@ const createApiResponse = (
|
|||||||
} as MetricRangePayloadProps);
|
} as MetricRangePayloadProps);
|
||||||
|
|
||||||
const baseProps = {
|
const baseProps = {
|
||||||
widget: createWidget(),
|
...createBaseConfigBuilderProps(),
|
||||||
apiResponse: createApiResponse(),
|
apiResponse: createApiResponse(),
|
||||||
isDarkMode: true,
|
isDarkMode: true,
|
||||||
panelMode: PanelMode.DASHBOARD_VIEW,
|
panelMode: PanelMode.DASHBOARD_VIEW,
|
||||||
@@ -67,7 +68,7 @@ describe('buildBaseConfig', () => {
|
|||||||
const builder = buildBaseConfig({
|
const builder = buildBaseConfig({
|
||||||
...baseProps,
|
...baseProps,
|
||||||
panelMode: PanelMode.DASHBOARD_VIEW,
|
panelMode: PanelMode.DASHBOARD_VIEW,
|
||||||
widget: createWidget({ id: 'my-widget' }),
|
...createBaseConfigBuilderProps({ widgetId: 'my-widget' }),
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(builder.getWidgetId()).toBe('my-widget');
|
expect(builder.getWidgetId()).toBe('my-widget');
|
||||||
@@ -127,7 +128,7 @@ describe('buildBaseConfig', () => {
|
|||||||
it('configures log scale on y axis when widget.isLogScale is true', () => {
|
it('configures log scale on y axis when widget.isLogScale is true', () => {
|
||||||
const builder = buildBaseConfig({
|
const builder = buildBaseConfig({
|
||||||
...baseProps,
|
...baseProps,
|
||||||
widget: createWidget({ isLogScale: true }),
|
...createBaseConfigBuilderProps({ isLogScale: true }),
|
||||||
});
|
});
|
||||||
|
|
||||||
const config = builder.getConfig();
|
const config = builder.getConfig();
|
||||||
@@ -171,7 +172,7 @@ describe('buildBaseConfig', () => {
|
|||||||
it('adds thresholds from widget', () => {
|
it('adds thresholds from widget', () => {
|
||||||
const builder = buildBaseConfig({
|
const builder = buildBaseConfig({
|
||||||
...baseProps,
|
...baseProps,
|
||||||
widget: createWidget({
|
...createBaseConfigBuilderProps({
|
||||||
thresholds: [
|
thresholds: [
|
||||||
{
|
{
|
||||||
thresholdValue: 80,
|
thresholdValue: 80,
|
||||||
@@ -179,7 +180,7 @@ describe('buildBaseConfig', () => {
|
|||||||
thresholdUnit: 'ms',
|
thresholdUnit: 'ms',
|
||||||
thresholdLabel: 'High',
|
thresholdLabel: 'High',
|
||||||
},
|
},
|
||||||
] as Widgets['thresholds'],
|
] as ThresholdProps[],
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Timezone } from 'components/CustomTimePicker/timezoneUtils';
|
import { Timezone } from 'components/CustomTimePicker/timezoneUtils';
|
||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
|
import { ThresholdProps } from 'container/NewWidget/RightContainer/Threshold/types';
|
||||||
import onClickPlugin, {
|
import onClickPlugin, {
|
||||||
OnClickPluginOpts,
|
OnClickPluginOpts,
|
||||||
} from 'lib/uPlotLib/plugins/onClickPlugin';
|
} from 'lib/uPlotLib/plugins/onClickPlugin';
|
||||||
@@ -9,28 +10,32 @@ import {
|
|||||||
} from 'lib/uPlotV2/config/types';
|
} from 'lib/uPlotV2/config/types';
|
||||||
import { UPlotConfigBuilder } from 'lib/uPlotV2/config/UPlotConfigBuilder';
|
import { UPlotConfigBuilder } from 'lib/uPlotV2/config/UPlotConfigBuilder';
|
||||||
import { ThresholdsDrawHookOptions } from 'lib/uPlotV2/hooks/types';
|
import { ThresholdsDrawHookOptions } from 'lib/uPlotV2/hooks/types';
|
||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
|
||||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
|
|
||||||
import { PanelMode } from '../types';
|
import { PanelMode } from '../types';
|
||||||
|
|
||||||
export interface BaseConfigBuilderProps {
|
export interface BaseConfigBuilderProps {
|
||||||
widget: Widgets;
|
widgetId?: string;
|
||||||
|
thresholds?: ThresholdProps[];
|
||||||
apiResponse: MetricRangePayloadProps;
|
apiResponse: MetricRangePayloadProps;
|
||||||
isDarkMode: boolean;
|
isDarkMode: boolean;
|
||||||
onClick?: OnClickPluginOpts['onClick'];
|
onClick?: OnClickPluginOpts['onClick'];
|
||||||
onDragSelect?: (startTime: number, endTime: number) => void;
|
onDragSelect?: (startTime: number, endTime: number) => void;
|
||||||
timezone?: Timezone;
|
timezone?: Timezone;
|
||||||
panelMode: PanelMode;
|
panelMode?: PanelMode;
|
||||||
panelType: PANEL_TYPES;
|
panelType: PANEL_TYPES;
|
||||||
minTimeScale?: number;
|
minTimeScale?: number;
|
||||||
maxTimeScale?: number;
|
maxTimeScale?: number;
|
||||||
stepInterval?: number;
|
stepInterval?: number;
|
||||||
|
isLogScale?: boolean;
|
||||||
|
yAxisUnit?: string;
|
||||||
|
softMin?: number;
|
||||||
|
softMax?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildBaseConfig({
|
export function buildBaseConfig({
|
||||||
widget,
|
widgetId,
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
onClick,
|
onClick,
|
||||||
onDragSelect,
|
onDragSelect,
|
||||||
@@ -38,9 +43,14 @@ export function buildBaseConfig({
|
|||||||
timezone,
|
timezone,
|
||||||
panelMode,
|
panelMode,
|
||||||
panelType,
|
panelType,
|
||||||
|
thresholds,
|
||||||
minTimeScale,
|
minTimeScale,
|
||||||
maxTimeScale,
|
maxTimeScale,
|
||||||
stepInterval,
|
stepInterval,
|
||||||
|
isLogScale,
|
||||||
|
yAxisUnit,
|
||||||
|
softMin,
|
||||||
|
softMax,
|
||||||
}: BaseConfigBuilderProps): UPlotConfigBuilder {
|
}: BaseConfigBuilderProps): UPlotConfigBuilder {
|
||||||
const tzDate = timezone
|
const tzDate = timezone
|
||||||
? (timestamp: number): Date =>
|
? (timestamp: number): Date =>
|
||||||
@@ -49,27 +59,26 @@ export function buildBaseConfig({
|
|||||||
|
|
||||||
const builder = new UPlotConfigBuilder({
|
const builder = new UPlotConfigBuilder({
|
||||||
onDragSelect,
|
onDragSelect,
|
||||||
widgetId: widget.id,
|
widgetId: widgetId,
|
||||||
tzDate,
|
tzDate,
|
||||||
shouldSaveSelectionPreference: panelMode === PanelMode.DASHBOARD_VIEW,
|
shouldSaveSelectionPreference: panelMode === PanelMode.DASHBOARD_VIEW,
|
||||||
selectionPreferencesSource: [
|
selectionPreferencesSource: panelMode
|
||||||
PanelMode.DASHBOARD_VIEW,
|
? [PanelMode.DASHBOARD_VIEW, PanelMode.STANDALONE_VIEW].includes(panelMode)
|
||||||
PanelMode.STANDALONE_VIEW,
|
? SelectionPreferencesSource.LOCAL_STORAGE
|
||||||
].includes(panelMode)
|
: SelectionPreferencesSource.IN_MEMORY
|
||||||
? SelectionPreferencesSource.LOCAL_STORAGE
|
|
||||||
: SelectionPreferencesSource.IN_MEMORY,
|
: SelectionPreferencesSource.IN_MEMORY,
|
||||||
stepInterval,
|
stepInterval,
|
||||||
});
|
});
|
||||||
|
|
||||||
const thresholdOptions: ThresholdsDrawHookOptions = {
|
const thresholdOptions: ThresholdsDrawHookOptions = {
|
||||||
scaleKey: 'y',
|
scaleKey: 'y',
|
||||||
thresholds: (widget.thresholds || []).map((threshold) => ({
|
thresholds: (thresholds || []).map((threshold) => ({
|
||||||
thresholdValue: threshold.thresholdValue ?? 0,
|
thresholdValue: threshold.thresholdValue ?? 0,
|
||||||
thresholdColor: threshold.thresholdColor,
|
thresholdColor: threshold.thresholdColor,
|
||||||
thresholdUnit: threshold.thresholdUnit,
|
thresholdUnit: threshold.thresholdUnit,
|
||||||
thresholdLabel: threshold.thresholdLabel,
|
thresholdLabel: threshold.thresholdLabel,
|
||||||
})),
|
})),
|
||||||
yAxisUnit: widget.yAxisUnit,
|
yAxisUnit: yAxisUnit,
|
||||||
};
|
};
|
||||||
|
|
||||||
builder.addThresholds(thresholdOptions);
|
builder.addThresholds(thresholdOptions);
|
||||||
@@ -79,8 +88,8 @@ export function buildBaseConfig({
|
|||||||
time: true,
|
time: true,
|
||||||
min: minTimeScale,
|
min: minTimeScale,
|
||||||
max: maxTimeScale,
|
max: maxTimeScale,
|
||||||
logBase: widget.isLogScale ? 10 : undefined,
|
logBase: isLogScale ? 10 : undefined,
|
||||||
distribution: widget.isLogScale
|
distribution: isLogScale
|
||||||
? DistributionType.Logarithmic
|
? DistributionType.Logarithmic
|
||||||
: DistributionType.Linear,
|
: DistributionType.Linear,
|
||||||
});
|
});
|
||||||
@@ -91,11 +100,11 @@ export function buildBaseConfig({
|
|||||||
time: false,
|
time: false,
|
||||||
min: undefined,
|
min: undefined,
|
||||||
max: undefined,
|
max: undefined,
|
||||||
softMin: widget.softMin ?? undefined,
|
softMin: softMin,
|
||||||
softMax: widget.softMax ?? undefined,
|
softMax: softMax,
|
||||||
thresholds: thresholdOptions,
|
thresholds: thresholdOptions,
|
||||||
logBase: widget.isLogScale ? 10 : undefined,
|
logBase: isLogScale ? 10 : undefined,
|
||||||
distribution: widget.isLogScale
|
distribution: isLogScale
|
||||||
? DistributionType.Logarithmic
|
? DistributionType.Logarithmic
|
||||||
: DistributionType.Linear,
|
: DistributionType.Linear,
|
||||||
});
|
});
|
||||||
@@ -114,7 +123,7 @@ export function buildBaseConfig({
|
|||||||
show: true,
|
show: true,
|
||||||
side: 2,
|
side: 2,
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
isLogScale: widget.isLogScale,
|
isLogScale: isLogScale,
|
||||||
panelType,
|
panelType,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -123,8 +132,8 @@ export function buildBaseConfig({
|
|||||||
show: true,
|
show: true,
|
||||||
side: 3,
|
side: 3,
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
isLogScale: widget.isLogScale,
|
isLogScale: isLogScale,
|
||||||
yAxisUnit: widget.yAxisUnit,
|
yAxisUnit: yAxisUnit,
|
||||||
panelType,
|
panelType,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import cx from 'classnames';
|
|||||||
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
|
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
|
import { useTimezone } from 'providers/Timezone';
|
||||||
|
|
||||||
import { TooltipProps } from '../types';
|
import { TooltipProps } from '../types';
|
||||||
|
|
||||||
@@ -22,6 +23,14 @@ export default function Tooltip({
|
|||||||
const isDarkMode = useIsDarkMode();
|
const isDarkMode = useIsDarkMode();
|
||||||
const [listHeight, setListHeight] = useState(0);
|
const [listHeight, setListHeight] = useState(0);
|
||||||
const tooltipContent = content ?? [];
|
const tooltipContent = content ?? [];
|
||||||
|
const { timezone: userTimezone } = useTimezone();
|
||||||
|
|
||||||
|
const resolvedTimezone = useMemo(() => {
|
||||||
|
if (!timezone) {
|
||||||
|
return userTimezone.value;
|
||||||
|
}
|
||||||
|
return timezone.value;
|
||||||
|
}, [timezone, userTimezone]);
|
||||||
|
|
||||||
const headerTitle = useMemo(() => {
|
const headerTitle = useMemo(() => {
|
||||||
if (!showTooltipHeader) {
|
if (!showTooltipHeader) {
|
||||||
@@ -33,10 +42,10 @@ export default function Tooltip({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return dayjs(data[0][cursorIdx] * 1000)
|
return dayjs(data[0][cursorIdx] * 1000)
|
||||||
.tz(timezone)
|
.tz(resolvedTimezone)
|
||||||
.format(DATE_TIME_FORMATS.MONTH_DATETIME_SECONDS);
|
.format(DATE_TIME_FORMATS.MONTH_DATETIME_SECONDS);
|
||||||
}, [
|
}, [
|
||||||
timezone,
|
resolvedTimezone,
|
||||||
uPlotInstance.data,
|
uPlotInstance.data,
|
||||||
uPlotInstance.cursor.idx,
|
uPlotInstance.cursor.idx,
|
||||||
showTooltipHeader,
|
showTooltipHeader,
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ function createUPlotInstance(cursorIdx: number | null): uPlot {
|
|||||||
function renderTooltip(props: Partial<TooltipTestProps> = {}): RenderResult {
|
function renderTooltip(props: Partial<TooltipTestProps> = {}): RenderResult {
|
||||||
const defaultProps: TooltipTestProps = {
|
const defaultProps: TooltipTestProps = {
|
||||||
uPlotInstance: createUPlotInstance(null),
|
uPlotInstance: createUPlotInstance(null),
|
||||||
timezone: 'UTC',
|
timezone: { value: 'UTC', name: 'UTC', offset: '0', searchIndex: '0' },
|
||||||
content: [],
|
content: [],
|
||||||
showTooltipHeader: true,
|
showTooltipHeader: true,
|
||||||
// TooltipRenderArgs (not used directly in component but required by type)
|
// TooltipRenderArgs (not used directly in component but required by type)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
import { Timezone } from 'components/CustomTimePicker/timezoneUtils';
|
||||||
import { PrecisionOption } from 'components/Graph/types';
|
import { PrecisionOption } from 'components/Graph/types';
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ export interface TooltipRenderArgs {
|
|||||||
|
|
||||||
export interface BaseTooltipProps {
|
export interface BaseTooltipProps {
|
||||||
showTooltipHeader?: boolean;
|
showTooltipHeader?: boolean;
|
||||||
timezone: string;
|
timezone?: Timezone;
|
||||||
yAxisUnit?: string;
|
yAxisUnit?: string;
|
||||||
decimalPrecision?: PrecisionOption;
|
decimalPrecision?: PrecisionOption;
|
||||||
content?: TooltipContentItem[];
|
content?: TooltipContentItem[];
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
|
||||||
import { themeColors } from 'constants/theme';
|
import { themeColors } from 'constants/theme';
|
||||||
import { generateColor } from 'lib/uPlotLib/utils/generateColor';
|
import { generateColor } from 'lib/uPlotLib/utils/generateColor';
|
||||||
import { calculateWidthBasedOnStepInterval } from 'lib/uPlotV2/utils';
|
import { calculateWidthBasedOnStepInterval } from 'lib/uPlotV2/utils';
|
||||||
@@ -23,6 +22,9 @@ import {
|
|||||||
* Path builders are static and shared across all instances of UPlotSeriesBuilder
|
* Path builders are static and shared across all instances of UPlotSeriesBuilder
|
||||||
*/
|
*/
|
||||||
let builders: PathBuilders | null = null;
|
let builders: PathBuilders | null = null;
|
||||||
|
|
||||||
|
const DEFAULT_LINE_WIDTH = 2;
|
||||||
|
export const POINT_SIZE_FACTOR = 2.5;
|
||||||
export class UPlotSeriesBuilder extends ConfigBuilder<SeriesProps, Series> {
|
export class UPlotSeriesBuilder extends ConfigBuilder<SeriesProps, Series> {
|
||||||
constructor(props: SeriesProps) {
|
constructor(props: SeriesProps) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -53,7 +55,7 @@ export class UPlotSeriesBuilder extends ConfigBuilder<SeriesProps, Series> {
|
|||||||
const { lineWidth, lineStyle, lineCap, fillColor } = this.props;
|
const { lineWidth, lineStyle, lineCap, fillColor } = this.props;
|
||||||
const lineConfig: Partial<Series> = {
|
const lineConfig: Partial<Series> = {
|
||||||
stroke: resolvedLineColor,
|
stroke: resolvedLineColor,
|
||||||
width: lineWidth ?? 2,
|
width: lineWidth ?? DEFAULT_LINE_WIDTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (lineStyle === LineStyle.Dashed) {
|
if (lineStyle === LineStyle.Dashed) {
|
||||||
@@ -66,9 +68,9 @@ export class UPlotSeriesBuilder extends ConfigBuilder<SeriesProps, Series> {
|
|||||||
|
|
||||||
if (fillColor) {
|
if (fillColor) {
|
||||||
lineConfig.fill = fillColor;
|
lineConfig.fill = fillColor;
|
||||||
} else if (this.props.panelType === PANEL_TYPES.BAR) {
|
} else if (this.props.drawStyle === DrawStyle.Bar) {
|
||||||
lineConfig.fill = resolvedLineColor;
|
lineConfig.fill = resolvedLineColor;
|
||||||
} else if (this.props.panelType === PANEL_TYPES.HISTOGRAM) {
|
} else if (this.props.drawStyle === DrawStyle.Histogram) {
|
||||||
lineConfig.fill = `${resolvedLineColor}40`;
|
lineConfig.fill = `${resolvedLineColor}40`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,10 +139,19 @@ export class UPlotSeriesBuilder extends ConfigBuilder<SeriesProps, Series> {
|
|||||||
drawStyle,
|
drawStyle,
|
||||||
showPoints,
|
showPoints,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If pointSize is not provided, use the lineWidth * POINT_SIZE_FACTOR
|
||||||
|
* to determine the point size.
|
||||||
|
* POINT_SIZE_FACTOR is 2, so the point size will be 2x the line width.
|
||||||
|
*/
|
||||||
|
const resolvedPointSize =
|
||||||
|
pointSize ?? (lineWidth ?? DEFAULT_LINE_WIDTH) * POINT_SIZE_FACTOR;
|
||||||
|
|
||||||
const pointsConfig: Partial<Series.Points> = {
|
const pointsConfig: Partial<Series.Points> = {
|
||||||
stroke: resolvedLineColor,
|
stroke: resolvedLineColor,
|
||||||
fill: resolvedLineColor,
|
fill: resolvedLineColor,
|
||||||
size: !pointSize || pointSize < (lineWidth ?? 2) ? undefined : pointSize,
|
size: resolvedPointSize,
|
||||||
filter: pointsFilter || undefined,
|
filter: pointsFilter || undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -231,7 +242,7 @@ function getPathBuilder({
|
|||||||
throw new Error('Required uPlot path builders are not available');
|
throw new Error('Required uPlot path builders are not available');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawStyle === DrawStyle.Bar) {
|
if (drawStyle === DrawStyle.Bar || drawStyle === DrawStyle.Histogram) {
|
||||||
const pathBuilders = uPlot.paths;
|
const pathBuilders = uPlot.paths;
|
||||||
return getBarPathBuilder({
|
return getBarPathBuilder({
|
||||||
pathBuilders,
|
pathBuilders,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -43,7 +42,6 @@ describe('UPlotConfigBuilder', () => {
|
|||||||
label: 'Requests',
|
label: 'Requests',
|
||||||
colorMapping: {},
|
colorMapping: {},
|
||||||
drawStyle: DrawStyle.Line,
|
drawStyle: DrawStyle.Line,
|
||||||
panelType: PANEL_TYPES.TIME_SERIES,
|
|
||||||
...overrides,
|
...overrides,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
|
||||||
import { themeColors } from 'constants/theme';
|
import { themeColors } from 'constants/theme';
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
|
|
||||||
@@ -9,7 +8,7 @@ import {
|
|||||||
LineStyle,
|
LineStyle,
|
||||||
VisibilityMode,
|
VisibilityMode,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { UPlotSeriesBuilder } from '../UPlotSeriesBuilder';
|
import { POINT_SIZE_FACTOR, UPlotSeriesBuilder } from '../UPlotSeriesBuilder';
|
||||||
|
|
||||||
const createBaseProps = (
|
const createBaseProps = (
|
||||||
overrides: Partial<SeriesProps> = {},
|
overrides: Partial<SeriesProps> = {},
|
||||||
@@ -19,7 +18,6 @@ const createBaseProps = (
|
|||||||
colorMapping: {},
|
colorMapping: {},
|
||||||
drawStyle: DrawStyle.Line,
|
drawStyle: DrawStyle.Line,
|
||||||
isDarkMode: false,
|
isDarkMode: false,
|
||||||
panelType: PANEL_TYPES.TIME_SERIES,
|
|
||||||
...overrides,
|
...overrides,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -137,7 +135,6 @@ describe('UPlotSeriesBuilder', () => {
|
|||||||
const smallPointsBuilder = new UPlotSeriesBuilder(
|
const smallPointsBuilder = new UPlotSeriesBuilder(
|
||||||
createBaseProps({
|
createBaseProps({
|
||||||
lineWidth: 4,
|
lineWidth: 4,
|
||||||
pointSize: 2,
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const largePointsBuilder = new UPlotSeriesBuilder(
|
const largePointsBuilder = new UPlotSeriesBuilder(
|
||||||
@@ -150,7 +147,7 @@ describe('UPlotSeriesBuilder', () => {
|
|||||||
const smallConfig = smallPointsBuilder.getConfig();
|
const smallConfig = smallPointsBuilder.getConfig();
|
||||||
const largeConfig = largePointsBuilder.getConfig();
|
const largeConfig = largePointsBuilder.getConfig();
|
||||||
|
|
||||||
expect(smallConfig.points?.size).toBeUndefined();
|
expect(smallConfig.points?.size).toBe(4 * POINT_SIZE_FACTOR); // should be lineWidth * POINT_SIZE_FACTOR, when pointSize is not provided
|
||||||
expect(largeConfig.points?.size).toBe(4);
|
expect(largeConfig.points?.size).toBe(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ export enum DrawStyle {
|
|||||||
Line = 'line',
|
Line = 'line',
|
||||||
Points = 'points',
|
Points = 'points',
|
||||||
Bar = 'bar',
|
Bar = 'bar',
|
||||||
|
Histogram = 'histogram',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum LineInterpolation {
|
export enum LineInterpolation {
|
||||||
@@ -168,7 +169,6 @@ export interface PointsConfig {
|
|||||||
export interface SeriesProps extends LineConfig, PointsConfig, BarConfig {
|
export interface SeriesProps extends LineConfig, PointsConfig, BarConfig {
|
||||||
scaleKey: string;
|
scaleKey: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
panelType: PANEL_TYPES;
|
|
||||||
colorMapping: Record<string, string>;
|
colorMapping: Record<string, string>;
|
||||||
drawStyle: DrawStyle;
|
drawStyle: DrawStyle;
|
||||||
pathBuilder?: Series.PathBuilder;
|
pathBuilder?: Series.PathBuilder;
|
||||||
|
|||||||
Reference in New Issue
Block a user