Skip to content

Commit

Permalink
StatsHouse UI: feature byte_as_bits unit
Browse files Browse the repository at this point in the history
  • Loading branch information
vauweb committed Oct 25, 2024
1 parent e313058 commit df0208c
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 30 deletions.
23 changes: 15 additions & 8 deletions statshouse-ui/src/admin/pages/FormPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ export function EditForm(props: { isReadonly: boolean; adminMode: boolean }) {
}, [] as number[]),
[values.tags, values.tagsSize]
);
const otherResolution = useMemo(() => {
if ([1, 5, 15, 60].indexOf(values.resolution) < 0) {
return values.resolution;
}
return false;
}, [values.resolution]);

return (
<form key={values.version}>
Expand Down Expand Up @@ -231,17 +237,18 @@ export function EditForm(props: { isReadonly: boolean; adminMode: boolean }) {
disabled={isReadonly}
>
<option value="1">1 second (native, default)</option>
<option value="2">2 seconds</option>
<option value="3">3 seconds</option>
<option value="4">4 seconds</option>
{/*<option value="2">2 seconds</option>*/}
{/*<option value="3">3 seconds</option>*/}
{/*<option value="4">4 seconds</option>*/}
<option value="5">5 seconds (native)</option>
<option value="6">6 seconds</option>
<option value="10">10 seconds</option>
<option value="12">12 seconds</option>
{/*<option value="6">6 seconds</option>*/}
{/*<option value="10">10 seconds</option>*/}
{/*<option value="12">12 seconds</option>*/}
<option value="15">15 seconds (native)</option>
<option value="20">20 seconds</option>
<option value="30">30 seconds</option>
{/*<option value="20">20 seconds</option>*/}
{/*<option value="30">30 seconds</option>*/}
<option value="60">60 seconds (native)</option>
{otherResolution !== false && <option value={otherResolution}>{otherResolution} seconds</option>}
</select>
</div>
<div id="resolutionHelpBlock" className="form-text">
Expand Down
3 changes: 3 additions & 0 deletions statshouse-ui/src/api/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ export const METRIC_TYPE = {
nanosecond: 'nanosecond',
// data size
byte: 'byte',
byte_as_bits: 'byte_as_bits',
} as const;
export type MetricType = Enum<typeof METRIC_TYPE>;
export const isMetricType = isEnum<MetricType>(METRIC_TYPE);
Expand All @@ -248,6 +249,7 @@ export const METRIC_TYPE_DESCRIPTION: Record<MetricType, string> = {
[METRIC_TYPE.microsecond]: 'microsecond',
[METRIC_TYPE.nanosecond]: 'nanosecond',
[METRIC_TYPE.byte]: 'byte',
[METRIC_TYPE.byte_as_bits]: 'byte (shown as bits)',
};

export const METRIC_TYPE_URL = {
Expand All @@ -259,6 +261,7 @@ export const METRIC_TYPE_URL = {
[METRIC_TYPE.nanosecond]: 'ns',
// data size
[METRIC_TYPE.byte]: 'b',
[METRIC_TYPE.byte_as_bits]: 'bbt',
} as const;
export type MetricTypeUrl = Enum<typeof METRIC_TYPE_URL>;
export const isMetricTypeUrl = isEnum<MetricTypeUrl>(METRIC_TYPE_URL);
Expand Down
7 changes: 7 additions & 0 deletions statshouse-ui/src/common/byteAsBitsData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import uPlot from 'uplot';

export function byteAsBitsData(data: uPlot.AlignedData): uPlot.AlignedData {
// @ts-ignore
let data2: uPlot.AlignedData = data.slice(1).map((l) => l.map((v) => (v == null ? v : v * 8)));
return [data[0].slice(), ...data2];
}
41 changes: 41 additions & 0 deletions statshouse-ui/src/common/formatByMetricType.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,29 @@ describe('formatByMetricType', () => {
expect(formatter(100 * p)).toEqual('102400YiB');
expect(formatter(1000 * p)).toEqual('1024000YiB');
});
test('byte_as_bits', () => {
const formatter = formatByMetricType(METRIC_TYPE.byte_as_bits);
expect(formatter(0)).toEqual('0');
expect(formatter(0.01111)).toEqual('0.088b');
expect(formatter(0.001111)).toEqual('8.888mb');
expect(formatter(0.000001111)).toEqual('8.888μb');
expect(formatter(0.000000001111)).toEqual('8.888nb');
expect(formatter(0.000000000001111)).toEqual('8.888pb');
expect(formatter(0.000000000000001111)).toEqual('8.888fb');
expect(formatter(0.000000000000000001111)).toEqual('8.888ab');
expect(formatter(0.000000000000000000001111)).toEqual('8.888zb');
expect(formatter(0.000000000000000000000001111)).toEqual('8.888yb');
expect(formatter(0.000000000000000000000000001111)).toEqual('0.008yb');
expect(formatter(1111)).toEqual('8.888Kb');
expect(formatter(1111100)).toEqual('8.888Mb');
expect(formatter(1111100000)).toEqual('8.888Gb');
expect(formatter(1111100000000)).toEqual('8.888Tb');
expect(formatter(1111100000000000)).toEqual('8.888Pb');
expect(formatter(1111100000000000000)).toEqual('8.888Eb');
expect(formatter(1111100000000000000000)).toEqual('8.888Zb');
expect(formatter(1111100000000000000000000)).toEqual('8.888Yb');
expect(formatter(1111100000000000000000000000)).toEqual('8888.8Yb');
});
test('second', () => {
const formatter = formatByMetricType(METRIC_TYPE.second);
expect(formatter(0)).toEqual('0');
Expand Down Expand Up @@ -349,4 +372,22 @@ describe('formatByMetricType', () => {
0, 201326592, 402653184, 603979776, 805306368, 1006632960,
]);
});
test('splitByMetricType byte_as_bits', () => {
const split = splitByMetricType(METRIC_TYPE.byte_as_bits);
expect(split(null, 1, 0, 1, 0.1, 0)).toEqual([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]);
expect(split(null, 1, 0, 2, 0.25, 0)).toEqual([0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]);
expect(split(null, 1, 0, 10, 1, 0)).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
expect(split(null, 1, 0, 120, 10, 0)).toEqual([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120]);
expect(split(null, 1, 0, 1024, 100, 0)).toEqual([0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]);
expect(split(null, 1, 0, 100 * 1024, 10000, 0)).toEqual([
0, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000, 100000,
]);
expect(split(null, 1, 0, 1024 * 1024, 200000, 0)).toEqual([0, 200000, 400000, 600000, 800000, 1000000]);
expect(split(null, 1, 0, 100 * 1024 * 1024, 10000000, 0)).toEqual([
0, 10000000, 20000000, 30000000, 40000000, 50000000, 60000000, 70000000, 80000000, 90000000, 100000000,
]);
expect(split(null, 1, 0, 1024 * 1024 * 1024, 200000000, 0)).toEqual([
0, 200000000, 400000000, 600000000, 800000000, 1000000000,
]);
});
});
55 changes: 47 additions & 8 deletions statshouse-ui/src/common/formatByMetricType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,35 @@ const baseMetricTypeSi: ConfigConvertMetric = {
'8': 'Y',
},
};
const baseMetricTypeByteAsBits: ConfigConvertMetric = {
baseOffset: 0,
getBase(n) {
return Math.max(-8, Math.min(8, getMetricTypeBase(n)));
},
format(n) {
const base = this.getBase(8 * n);
return floor((8 * n) / Math.pow(10, base * 3), 3) + (this.suffix[base] ?? '');
},
suffix: {
'-8': 'yb',
'-7': 'zb',
'-6': 'ab',
'-5': 'fb',
'-4': 'pb',
'-3': 'nb',
'-2': 'μb',
'-1': 'mb',
'0': 'b',
'1': 'Kb',
'2': 'Mb',
'3': 'Gb',
'4': 'Tb',
'5': 'Pb',
'6': 'Eb',
'7': 'Zb',
'8': 'Yb',
},
};
const baseMetricTypeSecond: ConfigConvertMetric = {
baseOffset: 0,
getBase(n) {
Expand Down Expand Up @@ -140,6 +169,9 @@ export const suffixesByMetricType: Record<MetricType, ConfigConvertMetric> = {
[METRIC_TYPE.none]: {
...baseMetricTypeSi,
},
[METRIC_TYPE.byte_as_bits]: {
...baseMetricTypeByteAsBits,
},
[METRIC_TYPE.byte]: {
...baseMetricTypeByte,
},
Expand Down Expand Up @@ -181,7 +213,7 @@ export function splitByMetricType(metricType: MetricType) {
): number[] => {
let splits: number[] = [];
const conf = suffixesByMetricType[metricType];
const base = conf.getBase(Math.max(Math.abs(scaleMin), Math.abs(scaleMax)));
let base = conf.getBase(Math.max(Math.abs(scaleMin), Math.abs(scaleMax)));
function fixFloat(v: number) {
return round(v, 14);
}
Expand All @@ -199,6 +231,9 @@ export function splitByMetricType(metricType: MetricType) {
case METRIC_TYPE.millisecond:
p = 0.001;
break;
case METRIC_TYPE.byte_as_bits:
p = 8;
break;
}
let incr = fixFloat(foundIncr);
let start = incrRoundUp(scaleMin, incr);
Expand All @@ -218,17 +253,21 @@ export function splitByMetricType(metricType: MetricType) {
end = scaleMax + incr / 100;
}
break;

case METRIC_TYPE.byte:
default:
if (base > 0) {
const r1 = Math.pow(2, 10 * base - base - 1); //?
const r2 = Math.pow(2, 10 * base); //?
const radix = Math.abs(foundIncr - r1) < Math.abs(foundIncr - r2) ? r1 : r2; //?
incr = round(foundIncr * p, -1, radix) / p || round(2 * foundIncr * p, -1, radix) / p; //?
start = round(incrRoundUp(round(scaleMin * p, -1, radix), incr)) / p; //?
end = scaleMax + incr / 100; //?
const r1 = Math.pow(2, 10 * base - base - 1);
const r2 = Math.pow(2, 10 * base);
const radix = Math.abs(foundIncr - r1) < Math.abs(foundIncr - r2) ? r1 : r2;
incr = round(foundIncr * p, -1, radix) / p || round(2 * foundIncr * p, -1, radix) / p;
start = round(incrRoundUp(round(scaleMin * p, -1, radix), incr)) / p;
end = scaleMax + incr / 100;
}
break;
case METRIC_TYPE.byte_as_bits:
// base = conf.getBase(Math.max(Math.abs(8 * scaleMin), Math.abs(8 * scaleMax)));
break;
default:
}
if (incr > 0) {
for (let val = start; val <= end; val = val + incr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function PlotValueUnit({ unit, value }: PlotValueUnitProps) {
}
return value != null ? (
<span className="small text-secondary">
{format(value)}&nbsp;({value})
{unit} {format(value)}&nbsp;({value})
</span>
) : null;
}
11 changes: 8 additions & 3 deletions statshouse-ui/src/components2/Plot/PlotView/PlotEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export function PlotEvents({ plotKey, className, onCursor, cursor }: PlotEventsP
[eventColumns, plotEventsData?.what]
);
const loadPrev = useCallback(() => {
!!plotEventsData?.prevKey &&
if (!!plotEventsData?.prevKey) {
loadPlotEvents(plotKey, plotEventsData.prevKey, true)
.then((res) => {
if (gridRef.current?.element && res) {
Expand All @@ -91,10 +91,13 @@ export function PlotEvents({ plotKey, className, onCursor, cursor }: PlotEventsP
}
})
.catch(() => undefined);
}
}, [loadPlotEvents, plotEventsData?.chunks.length, plotEventsData?.prevKey, plotKey]);

const loadNext = useCallback(() => {
!!plotEventsData?.nextKey && loadPlotEvents(plotKey, plotEventsData.nextKey, false).catch(() => undefined);
if (!!plotEventsData?.nextKey) {
loadPlotEvents(plotKey, plotEventsData.nextKey, false).catch(() => undefined);
}
}, [loadPlotEvents, plotEventsData?.nextKey, plotKey]);

const onScroll = useCallback(
Expand All @@ -111,7 +114,9 @@ export function PlotEvents({ plotKey, className, onCursor, cursor }: PlotEventsP
}
} else {
setParams((p) => {
p.eventFrom = 0;
if (p.eventFrom !== 0) {
p.eventFrom = 0;
}
}, true);
}
if (
Expand Down
12 changes: 8 additions & 4 deletions statshouse-ui/src/components2/Plot/PlotView/PlotViewEvent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ export function PlotViewEvent({ plotKey, className, isDashboard }: PlotViewProps
metricUnit,
metricUnitData,

data,
dataView,
bands,
series,
// scales,
timeRangeTo,
Expand Down Expand Up @@ -99,7 +100,8 @@ export function PlotViewEvent({ plotKey, className, isDashboard }: PlotViewProps
error403: plotData?.error403 ?? '',
metricUnit: plot?.metricUnit,
metricUnitData: plotData?.metricUnit ?? metricMeta[plot?.metricName ?? '']?.metric_type,
data: plotData?.data,
dataView: plotData?.dataView,
bands: plotData?.bands,
series: plotData?.series,
// scales: plotData?.scales,
seriesShow: plotData?.seriesShow,
Expand Down Expand Up @@ -398,7 +400,8 @@ export function PlotViewEvent({ plotKey, className, isDashboard }: PlotViewProps
className="position-relative w-100 z-1"
style={
{
paddingTop: '15%',
// paddingTop: '15%',
paddingTop: '55%',
'--plot-padding-top': `${topPad}px`,
} as React.CSSProperties
}
Expand All @@ -410,7 +413,8 @@ export function PlotViewEvent({ plotKey, className, isDashboard }: PlotViewProps
) : (
<UPlotWrapper
opts={opts}
data={data}
data={dataView}
bands={bands}
series={series}
scales={scales}
onReady={onReady}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function PlotViewMetric({ className, plotKey, isDashboard }: PlotViewProp
metricUnit,
metricUnitData,
topInfo,
data,
dataView,
series,
timeRangeTo,
timeRangeFrom,
Expand All @@ -82,7 +82,7 @@ export function PlotViewMetric({ className, plotKey, isDashboard }: PlotViewProp
error403: plotData?.error403 ?? '',
metricUnit: plot?.metricUnit,
metricUnitData: plotData?.metricUnit ?? metricMeta[plot?.metricName ?? '']?.metric_type,
data: plotData?.data,
dataView: plotData?.dataView,
series: plotData?.series,
seriesShow: plotData?.seriesShow,
legendNameWidth: plotData?.legendNameWidth,
Expand Down Expand Up @@ -371,7 +371,7 @@ export function PlotViewMetric({ className, plotKey, isDashboard }: PlotViewProp
) : (
<UPlotWrapper
opts={opts}
data={data}
data={dataView}
series={series}
scales={scales}
onReady={onReady}
Expand Down
7 changes: 5 additions & 2 deletions statshouse-ui/src/store2/plotDataStore/normalizePlotData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function normalizePlotData(
const usedBaseColors = {};
const baseColors: Record<string, string> = {};

if (plot.type === PLOT_TYPE.Event) {
if (plot.type === PLOT_TYPE.Event && response.series.series_meta.length > 0) {
series_meta = [];
series_data = [];
const colorIndex = new Map<string, number>();
Expand Down Expand Up @@ -130,10 +130,12 @@ export function normalizePlotData(

plotData.legendMaxHostWidth = 0;
plotData.legendMaxHostPercentWidth = 0;

const localData: uPlot.AlignedData = [response.series.time, ...series_data];
plotData.dataView = plotData.data = localData;
plotData.bands = undefined;

if (currentPrevLastPlotParams?.type === PLOT_TYPE.Event) {
if (plot?.type === PLOT_TYPE.Event) {
const stacked = stackData(plotData.data);
plotData.dataView = stacked.data;
plotData.bands = stacked.bands;
Expand Down Expand Up @@ -323,6 +325,7 @@ export function normalizePlotData(
plotData.promQL = response.promql;
plotData.lastPlotParams = deepClone(plot);
plotData.lastTimeRange = deepClone(timeRange);
plotData.lastTimeShifts = deepClone(timeShifts);

const maxLengthValue = plotData.series.reduce(
(res, s, indexSeries) => {
Expand Down
2 changes: 1 addition & 1 deletion statshouse-ui/src/store2/plotDataStore/plotsDataStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export const plotsDataStore: StoreSlice<StatsHouseStore, PlotsDataStore> = (setS
getState().loadPlotData(iPlot, true);
}
});
if (plot?.type === PLOT_TYPE.Event && plotKey === getState().params.tabNum) {
if (plot?.type === PLOT_TYPE.Event && plotKey === getState().params.tabNum && update) {
const { params } = getState();
const from =
params.timeRange.from + params.timeRange.to < params.eventFrom && params.timeRange.to > params.eventFrom
Expand Down

0 comments on commit df0208c

Please sign in to comment.