diff --git a/src/components/Table/DateRangeWrapper.tsx b/src/components/Table/DateRangeWrapper.tsx index 587e3bf..4ad140f 100755 --- a/src/components/Table/DateRangeWrapper.tsx +++ b/src/components/Table/DateRangeWrapper.tsx @@ -11,6 +11,7 @@ const { RangePicker } = DatePicker export type DateRangeWrapperProps = RangePickerSharedProps & { value?: RangeValue, isUTC?: boolean + allowClear?: boolean } const normalizeDates = (value?: RangeValue, isUTC?: boolean): RangeValue => { @@ -21,10 +22,10 @@ const normalizeDates = (value?: RangeValue, isUTC?: boolean): RangeValue ] } -export const DateRangeWrapper = memo(({ value, isUTC, ...other }) => ( +export const DateRangeWrapper = memo(({ value, isUTC, allowClear = false, ...other }) => ( void + onMouseOut?: (e: MouseEvent, d: HorizontalChartDataType) => void } -const D3HorizontalChart = memo(( +export const D3HorizontalChart = memo(( { width: givenWidth = '100%', height: givenHeight = '100%', + selected, data, - colors + colors, + onMouseOver, + onMouseOut, }: D3HorizontalChartProps) => { const [rootRef, { width, height }] = useElementSize() @@ -54,6 +60,7 @@ const D3HorizontalChart = memo(( const y = d3.scaleBand() .domain(names) .range([0, chartHeight]) + .padding(0.25) // axes @@ -113,16 +120,17 @@ const D3HorizontalChart = memo(( .attr('fill', (d, i) => colors ? colors[i] : 'black') .attr('y', d => String(y(d.name))) .attr('height', y.bandwidth()) - .transition() - .duration(1000) - .ease(d3.easeLinear) .attr('width', d => d.percent >= 0 ? x(d.percent) : 0) + .attr('stroke', d => selected && d.name === selected ? 'black' : '') + .attr('stroke-width', d => selected && d.name === selected ? '2' : '0') + .on('mouseover', onMouseOver ? onMouseOver : () => {}) + .on('mouseout', onMouseOut ? onMouseOut : () => {}) }) return () => { svg.remove() } - }, [width, height, data]) + }, [width, height, data, colors, selected, onMouseOver, onMouseOut]) return ( diff --git a/src/pages/Telemetry/OperationTime/index.tsx b/src/pages/Telemetry/OperationTime/index.tsx index 7423971..2caed16 100644 --- a/src/pages/Telemetry/OperationTime/index.tsx +++ b/src/pages/Telemetry/OperationTime/index.tsx @@ -5,7 +5,7 @@ import { Moment } from 'moment' import { DateRangeWrapper, makeColumn, makeNumericRender, Table } from '@components/Table' import LoaderPortal from '@components/LoaderPortal' import { arrayOrDefault, wrapPrivateComponent } from '@utils' -import D3HorizontalChart from '@components/d3/D3HorizontalChart' +import { D3HorizontalChart, HorizontalChartDataType } from '@components/d3/D3HorizontalChart' import { useWell } from '@asb/context' import { invokeWebApiWrapperAsync } from '@components/factory' import { SubsystemOperationTimeService } from '@api' @@ -49,22 +49,50 @@ const tableColumns = [
) }), makeColumn('Подсистема', 'subsystemName'), - makeColumn('% использования', 'kUsage', { render: val => (+val * 100).toFixed(2) }), - makeColumn('Проходка, м', 'sumDepthInterval', {render: makeNumericRender(2)}), - makeColumn('Время работы, ч', 'usedTimeHours', {render: makeNumericRender(2)}), - makeColumn('Кол-во запусков', 'operationCount'), + makeColumn('% использования', 'kUsage', { width: 200, render: val => makeNumericRender(2)(+val * 100) }), + makeColumn('Проходка, м', 'sumDepthInterval', { width: 200, render: makeNumericRender(2) }), + makeColumn('Время работы, ч', 'usedTimeHours', { width: 200, render: makeNumericRender(2) }), + makeColumn('Кол-во запусков', 'operationCount', { width: 200, render: makeNumericRender(0) }), ] const OperationTime = memo(() => { const [showLoader, setShowLoader] = useState(false) const [data, setData] = useState([]) const [selectedData, setSelectedData] = useState([]) - const [dateRange, setDateRange] = useState([]) + const [dateRange, setDateRange] = useState([]) + const [selected, setSelected] = useState(null) const [childrenData, setChildrenData] = useState([]) const [well] = useWell() const errorNotifyText = `Не удалось загрузить данные` + const onRow = useCallback((item: DataType) => { + const out = { + onMouseEnter: () => { + setSelected(item.subsystemName) + }, + onMouseLeave: () => { + setSelected(null) + }, + style: {} + } + + if (item.subsystemName === selected) { + out.style = { background: '#FAFAFA', fontSize: '16px', fontWeight: '600' } + + } + + return out + }, [selected]) + + const onMouseOver = useCallback(function (e: MouseEvent, d: HorizontalChartDataType) { + setSelected(d.name) + }, []) + + const onMouseOut = useCallback(function (e: MouseEvent, d: HorizontalChartDataType) { + setSelected(null) + }, []) + useEffect(() => { invokeWebApiWrapperAsync( async () => { @@ -73,8 +101,8 @@ const OperationTime = memo(() => { const responseData:DataType[] = arrayOrDefault(await SubsystemOperationTimeService.getStat( well.id, undefined, - dateRange[1] ? dateRange[0]?.toISOString() : undefined, - dateRange[1]?.toISOString(), + dateRange && dateRange[1] ? dateRange[0]?.toISOString() : undefined, + dateRange && dateRange[1] ? dateRange[1].toISOString() : undefined, )) setData(responseData) setSelectedData(responseData) @@ -124,25 +152,29 @@ const OperationTime = memo(() => { setDateRange(dateRange)} - value={[dateRange[0], dateRange[1]]} + value={[dateRange && dateRange[0], dateRange && dateRange[1]]} /> -
- ({name: item.subsystemName, percent: item.kUsage * 100}))} - colors={subsystemColors} - width={'100%'} - height={'50vh'} - /> -
+ ({name: item.subsystemName, percent: item.kUsage * 100}))} + colors={subsystemColors} + selected={selected} + width={'100%'} + height={'50vh'} + onMouseOver={onMouseOver} + onMouseOut={onMouseOut} + /> ({...d, color: subsystemColors[i]}))} scroll={{ y: '25vh', x: true }} pagination={false} + onRow={onRow} /> )