forked from ddrilling/asb_cloud_front
Улучшен вывод значений на экран на ННБ, Мониторинге и Архиве
This commit is contained in:
parent
600c752675
commit
c3b48d210c
@ -2,6 +2,8 @@ import { Button } from 'antd'
|
|||||||
import { memo, ReactNode, useMemo } from 'react'
|
import { memo, ReactNode, useMemo } from 'react'
|
||||||
import { CloseOutlined, SettingOutlined } from '@ant-design/icons'
|
import { CloseOutlined, SettingOutlined } from '@ant-design/icons'
|
||||||
|
|
||||||
|
import { makeDisplayValue } from '@utils'
|
||||||
|
|
||||||
import '@styles/widgets/base.less'
|
import '@styles/widgets/base.less'
|
||||||
|
|
||||||
export type WidgetSettings<T = any> = {
|
export type WidgetSettings<T = any> = {
|
||||||
@ -19,13 +21,7 @@ export type WidgetSettings<T = any> = {
|
|||||||
|
|
||||||
const emptyNumber = '----'
|
const emptyNumber = '----'
|
||||||
|
|
||||||
const defaultFormatter = (v: any) => {
|
const defaultFormatter = makeDisplayValue({ def: emptyNumber, fixed: 2 })
|
||||||
if (typeof v === 'undefined' || v === null || String(v) === 'NaN') return emptyNumber
|
|
||||||
if (Number.isNaN(+v)) return v
|
|
||||||
const f = parseFloat(v)
|
|
||||||
if (Number.isFinite(v)) return f.toFixed(2)
|
|
||||||
return `${f < 0 ? '-' : ''}\u221E`
|
|
||||||
}
|
|
||||||
|
|
||||||
export const defaultSettings: WidgetSettings = {
|
export const defaultSettings: WidgetSettings = {
|
||||||
unit: '----',
|
unit: '----',
|
||||||
|
@ -1,39 +1,34 @@
|
|||||||
import { BarChartOutlined, LineChartOutlined, DotChartOutlined, AreaChartOutlined, BorderOuterOutlined } from '@ant-design/icons'
|
|
||||||
import { Grid, GridItem } from '@components/Grid'
|
|
||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
|
import { Grid, GridItem } from '@components/Grid'
|
||||||
|
import { getChartIcon, makeDisplayValue } from '@utils'
|
||||||
|
|
||||||
|
const defaultFormater = makeDisplayValue({ def: '---', fixed: 2 })
|
||||||
|
const defaultValueRender = (v, unit) => (
|
||||||
|
<>{defaultFormater(v)} {unit ?? ''}</>
|
||||||
|
)
|
||||||
|
|
||||||
export const cursorRender = (group, data) => {
|
export const cursorRender = (group, data) => {
|
||||||
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 yValue = firstChart.yAxis.format?.(y) ?? `${(+y).toFixed(2)} ${firstChart.yAxis.unit ?? ''}`
|
const yValue = firstChart.yAxis.format?.(y) ?? defaultValueRender(y, chart.yAxis.unit)
|
||||||
const yFormat = (chart) => {
|
const xFormat = (chart) => {
|
||||||
const v = chart.x(d)
|
const v = chart.x(d)
|
||||||
return chart.xAxis.format?.(v) ?? `${(+v)?.toFixed(2)} ${chart.xAxis.unit ?? ''}`
|
return chart.xAxis.format?.(v) ?? defaultValueRender(v, chart.xAxis.unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid>
|
<Grid>
|
||||||
<GridItem row={1} col={1} colSpan={4}>{yValue}</GridItem>
|
<GridItem row={1} col={1} colSpan={4}>{yValue}</GridItem>
|
||||||
{group.charts.map((chart, i) => {
|
{group.charts.map((chart, i) => {
|
||||||
let Icon
|
|
||||||
switch (chart.type) {
|
|
||||||
case 'needle': Icon = BarChartOutlined; break
|
|
||||||
case 'line': Icon = LineChartOutlined; break
|
|
||||||
case 'point': Icon = DotChartOutlined; break
|
|
||||||
case 'area': Icon = AreaChartOutlined; break
|
|
||||||
case 'rect_area': Icon = BorderOuterOutlined; break
|
|
||||||
}
|
|
||||||
|
|
||||||
const d = data[0]
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment key={chart.key}>
|
<Fragment key={chart.key}>
|
||||||
<GridItem row={i+2} col={1} style={{ padding: '4px 0' }}><Icon style={{ color: chart.color }} /></GridItem>
|
<GridItem row={i+2} col={1} style={{ padding: '4px 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 }}>{yFormat(chart)}</GridItem>
|
<GridItem row={i+2} col={3} style={{ paddingRight: 0 }}>{xFormat(chart)}</GridItem>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
@ -38,7 +38,7 @@ const { Option } = Select
|
|||||||
const yAxis = {
|
const yAxis = {
|
||||||
type: 'time',
|
type: 'time',
|
||||||
accessor: (d) => new Date(d.date),
|
accessor: (d) => new Date(d.date),
|
||||||
format: (d) => formatDate(d),
|
format: (d) => formatDate(d, undefined, 'YYYY-MM-DD HH:mm:ss'),
|
||||||
}
|
}
|
||||||
|
|
||||||
const dash = [7, 3]
|
const dash = [7, 3]
|
||||||
@ -251,7 +251,7 @@ const TelemetryView = memo(() => {
|
|||||||
yDomain={domain}
|
yDomain={domain}
|
||||||
yTicks={{
|
yTicks={{
|
||||||
visible: true,
|
visible: true,
|
||||||
format: (d) => formatDate(d)
|
format: (d) => formatDate(d, 'YYYY-MM-DD')
|
||||||
}}
|
}}
|
||||||
plugins={{
|
plugins={{
|
||||||
menu: { enabled: false },
|
menu: { enabled: false },
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
import { BarChartOutlined, LineChartOutlined, DotChartOutlined, AreaChartOutlined, BorderOuterOutlined, } from '@ant-design/icons'
|
||||||
|
import { AntdIconProps } from '@ant-design/icons/lib/components/AntdIcon'
|
||||||
|
|
||||||
|
import { ChartDataset } from '@components/d3'
|
||||||
|
|
||||||
export const makePointsOptimizator = <DataType extends Record<string, unknown>>(isEquals: (a: DataType, b: DataType) => boolean) => (points: DataType[]) => {
|
export const makePointsOptimizator = <DataType extends Record<string, unknown>>(isEquals: (a: DataType, b: DataType) => boolean) => (points: DataType[]) => {
|
||||||
if (!Array.isArray(points) || points.length < 3) return points
|
if (!Array.isArray(points) || points.length < 3) return points
|
||||||
|
|
||||||
@ -17,3 +22,16 @@ export const getDistance = (x1: number, y1: number, x2: number, y2: number, type
|
|||||||
|
|
||||||
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2))
|
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getChartIcon = <DataType,>(chart: ChartDataset<DataType>, options: Omit<AntdIconProps, 'ref'>) => {
|
||||||
|
let Icon
|
||||||
|
switch (chart.type) {
|
||||||
|
case 'needle': Icon = BarChartOutlined; break
|
||||||
|
case 'line': Icon = LineChartOutlined; break
|
||||||
|
case 'point': Icon = DotChartOutlined; break
|
||||||
|
case 'area': Icon = AreaChartOutlined; break
|
||||||
|
case 'rect_area': Icon = BorderOuterOutlined; break
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Icon { ...options } style={{ color: chart.color, ...options?.style }} />
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
export const getPrecision = (number: number, def: string = '-', fixed: number = 2): string => Number.isFinite(number) ? number.toFixed(fixed) : def
|
export const getPrecision = (number: number, def: string = '-', fixed: number = 2): string => Number.isFinite(number) ? number.toFixed(fixed) : def
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -7,7 +9,7 @@ export const getPrecision = (number: number, def: string = '-', fixed: number =
|
|||||||
* @param max Максимальное значение
|
* @param max Максимальное значение
|
||||||
* @returns Функция, ограничивающая значение в диапазоне [`min`; `max`]
|
* @returns Функция, ограничивающая значение в диапазоне [`min`; `max`]
|
||||||
*/
|
*/
|
||||||
export const limitValue = <T>(min: T, max: T) => (value: T) => {
|
export const limitValue = <T,>(min: T, max: T) => (value: T) => {
|
||||||
if (value > max) return max
|
if (value > max) return max
|
||||||
if (value < min) return min
|
if (value < min) return min
|
||||||
return value
|
return value
|
||||||
@ -22,3 +24,25 @@ export const limitValue = <T>(min: T, max: T) => (value: T) => {
|
|||||||
* @returns Массив чисел в диапазоне от `start` до `end`
|
* @returns Массив чисел в диапазоне от `start` до `end`
|
||||||
*/
|
*/
|
||||||
export const range = (end: number, start: number = 0) => Array.from({ length: end - start }, (_, i) => start + i)
|
export const range = (end: number, start: number = 0) => Array.from({ length: end - start }, (_, i) => start + i)
|
||||||
|
|
||||||
|
export type DisplayValueOptions = {
|
||||||
|
def?: ReactNode
|
||||||
|
inf?: ReactNode | ((v: number) => ReactNode)
|
||||||
|
fixed?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export const makeDisplayValue = ({
|
||||||
|
def = '----',
|
||||||
|
inf = (v) => `${v < 0 ? '-' : ''}\u221E`,
|
||||||
|
fixed = 2
|
||||||
|
}: DisplayValueOptions) => (v: unknown): ReactNode => {
|
||||||
|
if (typeof v === 'undefined' || v === null || String(v) === 'NaN') return def
|
||||||
|
let f = Number(v)
|
||||||
|
if (typeof v === 'string') {
|
||||||
|
if (Number.isNaN(+v)) return v
|
||||||
|
f = parseFloat(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number.isFinite(f)) return f.toFixed(fixed)
|
||||||
|
return typeof inf === 'function' ? inf(f) : inf
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user