Добавлено сохранение и редактирование колонки

This commit is contained in:
Александр Сироткин 2022-08-15 06:57:20 +05:00
parent 0a18b79416
commit cc37bccacf
4 changed files with 96 additions and 35 deletions

View File

@ -26,9 +26,9 @@ import D3MouseZone from '@components/d3/D3MouseZone'
import { getByAccessor, getChartClass, getGroupClass, getTicks } from '@components/d3/functions' import { getByAccessor, getChartClass, getGroupClass, getTicks } from '@components/d3/functions'
import { renderArea, renderLine, renderNeedle, renderPoint, renderRectArea } from '@components/d3/renders' import { renderArea, renderLine, renderNeedle, renderPoint, renderRectArea } from '@components/d3/renders'
import D3MonitoringGroupsEditor from './D3MonitoringGroupsEditor' import D3MonitoringEditor from './D3MonitoringEditor'
import { D3HorizontalCursor, D3HorizontalCursorSettings } from './D3HorizontalCursor' import { D3HorizontalCursor, D3HorizontalCursorSettings } from './D3HorizontalCursor'
import D3MonitoringLimitChart from './D3MonitoringLimitChart' import D3MonitoringLimitChart, { TelemetryRegulators } from './D3MonitoringLimitChart'
const roundTo = (v: number, to: number = 50) => { const roundTo = (v: number, to: number = 50) => {
if (v === 0) return v if (v === 0) return v
@ -77,6 +77,15 @@ const defaultOffsets: ChartOffset = {
right: 20, right: 20,
} }
const defaultRegulators: TelemetryRegulators = {
1: { color: '#007070', label: 'Расход' },
2: { color: '#59B359', label: 'Скорость блока' },
3: { color: '#FF0000', label: 'Давление' },
4: { color: '#0000CC', label: 'Осевая нагрузка' },
5: { color: '#00B3B3', label: 'Вес на крюке' },
6: { color: '#990099', label: 'Момент на роторе' },
}
const getDefaultYAxisConfig = <DataType,>(): ChartAxis<DataType> => ({ const getDefaultYAxisConfig = <DataType,>(): ChartAxis<DataType> => ({
type: 'time', type: 'time',
accessor: (d: any) => new Date(d.date) accessor: (d: any) => new Date(d.date)
@ -192,6 +201,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
const [chartAreaRef, setChartAreaRef] = useState<SVGGElement | null>(null) const [chartAreaRef, setChartAreaRef] = useState<SVGGElement | null>(null)
const [axesAreaRef, setAxesAreaRef] = useState<SVGGElement | null>(null) const [axesAreaRef, setAxesAreaRef] = useState<SVGGElement | null>(null)
const [settingsVisible, setSettingsVisible] = useState<boolean>(false) const [settingsVisible, setSettingsVisible] = useState<boolean>(false)
const [regulators, setRegulators] = useState<TelemetryRegulators>(defaultRegulators)
const offset = usePartialProps(_offset, defaultOffsets) const offset = usePartialProps(_offset, defaultOffsets)
const yTicks = usePartialProps<Required<ChartTick<DataType>>>(_yTicks, getDefaultYTicks) const yTicks = usePartialProps<Required<ChartTick<DataType>>>(_yTicks, getDefaultYTicks)
@ -272,23 +282,28 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
} }
), [chartArea]) ), [chartArea])
const onGroupsChange = useCallback((sets: ExtendedChartDataset<DataType>[][]) => { const onGroupsChange = useCallback((settings: ExtendedChartDataset<DataType>[][], regulators: TelemetryRegulators) => {
if (chartName) { if (chartName) {
invokeWebApiWrapperAsync( invokeWebApiWrapperAsync(
async () => { async () => {
await UserSettingsService.update(chartName, sets) await UserSettingsService.update(chartName, {
settings,
regulators,
})
}, },
undefined, undefined,
'Не удалось сохранить параметры графиков' 'Не удалось сохранить параметры графиков'
) )
} }
setDatasets(sets) setDatasets(settings)
setRegulators(regulators)
setSettingsVisible(false) setSettingsVisible(false)
}, [chartName]) }, [chartName])
const onGroupsReset = useCallback(() => { const onGroupsReset = useCallback(() => {
setSettingsVisible(false) setSettingsVisible(false)
setDatasets(datasetGroups) setDatasets(datasetGroups)
setRegulators(defaultRegulators)
if (chartName) { if (chartName) {
invokeWebApiWrapperAsync( invokeWebApiWrapperAsync(
async () => await UserSettingsService.delete(chartName), async () => await UserSettingsService.delete(chartName),
@ -306,13 +321,19 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
let sets = chartName ? await UserSettingsService.get(chartName) : null let sets = chartName ? await UserSettingsService.get(chartName) : null
if (typeof sets === 'string') if (typeof sets === 'string')
sets = JSON.parse(sets) sets = JSON.parse(sets)
if (Array.isArray(sets)) { const { settings, regulators } = sets
setDatasets(sets) if (regulators)
setRegulators(regulators)
if (Array.isArray(settings)) {
setDatasets(settings)
} else if (Array.isArray(datasetGroups)) { } else if (Array.isArray(datasetGroups)) {
setDatasets(datasetGroups) setDatasets(datasetGroups)
if (chartName) { if (chartName) {
invokeWebApiWrapperAsync( invokeWebApiWrapperAsync(
async () => await UserSettingsService.insert(chartName, datasetGroups), async () => await UserSettingsService.insert(chartName, {
settings: datasetGroups,
regulators: defaultRegulators,
}),
undefined, undefined,
'Не удалось сохранить настройки графиков' 'Не удалось сохранить настройки графиков'
) )
@ -574,6 +595,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
})} })}
</g> </g>
<D3MonitoringLimitChart <D3MonitoringLimitChart
regulators={regulators}
data={data} data={data}
yAxis={yAxis} yAxis={yAxis}
width={20} width={20}
@ -597,8 +619,9 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</div> </div>
)} )}
<D3MonitoringGroupsEditor <D3MonitoringEditor
groups={datasets} groups={datasets}
regulators={regulators}
visible={settingsVisible} visible={settingsVisible}
onChange={onGroupsChange} onChange={onGroupsChange}
onCancel={() => setSettingsVisible(false)} onCancel={() => setSettingsVisible(false)}

View File

@ -7,12 +7,15 @@ import { notify } from '@components/factory'
import { getChartIcon } from '@utils' import { getChartIcon } from '@utils'
import { ExtendedChartDataset } from './D3MonitoringCharts' import { ExtendedChartDataset } from './D3MonitoringCharts'
import { TelemetryRegulators } from './D3MonitoringLimitChart'
import D3MonitoringChartEditor from './D3MonitoringChartEditor' import D3MonitoringChartEditor from './D3MonitoringChartEditor'
import D3MonitoringLimitEditor from './D3MonitoringLimitEditor'
export type D3MonitoringGroupsEditorProps<DataType> = { export type D3MonitoringGroupsEditorProps<DataType> = {
visible?: boolean visible?: boolean
groups: ExtendedChartDataset<DataType>[][] groups: ExtendedChartDataset<DataType>[][]
onChange: (value: ExtendedChartDataset<DataType>[][]) => void regulators: TelemetryRegulators
onChange: (value: ExtendedChartDataset<DataType>[][], regs: TelemetryRegulators) => void
onCancel: () => void onCancel: () => void
onReset: () => void onReset: () => void
} }
@ -36,9 +39,12 @@ const getNodePos = (node: EventDataNode): { group: number, chart?: number } => {
return { group: out[1], chart: out[2] } return { group: out[1], chart: out[2] }
} }
const _D3MonitoringGroupsEditor = <DataType,>({ type EditingMode = null | 'limit' | 'chart'
const _D3MonitoringEditor = <DataType,>({
visible, visible,
groups: oldGroups, groups: oldGroups,
regulators: oldRegulators,
onChange, onChange,
onCancel, onCancel,
onReset, onReset,
@ -46,10 +52,13 @@ const _D3MonitoringGroupsEditor = <DataType,>({
const [groups, setGroups] = useState<ExtendedChartDataset<DataType>[][]>([]) const [groups, setGroups] = useState<ExtendedChartDataset<DataType>[][]>([])
const [expand, setExpand] = useState<Key[]>([]) const [expand, setExpand] = useState<Key[]>([])
const [selected, setSelected] = useState<Key[]>([]) const [selected, setSelected] = useState<Key[]>([])
const [mode, setMode] = useState<EditingMode>(null)
const [regulators, setRegulators] = useState<TelemetryRegulators>({})
useEffect(() => setGroups(oldGroups), [oldGroups]) useEffect(() => setGroups(oldGroups), [oldGroups])
useEffect(() => setRegulators(oldRegulators), [oldRegulators])
const onModalOk = useCallback(() => onChange(groups), [groups]) const onModalOk = useCallback(() => onChange(groups, regulators), [groups, regulators])
const onDrop = useCallback((info: { const onDrop = useCallback((info: {
node: EventDataNode node: EventDataNode
@ -148,23 +157,29 @@ const _D3MonitoringGroupsEditor = <DataType,>({
selectedKeys={selected} selectedKeys={selected}
treeData={treeItems} treeData={treeItems}
onDrop={onDrop} onDrop={onDrop}
onSelect={setSelected} onSelect={(value) => {
setSelected(value)
setMode('chart')
}}
height={250} height={250}
/> />
<Button onClick={() => setMode('limit')}>Ограничение подачи</Button>
</div> </div>
<Divider type={'vertical'} style={{ height: '100%', padding: '0 5px' }} /> <Divider type={'vertical'} style={{ height: '100%', padding: '0 5px' }} />
<div style={divStyle}> <div style={divStyle}>
{selectedGroup && selectedChart ? ( {mode === 'chart' && selectedGroup && selectedChart ? (
<D3MonitoringChartEditor<DataType> group={selectedGroup} chart={selectedChart} onChange={onChartChange} /> <D3MonitoringChartEditor<DataType> group={selectedGroup} chart={selectedChart} onChange={onChartChange} />
) : (mode === 'limit' ? (
<D3MonitoringLimitEditor<DataType> value={regulators} onChange={setRegulators} />
) : ( ) : (
<Empty description={'Выберите график для редактирования'} /> <Empty description={'Выберите график для редактирования'} />
)} ))}
</div> </div>
</div> </div>
</Modal> </Modal>
) )
} }
export const D3MonitoringGroupsEditor = memo(_D3MonitoringGroupsEditor) as typeof _D3MonitoringGroupsEditor export const D3MonitoringEditor = memo(_D3MonitoringEditor) as typeof _D3MonitoringEditor
export default D3MonitoringGroupsEditor export default D3MonitoringEditor

View File

@ -3,15 +3,6 @@ import * as d3 from 'd3'
import { TelemetryDataSaubDto } from '@api' import { TelemetryDataSaubDto } from '@api'
export type D3MonitoringLimitChartProps<DataType> = {
yAxis?: d3.ScaleTime<number, number, never>
data: DataType[]
width: number
height: number
left: number
top: number
}
type LimitChartData = { type LimitChartData = {
id: number id: number
dateStart: Date dateStart: Date
@ -24,14 +15,10 @@ type LimitChartDataRaw = {
dateEnd?: string dateEnd?: string
} }
const regulators: Record<number, any> = { export type TelemetryRegulators = Record<number, {
1: { color: '#007070', label: 'Расход' }, color: string
2: { color: '#59B359', label: 'Скорость блока' }, label: string
3: { color: '#FF0000', label: 'Давление' }, }>
4: { color: '#0000CC', label: 'Осевая нагрузка' },
5: { color: '#00B3B3', label: 'Вес на крюке' },
6: { color: '#990099', label: 'Момент на роторе' },
}
const getLast = (out: LimitChartDataRaw[]) => out.at(-1) as LimitChartDataRaw const getLast = (out: LimitChartDataRaw[]) => out.at(-1) as LimitChartDataRaw
function isDataCorrect(value: LimitChartDataRaw): value is Required<LimitChartDataRaw> { function isDataCorrect(value: LimitChartDataRaw): value is Required<LimitChartDataRaw> {
@ -63,7 +50,25 @@ const calcualteData = <DataType extends TelemetryDataSaubDto>(data: DataType[])
})) }))
} }
const _D3MonitoringLimitChart = <DataType extends TelemetryDataSaubDto>({ yAxis, data: chartData, width, height, left, top }: D3MonitoringLimitChartProps<DataType>) => { export type D3MonitoringLimitChartProps<DataType> = {
yAxis?: d3.ScaleTime<number, number, never>
regulators: TelemetryRegulators
data: DataType[]
width: number
height: number
left: number
top: number
}
const _D3MonitoringLimitChart = <DataType extends TelemetryDataSaubDto>({
yAxis,
data: chartData,
width,
height,
left,
top,
regulators
}: D3MonitoringLimitChartProps<DataType>) => {
const [ref, setRef] = useState<SVGGElement | null>(null) const [ref, setRef] = useState<SVGGElement | null>(null)
const data = useMemo(() => calcualteData(chartData), [chartData]) const data = useMemo(() => calcualteData(chartData), [chartData])

View File

@ -0,0 +1,18 @@
import { memo } from 'react'
import { TelemetryRegulators } from './D3MonitoringLimitChart'
export type D3MonitoringLimitEditorProps = {
value: TelemetryRegulators
onChange: (value: TelemetryRegulators) => void
}
const _D3MonitoringLimitEditor = <DataType,>({ value, onChange }: D3MonitoringLimitEditorProps) => {
return (
<></>
)
}
export const D3MonitoringLimitEditor = memo(_D3MonitoringLimitEditor) as typeof _D3MonitoringLimitEditor
export default D3MonitoringLimitEditor