forked from ddrilling/asb_cloud_front
Добавлен tooltip для графика операций время-день
This commit is contained in:
parent
5511c06410
commit
fc6646eb80
@ -8,7 +8,7 @@ import '@styles/detected_operations.less'
|
||||
|
||||
const displayNumber = makeDisplayValue({ fixed: 2 })
|
||||
|
||||
const makeTooltipRender = (category) => ([{ data: [data] }]) => (
|
||||
export const makeTooltipRender = (category) => ([{ data: [data] }]) => (
|
||||
<div className={'detected-operations-tooltip'}>
|
||||
<span className={'tooltip-label'}>{data.operationCategory?.name}</span>
|
||||
<span className={'tooltip-label'}>{formatDate(data.dateStart, undefined, 'DD.MM.YYYY')}</span>
|
||||
@ -21,12 +21,12 @@ const makeTooltipRender = (category) => ([{ data: [data] }]) => (
|
||||
<GridItem row={2} col={3}>{displayNumber(data.depthEnd)} м</GridItem>
|
||||
</Grid>
|
||||
<Grid style={{ marginTop: 0 }}>
|
||||
<GridItem row={1} col={1}>{category?.name ?? 'Ключ'}:</GridItem>
|
||||
<GridItem row={1} col={1}>{category?.keyValueName ?? 'Ключ'}:</GridItem>
|
||||
<GridItem row={1} col={2}>{displayNumber(data.value)}</GridItem>
|
||||
<GridItem row={1} col={3}>{category?.unit ?? '----'}</GridItem>
|
||||
<GridItem row={1} col={3}>{category?.keyValueUnits ?? '----'}</GridItem>
|
||||
<GridItem row={2} col={1}>Цель:</GridItem>
|
||||
<GridItem row={2} col={2}>{displayNumber(data.operationValue?.targetValue)}</GridItem>
|
||||
<GridItem row={2} col={3}>{category?.unit ?? '----'}</GridItem>
|
||||
<GridItem row={2} col={3}>{category?.keyValueUnits ?? '----'}</GridItem>
|
||||
</Grid>
|
||||
</div>
|
||||
)
|
||||
|
@ -70,7 +70,11 @@ const Operations = memo(() => {
|
||||
invokeWebApiWrapperAsync(
|
||||
async () => {
|
||||
const categories = arrayOrDefault(await DetectedOperationService.getCategories())
|
||||
setCategories(categories.map(({ id, name }) => ({ value: id, label: name })))
|
||||
setCategories(categories.map((category) => ({
|
||||
...category,
|
||||
value: category.id,
|
||||
label: category.name,
|
||||
})))
|
||||
},
|
||||
setIsLoading,
|
||||
'Не удалось загрзуить категории операций'
|
||||
|
@ -11,8 +11,13 @@ import { DetectedOperationService } from '@api'
|
||||
import { unique } from '@utils/filters'
|
||||
import { formatDate } from '@utils'
|
||||
|
||||
import { makeTooltipRender } from '@pages/Telemetry/Operations/OperationsChart'
|
||||
import { makeGetColor } from '.'
|
||||
|
||||
import '@styles/d3.less'
|
||||
import '@styles/tvd.less'
|
||||
import '@styles/detected_operations.less'
|
||||
|
||||
const defaultOffset = { left: 40, right: 20, top: 20, bottom: 20 }
|
||||
const zeroDate = moment('2000-01-01 00:00:00')
|
||||
|
||||
@ -42,10 +47,13 @@ export const TLChart = memo(({
|
||||
backgroundColor = '#0000',
|
||||
barHeight = 15,
|
||||
offset = defaultOffset,
|
||||
tooltipSize = { width: 200, height: 220 },
|
||||
}) => {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [svgRef, setSvgRef] = useState()
|
||||
const [data, setData] = useState()
|
||||
const [selected, setSelected] = useState()
|
||||
const [tooltipPos, setTooltipPos] = useState({ x: 0, y: 0 })
|
||||
|
||||
const getColor = useMemo(() => makeGetColor(data?.map((row) => row.idCategory).filter(unique)), [data])
|
||||
|
||||
@ -124,22 +132,54 @@ export const TLChart = memo(({
|
||||
.attr('width', (d) => xAxis(d.endTime) - xAxis(d.startTime))
|
||||
.attr('height', barHeight)
|
||||
.attr('fill', (d) => getColor(d.idCategory))
|
||||
.on('mouseover', (e, data) => {
|
||||
d3.select(svgRef).select('.chart-area')
|
||||
.selectAll('rect')
|
||||
.filter((d) => d.idCategory === data.idCategory)
|
||||
.attr('stroke-width', '2px')
|
||||
const rect = e.target.getBoundingClientRect()
|
||||
setTooltipPos({ x: rect.x, y: rect.y })
|
||||
setSelected(data)
|
||||
})
|
||||
.on('mouseout', (e, data) => {
|
||||
d3.select(svgRef).select('.chart-area')
|
||||
.selectAll('rect')
|
||||
.filter((d) => d.idCategory === data.idCategory)
|
||||
.attr('stroke-width', '0')
|
||||
setSelected(null)
|
||||
})
|
||||
}, [svgRef, xAxis, yAxis, data, getColor])
|
||||
|
||||
const tooltipStyle = useMemo(() => {
|
||||
return {
|
||||
...tooltipSize,
|
||||
left: tooltipPos.x - tooltipSize.width - 8,
|
||||
top: tooltipPos.y - tooltipSize.height / 2 + barHeight / 2,
|
||||
}
|
||||
}, [tooltipPos, tooltipSize, barHeight])
|
||||
|
||||
return (
|
||||
<div className={'tvd-right'} ref={rootRef}>
|
||||
<LoaderPortal show={isLoading} style={{ width: '100%', flexGrow: 1 }}>
|
||||
<LoaderPortal show={isLoading} className={'asb-d3-chart'}>
|
||||
{selected && (
|
||||
<div className={'tl-op-tooltip'} style={tooltipStyle}>
|
||||
<div className={'tooltip right'}>
|
||||
{makeTooltipRender(selected.operationCategory)([{ data: [selected] }])}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{data ? (
|
||||
<svg ref={setSvgRef} width={'100%'} height={'100%'}>
|
||||
<svg className={'tl-op-chart'} ref={setSvgRef} width={'100%'} height={'100%'}>
|
||||
<g className={'axis x'} transform={`translate(${offset.left}, ${offset.top})`} />
|
||||
<g className={'axis y'} transform={`translate(${offset.left}, ${offset.top + barHeight})`} />
|
||||
<g className={'chart-area'} transform={`translate(${offset.left}, ${offset.top + barHeight})`} stroke={'none'} />
|
||||
<g className={'chart-area'} transform={`translate(${offset.left}, ${offset.top + barHeight})`} stroke={'red'} strokeWidth={'0'} />
|
||||
<rect
|
||||
x={offset.left}
|
||||
y={offset.top}
|
||||
width={Math.max(width - offset.left - offset.right, 0)}
|
||||
height={Math.max(height - offset.top - offset.bottom, 0)}
|
||||
fill={backgroundColor}
|
||||
pointerEvents={'none'}
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
|
||||
&.bottom {
|
||||
margin-top: 0;
|
||||
margin-bottom: @arrow-size;
|
||||
|
||||
&::after {
|
||||
border-top-color: @bg-color;
|
||||
@ -50,6 +50,24 @@
|
||||
margin-left: -@arrow-size;
|
||||
}
|
||||
}
|
||||
|
||||
&.left {
|
||||
margin-left: @arrow-size;
|
||||
&::after {
|
||||
border-right-color: @bg-color;
|
||||
top: 50%;
|
||||
right: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.right {
|
||||
margin-right: @arrow-size;
|
||||
&::after {
|
||||
border-left-color: @bg-color;
|
||||
top: 50%;
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
& .tooltip-content {
|
||||
overflow: hidden;
|
||||
|
@ -86,6 +86,17 @@
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tl-op-tooltip {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tl-op-chart {
|
||||
& .chart-area > rect {
|
||||
transition: stroke-width .25s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
.tl-pie {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
Loading…
Reference in New Issue
Block a user