Косметические улучшения кода

This commit is contained in:
goodmice 2022-08-15 12:49:11 +05:00
parent 8ade639e0e
commit 1de4e8d909
2 changed files with 34 additions and 13 deletions

View File

@ -1,9 +1,9 @@
import { memo, useEffect, useMemo, useState } from 'react'
import { CSSProperties, memo, useEffect, useMemo, useState } from 'react'
import * as d3 from 'd3'
import { Grid, GridItem } from '@components/Grid'
import { formatDate, makeDisplayValue } from '@utils'
import { TelemetryDataSaubDto } from '@api'
import { formatDate } from '@utils'
type LimitChartData = {
id: number
@ -77,6 +77,8 @@ export type D3MonitoringLimitChartProps<DataType> = {
const tooltipWidth = 270
const tooltipHeight = 120
const displayValue = makeDisplayValue()
const _D3MonitoringLimitChart = <DataType extends TelemetryDataSaubDto>({
yAxis,
data: chartData,
@ -85,7 +87,7 @@ const _D3MonitoringLimitChart = <DataType extends TelemetryDataSaubDto>({
left,
top,
regulators,
zoneWidth = 0
zoneWidth = 0,
}: D3MonitoringLimitChartProps<DataType>) => {
const [ref, setRef] = useState<SVGGElement | null>(null)
const [selected, setSelected] = useState<LimitChartData & { x: number, y: number, visible: boolean }>()
@ -108,22 +110,37 @@ const _D3MonitoringLimitChart = <DataType extends TelemetryDataSaubDto>({
const y = yAxis(d.dateStart) - tooltipHeight
setSelected({ ...d, y, x: -tooltipWidth - 10, visible: true })
})
.on('mouseout', (_, d) => setSelected((pre) => pre ? ({ ...pre, visible: false }) : undefined))
.on('mouseout', () => setSelected((pre) => pre ? ({ ...pre, visible: false }) : undefined))
}, [yAxis, data, ref, width])
const zoneY1 = useMemo(() => yAxis && selected ? yAxis(selected.dateStart) : 0, [yAxis, selected])
const zoneY2 = useMemo(() => yAxis && selected ? yAxis(selected.dateEnd) : 0, [yAxis, selected])
const tooltipStyle = useMemo(() => ({ transition: 'opacity .1s ease-in-out', opacity: selected?.visible ? 1 : 0 }), [selected])
const opacityStyle: CSSProperties = useMemo(() => ({
transition: 'opacity .1s ease-in-out',
opacity: selected?.visible ? 1 : 0,
}), [selected])
const tooltipStyle: CSSProperties = useMemo(() => ({
...opacityStyle,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}), [opacityStyle])
return (
<g transform={`translate(${left}, ${top})`} stroke={'#333'} strokeWidth={1} fill={'none'}>
<g ref={setRef} >
<g className={'bars'} strokeWidth={0} />
{selected && (
<g strokeDasharray={'6, 3, 3, 3'} style={tooltipStyle} stroke={regulators[selected.id].color}>
<line x1={-zoneWidth} y1={zoneY1} y2={zoneY1} />
<line x1={-zoneWidth} y1={zoneY2} y2={zoneY2} />
<g
style={opacityStyle}
pointerEvents={'none'}
strokeDasharray={'6, 3, 3, 3'}
stroke={regulators[selected.id].color}
>
<line x1={-zoneWidth} x2={0} y1={zoneY1} y2={zoneY1} />
<line x1={-zoneWidth} x2={0} y1={zoneY2} y2={zoneY2} />
<rect
opacity={0.1}
stroke={'none'}
@ -139,17 +156,17 @@ const _D3MonitoringLimitChart = <DataType extends TelemetryDataSaubDto>({
<rect x={0} y={0} width={width} height={height} />
{selected && (
<foreignObject width={tooltipWidth} height={tooltipHeight} x={selected.x} y={selected.y} pointerEvents={'none'}>
<div className={'tooltip bottom'} style={{ ...tooltipStyle, display: 'flex', flexDirection: 'column', alignItems: 'center'}}>
<div className={'tooltip bottom'} style={tooltipStyle}>
<span>Ограничивающий параметр</span>
<span>{regulators[selected.id].label}</span>
<Grid style={{ margin: 0 }}>
<Grid style={{ margin: 0, padding: 0 }}>
<GridItem row={1} col={1}>Начало:</GridItem>
<GridItem row={1} col={2}>{formatDate(selected.dateStart)}</GridItem>
<GridItem row={1} col={3}>{selected.depthStart?.toFixed(2) ?? '---'}</GridItem>
<GridItem row={1} col={3}>{displayValue(selected.depthStart)}</GridItem>
<GridItem row={1} col={4}>м.</GridItem>
<GridItem row={2} col={1}>Конец:</GridItem>
<GridItem row={2} col={2}>{formatDate(selected.dateEnd)}</GridItem>
<GridItem row={2} col={3}>{selected.depthEnd?.toFixed(2) ?? '---'}</GridItem>
<GridItem row={2} col={3}>{displayValue(selected.depthEnd)}</GridItem>
<GridItem row={2} col={4}>м.</GridItem>
</Grid>
</div>

View File

@ -35,7 +35,11 @@ export const makeDisplayValue = ({
def = '----',
inf = (v) => `${v < 0 ? '-' : ''}\u221E`,
fixed = 2
}: DisplayValueOptions) => (v: unknown): ReactNode => {
}: DisplayValueOptions = {
def: '----',
inf: (v) => `${v < 0 ? '-' : ''}\u221E`,
fixed: 2
}) => (v: unknown): ReactNode => {
if (typeof v === 'undefined' || v === null || String(v) === 'NaN') return def
let f = Number(v)
if (typeof v === 'string') {