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> & {
|
export type DateRangeWrapperProps = RangePickerSharedProps<Moment> & {
|
||||||
value?: RangeValue<Moment>,
|
value?: RangeValue<Moment>,
|
||||||
isUTC?: boolean
|
isUTC?: boolean
|
||||||
|
allowClear?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalizeDates = (value?: RangeValue<Moment>, isUTC?: boolean): RangeValue<Moment> => {
|
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
|
<RangePicker
|
||||||
showTime
|
showTime
|
||||||
allowClear={false}
|
allowClear={allowClear}
|
||||||
format={defaultFormat}
|
format={defaultFormat}
|
||||||
defaultValue={[
|
defaultValue={[
|
||||||
moment().subtract(1, 'days').startOf('day'),
|
moment().subtract(1, 'days').startOf('day'),
|
||||||
|
@ -7,7 +7,7 @@ import { useElementSize } from 'usehooks-ts'
|
|||||||
|
|
||||||
import '@styles/d3.less'
|
import '@styles/d3.less'
|
||||||
|
|
||||||
type DataType = {
|
export type HorizontalChartDataType = {
|
||||||
name: string
|
name: string
|
||||||
percent: number
|
percent: number
|
||||||
}
|
}
|
||||||
@ -15,16 +15,22 @@ type DataType = {
|
|||||||
type D3HorizontalChartProps = {
|
type D3HorizontalChartProps = {
|
||||||
width?: string
|
width?: string
|
||||||
height?: string
|
height?: string
|
||||||
data: DataType[]
|
data: HorizontalChartDataType[]
|
||||||
colors?: string[]
|
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%',
|
width: givenWidth = '100%',
|
||||||
height: givenHeight = '100%',
|
height: givenHeight = '100%',
|
||||||
|
selected,
|
||||||
data,
|
data,
|
||||||
colors
|
colors,
|
||||||
|
onMouseOver,
|
||||||
|
onMouseOut,
|
||||||
}: D3HorizontalChartProps) => {
|
}: D3HorizontalChartProps) => {
|
||||||
|
|
||||||
const [rootRef, { width, height }] = useElementSize()
|
const [rootRef, { width, height }] = useElementSize()
|
||||||
@ -54,6 +60,7 @@ const D3HorizontalChart = memo((
|
|||||||
const y = d3.scaleBand()
|
const y = d3.scaleBand()
|
||||||
.domain(names)
|
.domain(names)
|
||||||
.range([0, chartHeight])
|
.range([0, chartHeight])
|
||||||
|
.padding(0.25)
|
||||||
|
|
||||||
// axes
|
// axes
|
||||||
|
|
||||||
@ -113,16 +120,17 @@ const D3HorizontalChart = memo((
|
|||||||
.attr('fill', (d, i) => colors ? colors[i] : 'black')
|
.attr('fill', (d, i) => colors ? colors[i] : 'black')
|
||||||
.attr('y', d => String(y(d.name)))
|
.attr('y', d => String(y(d.name)))
|
||||||
.attr('height', y.bandwidth())
|
.attr('height', y.bandwidth())
|
||||||
.transition()
|
|
||||||
.duration(1000)
|
|
||||||
.ease(d3.easeLinear)
|
|
||||||
.attr('width', d => d.percent >= 0 ? x(d.percent) : 0)
|
.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 () => {
|
return () => {
|
||||||
svg.remove()
|
svg.remove()
|
||||||
}
|
}
|
||||||
}, [width, height, data])
|
}, [width, height, data, colors, selected, onMouseOver, onMouseOut])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoaderPortal show={false} style={{width: givenWidth, height: givenHeight}}>
|
<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 { DateRangeWrapper, makeColumn, makeNumericRender, Table } from '@components/Table'
|
||||||
import LoaderPortal from '@components/LoaderPortal'
|
import LoaderPortal from '@components/LoaderPortal'
|
||||||
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
import { arrayOrDefault, wrapPrivateComponent } from '@utils'
|
||||||
import D3HorizontalChart from '@components/d3/D3HorizontalChart'
|
import { D3HorizontalChart, HorizontalChartDataType } from '@components/d3/D3HorizontalChart'
|
||||||
import { useWell } from '@asb/context'
|
import { useWell } from '@asb/context'
|
||||||
import { invokeWebApiWrapperAsync } from '@components/factory'
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
||||||
import { SubsystemOperationTimeService } from '@api'
|
import { SubsystemOperationTimeService } from '@api'
|
||||||
@ -49,22 +49,50 @@ const tableColumns = [
|
|||||||
<div style={{ backgroundColor: color, padding: '5px 0' }} />
|
<div style={{ backgroundColor: color, padding: '5px 0' }} />
|
||||||
) }),
|
) }),
|
||||||
makeColumn('Подсистема', 'subsystemName'),
|
makeColumn('Подсистема', 'subsystemName'),
|
||||||
makeColumn('% использования', 'kUsage', { render: val => (+val * 100).toFixed(2) }),
|
makeColumn('% использования', 'kUsage', { width: 200, render: val => makeNumericRender(2)(+val * 100) }),
|
||||||
makeColumn('Проходка, м', 'sumDepthInterval', {render: makeNumericRender(2)}),
|
makeColumn('Проходка, м', 'sumDepthInterval', { width: 200, render: makeNumericRender(2) }),
|
||||||
makeColumn('Время работы, ч', 'usedTimeHours', {render: makeNumericRender(2)}),
|
makeColumn('Время работы, ч', 'usedTimeHours', { width: 200, render: makeNumericRender(2) }),
|
||||||
makeColumn('Кол-во запусков', 'operationCount'),
|
makeColumn('Кол-во запусков', 'operationCount', { width: 200, render: makeNumericRender(0) }),
|
||||||
]
|
]
|
||||||
|
|
||||||
const OperationTime = memo(() => {
|
const OperationTime = memo(() => {
|
||||||
const [showLoader, setShowLoader] = useState(false)
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
const [data, setData] = useState<DataType[]>([])
|
const [data, setData] = useState<DataType[]>([])
|
||||||
const [selectedData, setSelectedData] = 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 [childrenData, setChildrenData] = useState<ReactNode[]>([])
|
||||||
const [well] = useWell()
|
const [well] = useWell()
|
||||||
|
|
||||||
const errorNotifyText = `Не удалось загрузить данные`
|
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(() => {
|
useEffect(() => {
|
||||||
invokeWebApiWrapperAsync(
|
invokeWebApiWrapperAsync(
|
||||||
async () => {
|
async () => {
|
||||||
@ -73,8 +101,8 @@ const OperationTime = memo(() => {
|
|||||||
const responseData:DataType[] = arrayOrDefault(await SubsystemOperationTimeService.getStat(
|
const responseData:DataType[] = arrayOrDefault(await SubsystemOperationTimeService.getStat(
|
||||||
well.id,
|
well.id,
|
||||||
undefined,
|
undefined,
|
||||||
dateRange[1] ? dateRange[0]?.toISOString() : undefined,
|
dateRange && dateRange[1] ? dateRange[0]?.toISOString() : undefined,
|
||||||
dateRange[1]?.toISOString(),
|
dateRange && dateRange[1] ? dateRange[1].toISOString() : undefined,
|
||||||
))
|
))
|
||||||
setData(responseData)
|
setData(responseData)
|
||||||
setSelectedData(responseData)
|
setSelectedData(responseData)
|
||||||
@ -124,25 +152,29 @@ const OperationTime = memo(() => {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={6}>
|
<Col span={6}>
|
||||||
<DateRangeWrapper
|
<DateRangeWrapper
|
||||||
|
allowClear
|
||||||
|
allowEmpty={[true, true]}
|
||||||
onCalendarChange={(dateRange: any) => setDateRange(dateRange)}
|
onCalendarChange={(dateRange: any) => setDateRange(dateRange)}
|
||||||
value={[dateRange[0], dateRange[1]]}
|
value={[dateRange && dateRange[0], dateRange && dateRange[1]]}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<div style={{width: '100%', height: '50vh'}}>
|
<D3HorizontalChart
|
||||||
<D3HorizontalChart
|
data={selectedData.map(item => ({name: item.subsystemName, percent: item.kUsage * 100}))}
|
||||||
data={selectedData.map(item => ({name: item.subsystemName, percent: item.kUsage * 100}))}
|
colors={subsystemColors}
|
||||||
colors={subsystemColors}
|
selected={selected}
|
||||||
width={'100%'}
|
width={'100%'}
|
||||||
height={'50vh'}
|
height={'50vh'}
|
||||||
/>
|
onMouseOver={onMouseOver}
|
||||||
</div>
|
onMouseOut={onMouseOut}
|
||||||
|
/>
|
||||||
<Table
|
<Table
|
||||||
size={'small'}
|
size={'small'}
|
||||||
columns={tableColumns}
|
columns={tableColumns}
|
||||||
dataSource={selectedData.map((d, i) => ({...d, color: subsystemColors[i]}))}
|
dataSource={selectedData.map((d, i) => ({...d, color: subsystemColors[i]}))}
|
||||||
scroll={{ y: '25vh', x: true }}
|
scroll={{ y: '25vh', x: true }}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
|
onRow={onRow}
|
||||||
/>
|
/>
|
||||||
</LoaderPortal>
|
</LoaderPortal>
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user