Улучшено отображение РТК в подсказке мониторинга

This commit is contained in:
Александр Сироткин 2022-11-28 05:18:55 +05:00
parent 0aeef42811
commit 7acb7ce2b2
3 changed files with 43 additions and 14 deletions

View File

@ -11,7 +11,7 @@ import { ChartGroup, ChartSizes } from './D3MonitoringCharts'
import '@styles/d3.less' import '@styles/d3.less'
type D3GroupRenderFunction<DataType extends BaseDataType> = (group: ChartGroup<DataType>, data: DataType[]) => ReactNode type D3GroupRenderFunction<DataType extends BaseDataType> = (group: ChartGroup<DataType>, data: DataType[], flowData: DataType[] | undefined) => ReactNode
export type D3HorizontalCursorSettings<DataType extends BaseDataType> = { export type D3HorizontalCursorSettings<DataType extends BaseDataType> = {
width?: number width?: number
@ -27,6 +27,7 @@ export type D3HorizontalCursorSettings<DataType extends BaseDataType> = {
export type D3HorizontalCursorProps<DataType extends BaseDataType> = D3HorizontalCursorSettings<DataType> & { export type D3HorizontalCursorProps<DataType extends BaseDataType> = D3HorizontalCursorSettings<DataType> & {
groups: ChartGroup<DataType>[] groups: ChartGroup<DataType>[]
data: DataType[] data: DataType[]
flowData: DataType[] | undefined
sizes: ChartSizes sizes: ChartSizes
yAxis?: d3.ScaleTime<number, number> yAxis?: d3.ScaleTime<number, number>
spaceBetweenGroups?: number spaceBetweenGroups?: number
@ -38,7 +39,7 @@ const defaultLineStyle: SVGProps<SVGLineElement> = {
const offsetY = 5 const offsetY = 5
const makeDefaultRender = <DataType extends BaseDataType>(): D3GroupRenderFunction<DataType> => (group, data) => ( const makeDefaultRender = <DataType extends BaseDataType>(): D3GroupRenderFunction<DataType> => (group, data, flowData) => (
<> <>
{data.length > 0 ? group.charts.map((chart) => { {data.length > 0 ? group.charts.map((chart) => {
const xFormat = (d: number | Date) => chart.xAxis.format?.(d) ?? `${(+d).toFixed(2)} ${chart.xAxis.unit ?? ''}` const xFormat = (d: number | Date) => chart.xAxis.format?.(d) ?? `${(+d).toFixed(2)} ${chart.xAxis.unit ?? ''}`
@ -74,6 +75,7 @@ const _D3HorizontalCursor = <DataType extends BaseDataType>({
lineStyle: _lineStyle, lineStyle: _lineStyle,
data, data,
flowData,
groups, groups,
sizes, sizes,
yAxis, yAxis,
@ -167,7 +169,7 @@ const _D3HorizontalCursor = <DataType extends BaseDataType>({
return (date >= currentDate - limitInS) && (date <= currentDate + limitInS) return (date >= currentDate - limitInS) && (date <= currentDate + limitInS)
}) })
const bodies = groups.map((group) => render(group, chartData)) const bodies = groups.map((group) => render(group, chartData, flowData))
setTooltipBodies(bodies) setTooltipBodies(bodies)
}, [groups, data, yAxis, lineY, fixed, mouseState.visible]) }, [groups, data, yAxis, lineY, fixed, mouseState.visible])
@ -190,7 +192,7 @@ const _D3HorizontalCursor = <DataType extends BaseDataType>({
> >
<div className={'tooltip-wrapper'}> <div className={'tooltip-wrapper'}>
<div className={`adaptive-tooltip tooltip ${position} ${className}`} <div className={`adaptive-tooltip tooltip ${position} ${className}`}
style={{height: 'auto', bottom: `${position === 'bottom' ? '0' : ''}`}} style={{height: 'auto', bottom: `${position === 'bottom' ? '0' : ''}`}}
> >
<div className={'tooltip-content'}> <div className={'tooltip-content'}>
{tooltipBodies[i]} {tooltipBodies[i]}

View File

@ -250,7 +250,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
.range([0, sizes.chartsHeight]) .range([0, sizes.chartsHeight])
return yAxis return yAxis
}, [groups, data, yDomain, sizes.chartsHeight]) }, [groups, data, yDomain, sizes])
const chartDomains = useMemo(() => groups.map((group) => { const chartDomains = useMemo(() => groups.map((group) => {
const out: [string | number, ChartDomain][] = group.charts.map((chart) => { const out: [string | number, ChartDomain][] = group.charts.map((chart) => {
@ -575,6 +575,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
sizes={sizes} sizes={sizes}
spaceBetweenGroups={spaceBetweenGroups} spaceBetweenGroups={spaceBetweenGroups}
data={data} data={data}
flowData={flowData}
height={height} height={height}
/> />
</D3MouseZone> </D3MouseZone>

View File

@ -1,38 +1,64 @@
import { Fragment } from 'react' import { Fragment } from 'react'
import { getByAccessor } from '@components/d3'
import { Grid, GridItem } from '@components/Grid' import { Grid, GridItem } from '@components/Grid'
import { getChartIcon, makeDisplayValue } from '@utils' import { getChartIcon, makeDisplayValue } from '@utils'
import moment from 'moment'
const defaultFormater = makeDisplayValue({ def: '---', fixed: 2 }) const defaultFormater = makeDisplayValue({ def: '---', fixed: 2 })
const defaultValueRender = (v, unit) => ( const defaultValueRender = (v, unit) => (
<>{defaultFormater(v)} {unit ?? ''}</> <>{defaultFormater(v)} {unit ?? ''}</>
) )
export const cursorRender = (group, data) => { export const cursorRender = (group, data, flowData) => {
const d = data.length > 0 ? data[0] : {} const d = data.length > 0 ? data[0] : {}
if (group.charts.length <= 0) return <></> if (group.charts.length <= 0) return <></>
const firstChart = group.charts[0] const firstChart = group.charts[0]
const y = firstChart.y(d) const y = firstChart.y(d)
const yDate = moment(y)
const flow = flowData.filter((row) => yDate.isBetween(row.dateStart, row.dateEnd, 's', '[]'))
const yValue = firstChart.yAxis.format?.(y) ?? defaultValueRender(y, firstChart.yAxis.unit) const yValue = firstChart.yAxis.format?.(y) ?? defaultValueRender(y, firstChart.yAxis.unit)
const xFormat = (chart) => { const xFormat = (chart) => {
const v = chart.x(d) const v = chart.x(d)
return chart.xAxis.format?.(v) ?? defaultValueRender(v, chart.xAxis.unit) return chart.xAxis.format?.(v) ?? defaultValueRender(v, chart.xAxis.unit)
} }
let j = 0
return ( return (
<Grid> <>
<GridItem row={1} col={1} colSpan={4}>{yValue}</GridItem> <Grid>
{group.charts.map((chart, i) => { <GridItem row={1} col={1} colSpan={4} style={{ textAlign: 'center' }}>{yValue}</GridItem>
return ( {group.charts.filter((chart) => chart.type !== 'rect_area').map((chart, i) => (
<Fragment key={chart.key}> <Fragment key={chart.key}>
<GridItem row={i+2} col={1} style={{ padding: '4px 0' }}>{getChartIcon(chart)}</GridItem> <GridItem row={i+2} col={1} style={{ padding: '2px 0' }}>{getChartIcon(chart)}</GridItem>
<GridItem row={i+2} col={2}>{chart.shortLabel || chart.label}</GridItem> <GridItem row={i+2} col={2}>{chart.shortLabel || chart.label}</GridItem>
<GridItem row={i+2} col={3} style={{ paddingRight: 0, textAlign: 'end' }}>{xFormat(chart)}</GridItem> <GridItem row={i+2} col={3} style={{ paddingRight: 0, textAlign: 'end' }}>{xFormat(chart)}</GridItem>
</Fragment> </Fragment>
) ))}
})} </Grid>
</Grid> <Grid>
{group.charts.filter((chart) => chart.type === 'rect_area').map((chart, i) => {
const minX = getByAccessor(chart.minXAccessor)
const maxX = getByAccessor(chart.maxXAccessor)
const value = (row) => <span>{defaultFormater(minX(row))} - {defaultFormater(maxX(row))}</span>
return (
<Fragment key={chart.key}>
<GridItem row={i+2} col={1} style={{ padding: '2px 0' }}>{getChartIcon(chart)}</GridItem>
<GridItem row={i+2} col={2}>{chart.shortLabel || chart.label}</GridItem>
{flow.map((row) => (
<GridItem row={i+2+(j++)} col={3} style={{ paddingRight: 0, textAlign: 'end' }}>
{chart.xAxis.format?.(row) ?? value(row)}
</GridItem>
))}
<GridItem row={i+2} col={4} style={{ textAlign: 'end' }}>{chart.xAxis.unit}</GridItem>
</Fragment>
)
})}
</Grid>
</>
) )
} }