forked from ddrilling/asb_cloud_front
На странице Наработка добавлен сброс даты и выделение данных при наведении
This commit is contained in:
parent
74b309ee87
commit
be7e76acf7
@ -11,6 +11,7 @@ const { RangePicker } = DatePicker
|
||||
export type DateRangeWrapperProps = RangePickerSharedProps<Moment> & {
|
||||
value?: RangeValue<Moment>,
|
||||
isUTC?: boolean
|
||||
allowClear?: boolean
|
||||
}
|
||||
|
||||
const normalizeDates = (value?: RangeValue<Moment>, isUTC?: boolean): RangeValue<Moment> => {
|
||||
@ -21,10 +22,10 @@ const normalizeDates = (value?: RangeValue<Moment>, isUTC?: boolean): RangeValue
|
||||
]
|
||||
}
|
||||
|
||||
export const DateRangeWrapper = memo<DateRangeWrapperProps>(({ value, isUTC, ...other }) => (
|
||||
export const DateRangeWrapper = memo<DateRangeWrapperProps>(({ value, isUTC, allowClear = false, ...other }) => (
|
||||
<RangePicker
|
||||
showTime
|
||||
allowClear={false}
|
||||
allowClear={allowClear}
|
||||
format={defaultFormat}
|
||||
defaultValue={[
|
||||
moment().subtract(1, 'days').startOf('day'),
|
||||
|
@ -7,7 +7,7 @@ import { useElementSize } from 'usehooks-ts'
|
||||
|
||||
import '@styles/d3.less'
|
||||
|
||||
type DataType = {
|
||||
export type HorizontalChartDataType = {
|
||||
name: string
|
||||
percent: number
|
||||
}
|
||||
@ -15,16 +15,22 @@ type DataType = {
|
||||
type D3HorizontalChartProps = {
|
||||
width?: string
|
||||
height?: string
|
||||
data: DataType[]
|
||||
data: HorizontalChartDataType[]
|
||||
colors?: string[]
|
||||
selected?: string | null
|
||||
onMouseOver?: (e: MouseEvent, d: HorizontalChartDataType) => 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 (
|
||||
<LoaderPortal show={false} style={{width: givenWidth, height: givenHeight}}>
|
||||
|
@ -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 = [
|
||||
<div style={{ backgroundColor: color, padding: '5px 0' }} />
|
||||
) }),
|
||||
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<DataType[]>([])
|
||||
const [selectedData, setSelectedData] = useState<DataType[]>([])
|
||||
const [dateRange, setDateRange] = useState<Moment[]>([])
|
||||
const [dateRange, setDateRange] = useState<Moment[] | null>([])
|
||||
const [selected, setSelected] = useState<string | null>(null)
|
||||
const [childrenData, setChildrenData] = useState<ReactNode[]>([])
|
||||
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(() => {
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<DateRangeWrapper
|
||||
allowClear
|
||||
allowEmpty={[true, true]}
|
||||
onCalendarChange={(dateRange: any) => setDateRange(dateRange)}
|
||||
value={[dateRange[0], dateRange[1]]}
|
||||
value={[dateRange && dateRange[0], dateRange && dateRange[1]]}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<div style={{width: '100%', height: '50vh'}}>
|
||||
<D3HorizontalChart
|
||||
data={selectedData.map(item => ({name: item.subsystemName, percent: item.kUsage * 100}))}
|
||||
colors={subsystemColors}
|
||||
selected={selected}
|
||||
width={'100%'}
|
||||
height={'50vh'}
|
||||
onMouseOver={onMouseOver}
|
||||
onMouseOut={onMouseOut}
|
||||
/>
|
||||
</div>
|
||||
<Table
|
||||
size={'small'}
|
||||
columns={tableColumns}
|
||||
dataSource={selectedData.map((d, i) => ({...d, color: subsystemColors[i]}))}
|
||||
scroll={{ y: '25vh', x: true }}
|
||||
pagination={false}
|
||||
onRow={onRow}
|
||||
/>
|
||||
</LoaderPortal>
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user