На странице Наработка добавлен сброс даты и выделение данных при наведении

This commit is contained in:
ts_salikhov 2022-10-11 01:27:27 +04:00
parent bbf15c1f35
commit 1b23ee3437
2 changed files with 30 additions and 26 deletions

View File

@ -20,9 +20,7 @@ export type D3HorizontalChartProps = {
height?: Property.Height
data: PercentChartDataType[]
offset?: Partial<ChartOffset>
selected?: string | null
onMouseOver?: (e: MouseEvent, d: PercentChartDataType) => void
onMouseOut?: (e: MouseEvent, d: PercentChartDataType) => void
afterDraw?: (d: d3.Selection<SVGGElement, unknown, null, undefined>) => void
}
const defaultOffset = { top: 50, right: 100, bottom: 50, left: 100 }
@ -32,9 +30,7 @@ export const D3HorizontalPercentChart = memo<D3HorizontalChartProps>(({
height: givenHeight = '100%',
offset: givenOffset,
data,
selected = null,
onMouseOver = () => {},
onMouseOut= () => {},
afterDraw,
}) => {
const offset = usePartialProps<ChartOffset>(givenOffset, defaultOffset)
@ -51,8 +47,8 @@ export const D3HorizontalPercentChart = memo<D3HorizontalChartProps>(({
useEffect(() => { /// Отрисовываем оси X сверху и снизу
if (width < 100 || height < 100 || !root) return
const xAxisTop = d3.axisTop(xScale).tickFormat((d) => `${d}%`).tickValues([0, 25, 50, 75, 100]).tickSize(-inlineHeight)
const xAxisBottom = d3.axisBottom(xScale).tickFormat((d) => `${d}%`).tickValues([0, 25, 50, 75, 100])
const xAxisTop = d3.axisTop(xScale).tickFormat((d) => `${d}%`).ticks(4).tickSize(-inlineHeight)
const xAxisBottom = d3.axisBottom(xScale).tickFormat((d) => `${d}%`).ticks(4)
root.selectChild<SVGGElement>('.axis.x.bottom').call(xAxisBottom)
root.selectChild<SVGGElement>('.axis.x.top').call(xAxisTop)
@ -77,15 +73,13 @@ export const D3HorizontalPercentChart = memo<D3HorizontalChartProps>(({
.selectAll<SVGRectElement, PercentChartDataType>('rect')
.attr('fill', (d) => d.color || 'black')
.attr('y', (d) => yScale(d.name) ?? null)
.attr('stroke', d => selected && d.name === selected ? 'black' : '')
.attr('stroke-width', d => selected && d.name === selected ? '2' : '0')
.attr('height', yScale.bandwidth())
.on('mouseover', onMouseOver)
.on('mouseout', onMouseOut)
.transition(delay)
.attr('width', (d) => d.percent > 0 ? xScale(d.percent) : 0)
}, [data, width, height, root, yScale, xScale, selected])
afterDraw?.(root)
}, [data, width, height, root, yScale, xScale, afterDraw])
return (
<LoaderPortal show={false} style={{ width: givenWidth, height: givenHeight }}>

View File

@ -45,7 +45,7 @@ export const OperationTime = memo(() => {
const [showLoader, setShowLoader] = useState(false)
const [data, setData] = useState([])
const [selected, setSelected] = useState([])
const [selectedOnHover, setSelectedOnHover] = useState(null)
const [selectedSubsystem, setSelectedSubsystem] = useState(null)
const [dateRange, setDateRange] = useState([])
const [well] = useWell()
@ -63,36 +63,46 @@ export const OperationTime = memo(() => {
const onRow = useCallback((item) => {
const out = {
onMouseEnter: () => {
setSelectedOnHover(item.subsystemName)
setSelectedSubsystem(item.subsystemName)
},
onMouseLeave: () => {
setSelectedOnHover(null)
setSelectedSubsystem(null)
},
}
if (item.subsystemName === selectedOnHover) {
out.style = { background: '#FAFAFA', fontSize: '16px', fontWeight: '600' }
if (item.subsystemName === selectedSubsystem) {
out.style = { background: '#FAFAFA', fontSize: '16px', fontWeight: '600', transition: 'all 0.2s ease-out' }
}
return out
}, [selectedOnHover])
}, [selectedSubsystem])
const onMouseOver = useCallback(function (e, d) {
setSelectedOnHover(d.name)
const onMouseOver = useCallback((_, d) => {
setSelectedSubsystem(d.name)
}, [])
const onMouseOut = useCallback(function (e, d) {
setSelectedOnHover(null)
const onMouseOut = useCallback(() => {
setSelectedSubsystem(null)
}, [])
const afterDraw = useCallback(function(selection) {
selection.selectAll('rect')
.on('mouseover', onMouseOver)
.on('mouseout', onMouseOut)
.transition(200)
.style('stroke-width', d => d.name === selectedSubsystem ? '2' : '0')
.style('stroke', d => d.name === selectedSubsystem ? 'black' : '')
.style('stroke-opacity', '0.4')
}, [onMouseOver, onMouseOut, selectedSubsystem])
useEffect(() => {
invokeWebApiWrapperAsync(
async () => {
if (!well.id) return
// Ограничение задаётся только если выбраны обе даты
const startDate = dateRange && dateRange[1] ? dateRange[0]?.toISOString() : undefined
const endDate = dateRange && dateRange[1] ? dateRange[1]?.toISOString() : undefined
const startDate = dateRange?.[1] ? dateRange[0]?.toISOString() : undefined
const endDate = dateRange?.[1] ? dateRange[1]?.toISOString() : undefined
const data = await SubsystemOperationTimeService.getStat(well.id, undefined, startDate, endDate)
// Выбираем цвета для подсистем (если цветов не хватает начинаем сначала)
@ -132,11 +142,11 @@ export const OperationTime = memo(() => {
<D3HorizontalPercentChart
data={chartData}
colors={subsystemColors}
selected={selectedOnHover}
width={'100%'}
height={'50vh'}
onMouseOver={onMouseOver}
onMouseOut={onMouseOut}
afterDraw={afterDraw}
/>
<Table
bordered