mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-01 18:10:39 +08:00

* feat: done with prd full view * refactor: updated some variable and naming convection * feat: when click on label only select associated graph * feat: made the table scrollable * feat: update the table column length * feat: save notification after saving state * refactor: removed unwanted code * refactor: renamed some file * fix: linter issue * fix: position of save button * refactor: seperated widgetGraphComponent from gridGraphComponent * feat: fetching the localstorage data while initial loading of graph * fix: dependency of graphVisibilityHandler for other component * refactor: updated the notification msg on save * fix: linter error * refactor: remove the update logic of graph from graph component * refactor: created utils and move some utility code * refactor: place the checkbox component in fullview * refactor: updated the utils function added enun localstorage * refactor: added enum for table columns data * refactor: name changes to graphVisibilityStates * refactor: shifted the type to types.ts * refactor: sepearated the type from graph componnet * refactor: seperated graphOptions from graph component * refactor: updated imports * refactor: shifted the logic to utils * refactor: remove unused file and check for full view * refactor: using PanelType instead of GraphType * refactor: changed the variable name * refactor: provided checks of useEffect * test: added unit test case for utility function * refactor: one on one maping of props and value * refactor: panelTypeAndGraphManagerVisibility as a props * refactor: remove the enforing of type in useChartMutable * refactor: updated the test case * refactor: moved types to types.ts files * refactor: separated types from components * refactor: one to one mapping and cancel feature * refactor: remove unwanted useEffect and used eventEmitter * fix: only open chart visibility will change issue * refactor: removed unwanted useEffect * refactor: resolve the hang issue for full view * refactor: legend to checkbox connection, separated code * refactor: updated styled component GraphContainer * chore: removed unwanted consoles * refactor: ux changes * fix: eslint and updated test case * refactor: review comments * chore: fix types * refactor: made utils for getIsGraphLegendToggleAvailable * refactor: removed the ref mutation from graphPanelSwitch * refactor: resolve the issue of chart state not getting reflect outside fullview * refactor: common utility for toggle graphs visibility in chart * refactor: shifted ref to perticular component level * test: removed extra space * chore: close on save and NaN infinity check * refactor: added yAxisUnit to GraphManager table header * refactor: create a function for appending yAxisUnit to table header * fix: decimal upto 2 decimal points --------- Co-authored-by: Vishal Sharma <makeavish786@gmail.com> Co-authored-by: Pranay Prateek <pranay@signoz.io> Co-authored-by: Palash Gupta <palashgdev@gmail.com>
141 lines
3.4 KiB
TypeScript
141 lines
3.4 KiB
TypeScript
import { Chart, TimeUnit } from 'chart.js';
|
|
import { useMemo } from 'react';
|
|
import { useSelector } from 'react-redux';
|
|
import { AppState } from 'store/reducers';
|
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
|
|
|
import { IAxisTimeConfig, IAxisTimeUintConfig, ITimeRange } from './types';
|
|
|
|
export const TIME_UNITS: Record<TimeUnit, TimeUnit> = {
|
|
millisecond: 'millisecond',
|
|
second: 'second',
|
|
minute: 'minute',
|
|
hour: 'hour',
|
|
day: 'day',
|
|
week: 'week',
|
|
month: 'month',
|
|
year: 'year',
|
|
quarter: 'quarter',
|
|
};
|
|
|
|
const TIME_UNITS_CONFIG: IAxisTimeUintConfig[] = [
|
|
{
|
|
unitName: TIME_UNITS.millisecond,
|
|
multiplier: 1,
|
|
},
|
|
{
|
|
unitName: TIME_UNITS.second,
|
|
multiplier: 1 / 1e3,
|
|
},
|
|
{
|
|
unitName: TIME_UNITS.minute,
|
|
multiplier: 1 / (1e3 * 60),
|
|
},
|
|
{
|
|
unitName: TIME_UNITS.hour,
|
|
multiplier: 1 / (1e3 * 60 * 60),
|
|
},
|
|
{
|
|
unitName: TIME_UNITS.day,
|
|
multiplier: 1 / (1e3 * 60 * 60 * 24),
|
|
},
|
|
{
|
|
unitName: TIME_UNITS.week,
|
|
multiplier: 1 / (1e3 * 60 * 60 * 24 * 7),
|
|
},
|
|
{
|
|
unitName: TIME_UNITS.month,
|
|
multiplier: 1 / (1e3 * 60 * 60 * 24 * 30),
|
|
},
|
|
{
|
|
unitName: TIME_UNITS.year,
|
|
multiplier: 1 / (1e3 * 60 * 60 * 24 * 365),
|
|
},
|
|
];
|
|
|
|
/**
|
|
* Finds the relevant time unit based on the input time stamps (in ms)
|
|
*/
|
|
export const convertTimeRange = (
|
|
start: number,
|
|
end: number,
|
|
): IAxisTimeConfig => {
|
|
const MIN_INTERVALS = 6;
|
|
const range = end - start;
|
|
let relevantTimeUnit = TIME_UNITS_CONFIG[1];
|
|
let stepSize = 1;
|
|
try {
|
|
for (let idx = TIME_UNITS_CONFIG.length - 1; idx >= 0; idx -= 1) {
|
|
const timeUnit = TIME_UNITS_CONFIG[idx];
|
|
const units = range * timeUnit.multiplier;
|
|
const steps = units / MIN_INTERVALS;
|
|
if (steps >= 1) {
|
|
relevantTimeUnit = timeUnit;
|
|
stepSize = steps;
|
|
break;
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
|
|
return {
|
|
unitName: relevantTimeUnit.unitName,
|
|
stepSize: Math.floor(stepSize) || 1,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Accepts Chart.js data's data-structure and returns the relevant time unit for the axis based on the range of the data.
|
|
*/
|
|
export const useXAxisTimeUnit = (data: Chart['data']): IAxisTimeConfig => {
|
|
// Local time is the time range inferred from the input chart data.
|
|
let localTime: ITimeRange | null;
|
|
try {
|
|
let minTime = Number.POSITIVE_INFINITY;
|
|
let maxTime = Number.NEGATIVE_INFINITY;
|
|
data?.labels?.forEach((timeStamp: unknown): void => {
|
|
const getTimeStamp = (time: Date | number): Date | number | string => {
|
|
if (time instanceof Date) {
|
|
return Date.parse(time.toString());
|
|
}
|
|
|
|
return time;
|
|
};
|
|
const time = getTimeStamp(timeStamp as Date | number);
|
|
|
|
minTime = Math.min(parseInt(time.toString(), 10), minTime);
|
|
maxTime = Math.max(parseInt(time.toString(), 10), maxTime);
|
|
});
|
|
|
|
localTime = {
|
|
minTime: minTime === Number.POSITIVE_INFINITY ? null : minTime,
|
|
maxTime: maxTime === Number.NEGATIVE_INFINITY ? null : maxTime,
|
|
};
|
|
} catch (error) {
|
|
localTime = null;
|
|
console.error(error);
|
|
}
|
|
|
|
// Global time is the time selected from the global time selector menu.
|
|
const globalTime = useSelector<AppState, GlobalReducer>(
|
|
(state) => state.globalTime,
|
|
);
|
|
|
|
// Use local time if valid else use the global time range
|
|
const { maxTime, minTime } = useMemo(() => {
|
|
if (localTime && localTime.maxTime && localTime.minTime) {
|
|
return {
|
|
minTime: localTime.minTime,
|
|
maxTime: localTime.maxTime,
|
|
};
|
|
}
|
|
return {
|
|
minTime: globalTime.minTime / 1e6,
|
|
maxTime: globalTime.maxTime / 1e6,
|
|
};
|
|
}, [globalTime, localTime]);
|
|
|
|
return convertTimeRange(minTime, maxTime);
|
|
};
|