segmented buttons style

This commit is contained in:
2026-07-08 14:48:50 +05:00
parent 9a542ce33e
commit 1127b14946
7 changed files with 85 additions and 38 deletions

View File

@@ -16,6 +16,7 @@ import { useHistoryChartQueries } from './useHistoryChartQueries';
import { useHistoryChartSeries } from './useHistoryChartSeries';
type HistoryChartProps = {
avgLineMode: AvgLineMode;
edge: string;
from: string;
granulate: string;
@@ -42,6 +43,7 @@ function shouldShowAvgLine(mode: AvgLineMode, range: HistoryZoomRange): boolean
}
export function HistoryChart({
avgLineMode,
edge,
from,
granulate,
@@ -62,7 +64,6 @@ export function HistoryChart({
const zoomRangeRef = useRef(zoomRange);
const zoomTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const lastReadyOptionRef = useRef<EChartsOption | null>(null);
const [avgLineMode, setAvgLineMode] = useState<AvgLineMode>('auto');
const lines = useHistoryChartQueries({
edge,
from: zoomRange.from,
@@ -149,13 +150,12 @@ export function HistoryChart({
return (
<HistoryChartArea
avgLineMode={avgLineMode}
hasData={displayHasData}
hasSelection={tags.length > 0}
loading={loading}
avgLineMode={avgLineMode}
option={displayOption}
onDataZoom={handleDataZoom}
onAvgLineModeChange={setAvgLineMode}
/>
);
}

View File

@@ -2,8 +2,9 @@ import type { EChartsOption } from 'echarts';
import ReactEChartsCore from 'echarts-for-react/esm/core.js';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import type { WheelEvent } from 'react';
import type { AvgLineMode, DataZoomEventBatch } from './chartTypes';
import type { DataZoomEventBatch } from './chartTypes';
import { echarts } from './historyChartEcharts';
import type { AvgLineMode } from './chartTypes';
type HistoryChartAreaProps = {
avgLineMode: AvgLineMode;
@@ -11,17 +12,9 @@ type HistoryChartAreaProps = {
hasSelection: boolean;
loading: boolean;
option: EChartsOption;
onAvgLineModeChange: (mode: AvgLineMode) => void;
onDataZoom: (event: DataZoomEventBatch) => void;
};
// Порядок режимов соответствует требованию: авто, принудительно рисовать, принудительно скрыть.
const AVG_LINE_MODES: Array<{ value: AvgLineMode; label: string }> = [
{ value: 'auto', label: 'Авто' },
{ value: 'show', label: 'Рисовать' },
{ value: 'hide', label: 'Не рисовать' },
];
/** Включает или выключает нативный X-зум колесом, чтобы Shift + колесо работал только по Y. */
function setXAxisWheelZoom(chart: ReturnType<ReactEChartsCore['getEchartsInstance']>, enabled: boolean): void {
chart.setOption(
@@ -44,7 +37,6 @@ export function HistoryChartArea({
hasSelection,
loading,
option,
onAvgLineModeChange,
onDataZoom,
}: HistoryChartAreaProps) {
const chartRef = useRef<InstanceType<typeof ReactEChartsCore> | null>(null);
@@ -111,22 +103,6 @@ export function HistoryChartArea({
return (
<div className="history-chart-shell" onWheelCapture={handleWheelCapture}>
<div className="history-chart-controls" aria-label="Режим соединительной линии avg">
<span>Линия avg</span>
<div className="segmented history-chart-line-mode">
{AVG_LINE_MODES.map((mode) => (
<button
key={mode.value}
type="button"
className={mode.value === avgLineMode ? 'history-chart-line-mode__button--active' : undefined}
onClick={() => onAvgLineModeChange(mode.value)}
aria-pressed={mode.value === avgLineMode}
>
{mode.label}
</button>
))}
</div>
</div>
<ReactEChartsCore
key={avgLineMode}
ref={chartRef}

View File

@@ -0,0 +1,33 @@
import type { AvgLineMode } from './chartTypes';
type HistoryChartAvgLineModeControlProps = {
value: AvgLineMode;
onChange: (mode: AvgLineMode) => void;
};
const AVG_LINE_MODES: Array<{ value: AvgLineMode; label: string }> = [
{ value: 'auto', label: 'Авто' },
{ value: 'show', label: 'Рисовать' },
{ value: 'hide', label: 'Не рисовать' },
];
export function HistoryChartAvgLineModeControl({ value, onChange }: HistoryChartAvgLineModeControlProps) {
return (
<div className="archive-avgline-mode-control" aria-label="Режим соединительной линии avg">
<span>Линия avg</span>
<div className="segmented history-chart-line-mode">
{AVG_LINE_MODES.map((mode) => (
<button
key={mode.value}
type="button"
className={mode.value === value ? 'history-chart-line-mode__button--active' : undefined}
onClick={() => onChange(mode.value)}
aria-pressed={mode.value === value}
>
{mode.label}
</button>
))}
</div>
</div>
);
}

View File

@@ -41,7 +41,7 @@ function createAvgLineData(points: HistoryPoint[], granulate: string, breakOnGap
}
const previousTime = new Date(finitePoints[index - 1].time).getTime();
const hasAcceptableGap = currentTime - previousTime <= slotMs * 100;
const hasAcceptableGap = currentTime - previousTime <= slotMs * 24;
return hasAcceptableGap ? [currentPoint] : [null, currentPoint];
});