forked from ddrilling/asb_cloud_front
Refactor defaultNumericColunmOptions to makeNumericColunmOptions(..)
This commit is contained in:
parent
fbc0c97b99
commit
26044734ad
@ -32,7 +32,7 @@
|
|||||||
"react_test": "react-scripts test",
|
"react_test": "react-scripts test",
|
||||||
"eject": "react-scripts eject"
|
"eject": "react-scripts eject"
|
||||||
},
|
},
|
||||||
"proxy": "http://localhost:5000",
|
"proxy": "http://192.168.1.58:5000",
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
"react-app",
|
"react-app",
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
|
import { makeNumericSorter, makeStringSorter} from './sorters'
|
||||||
|
export { makeDateSorter, makeNumericSorter, makeStringSorter} from './sorters'
|
||||||
export { Table } from 'antd'
|
export { Table } from 'antd'
|
||||||
export { EditableTable } from './EditableTable'
|
export { EditableTable } from './EditableTable'
|
||||||
export { DatePickerWrapper } from './DatePickerWrapper'
|
export { DatePickerWrapper } from './DatePickerWrapper'
|
||||||
@ -7,10 +9,28 @@ export { SelectFromDictionary } from './SelectFromDictionary'
|
|||||||
export const RegExpIsFloat = /^[-+]?\d+\.?\d*$/
|
export const RegExpIsFloat = /^[-+]?\d+\.?\d*$/
|
||||||
export const formatDate='YYYY.MM.DD HH:mm'
|
export const formatDate='YYYY.MM.DD HH:mm'
|
||||||
|
|
||||||
export const numericColumnOptions = {
|
export const makeNumericRender = (fixed?:number) => (value: any, row: object): ReactNode => {
|
||||||
|
const placeholder = '-'
|
||||||
|
let val = placeholder
|
||||||
|
if((value !== null) ||
|
||||||
|
(value !== undefined) ||
|
||||||
|
Number.isNaN(value) ||
|
||||||
|
!Number.isFinite(value)){
|
||||||
|
val = !!fixed
|
||||||
|
? (+value).toFixed(fixed)
|
||||||
|
: (+value).toPrecision(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<div className='text-align-r-container'>
|
||||||
|
<span>{val}</span>
|
||||||
|
</div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const makeNumericColumnOptions = (fixed?:number, sorterKey?:string ) => ({
|
||||||
editable: true,
|
editable: true,
|
||||||
initialValue: 0,
|
initialValue: 0,
|
||||||
width:100,
|
width:100,
|
||||||
|
sorter: sorterKey? makeNumericSorter(sorterKey) : null,
|
||||||
formItemRules: [
|
formItemRules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
@ -18,7 +38,8 @@ export const numericColumnOptions = {
|
|||||||
pattern: RegExpIsFloat,
|
pattern: RegExpIsFloat,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
render: makeNumericRender(fixed),
|
||||||
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
other - объект с дополнительными свойствами колонки
|
other - объект с дополнительными свойствами колонки
|
||||||
@ -78,41 +99,6 @@ export const makeColumnsPlanFact = (title:string | ReactNode, key:string|string[
|
|||||||
export const makeFilterTextMatch = (key: string | number) => (filterValue: string | number, dataItem: any) =>
|
export const makeFilterTextMatch = (key: string | number) => (filterValue: string | number, dataItem: any) =>
|
||||||
dataItem[key] === filterValue
|
dataItem[key] === filterValue
|
||||||
|
|
||||||
export const makeNumericSorter = (key: string) => (a: any, b: any) => a[key] - b[key]
|
|
||||||
|
|
||||||
export const makeStringSorter = (key: string) => (a: any, b: any) =>
|
|
||||||
{
|
|
||||||
if(a == null && b == null)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if(a == null)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if(b == null)
|
|
||||||
return -1
|
|
||||||
|
|
||||||
let aValue = a[key]
|
|
||||||
let bValue = b[key]
|
|
||||||
|
|
||||||
for (let i = 0; i < a.length; i++) {
|
|
||||||
if (isNaN(aValue.charCodeAt(i)) || (aValue.charCodeAt(i) > bValue.charCodeAt(i)))
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if (aValue.charCodeAt(i) > bValue.charCodeAt(i))
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
export const makeDateSorter = (key: string) => (a: any, b: any) => {
|
|
||||||
const date = new Date(a[key])
|
|
||||||
|
|
||||||
if(Number.isNaN(date.getTime()))
|
|
||||||
throw new Error('Date column contains not date formatted string(s)')
|
|
||||||
|
|
||||||
return date.getTime() - new Date(b[key]).getTime()
|
|
||||||
}
|
|
||||||
|
|
||||||
export const makeGroupColumn = (title: string, children: object[]) => ({
|
export const makeGroupColumn = (title: string, children: object[]) => ({
|
||||||
title: title,
|
title: title,
|
||||||
children: children,
|
children: children,
|
||||||
@ -135,17 +121,6 @@ export const makeTextColumn = (
|
|||||||
...other
|
...other
|
||||||
})
|
})
|
||||||
|
|
||||||
export const defaultNumericRender = (value: any, row: object) => {
|
|
||||||
const placeholder = '-'
|
|
||||||
if((value === null) ||
|
|
||||||
(value === undefined) ||
|
|
||||||
Number.isNaN(value) ||
|
|
||||||
!Number.isFinite(value))
|
|
||||||
return placeholder
|
|
||||||
|
|
||||||
return (+value).toPrecision(5)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const makeNumericColumn = (title: string, dataIndex: string,
|
export const makeNumericColumn = (title: string, dataIndex: string,
|
||||||
filters: object[], filterDelegate: (key: string | number) => any,
|
filters: object[], filterDelegate: (key: string | number) => any,
|
||||||
renderDelegate: (_: any, row: object) => any, width: string) => ({
|
renderDelegate: (_: any, row: object) => any, width: string) => ({
|
||||||
@ -156,7 +131,7 @@ export const makeNumericColumn = (title: string, dataIndex: string,
|
|||||||
onFilter: filterDelegate ? filterDelegate(dataIndex) : null,
|
onFilter: filterDelegate ? filterDelegate(dataIndex) : null,
|
||||||
sorter: makeNumericSorter(dataIndex),
|
sorter: makeNumericSorter(dataIndex),
|
||||||
width: width,
|
width: width,
|
||||||
render: renderDelegate??defaultNumericRender,
|
render: renderDelegate??makeNumericRender(),
|
||||||
align: 'right'
|
align: 'right'
|
||||||
})
|
})
|
||||||
|
|
33
src/components/Table/sorters.ts
Normal file
33
src/components/Table/sorters.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
export const makeNumericSorter = (key: string) => (a: any, b: any) => a[key] - b[key];
|
||||||
|
|
||||||
|
export const makeStringSorter = (key: string) => (a: any, b: any) => {
|
||||||
|
if (a == null && b == null)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (a == null)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (b == null)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
let aValue = a[key];
|
||||||
|
let bValue = b[key];
|
||||||
|
|
||||||
|
for (let i = 0; i < a.length; i++) {
|
||||||
|
if (isNaN(aValue.charCodeAt(i)) || (aValue.charCodeAt(i) > bValue.charCodeAt(i)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (aValue.charCodeAt(i) > bValue.charCodeAt(i))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const makeDateSorter = (key: string) => (a: any, b: any) => {
|
||||||
|
const date = new Date(a[key]);
|
||||||
|
|
||||||
|
if (Number.isNaN(date.getTime()))
|
||||||
|
throw new Error('Date column contains not date formatted string(s)');
|
||||||
|
|
||||||
|
return date.getTime() - new Date(b[key]).getTime();
|
||||||
|
};
|
@ -1,133 +0,0 @@
|
|||||||
import {useEffect, useRef, useState} from 'react';
|
|
||||||
import {
|
|
||||||
Chart,
|
|
||||||
TimeScale,
|
|
||||||
LinearScale,
|
|
||||||
Legend,
|
|
||||||
LineController,
|
|
||||||
PointElement,
|
|
||||||
LineElement
|
|
||||||
} from 'chart.js'
|
|
||||||
import 'chartjs-adapter-moment';
|
|
||||||
import ChartDataLabels from 'chartjs-plugin-datalabels';
|
|
||||||
import zoomPlugin from 'chartjs-plugin-zoom';
|
|
||||||
|
|
||||||
Chart.register(TimeScale, LinearScale, LineController, LineElement, PointElement, Legend, ChartDataLabels, zoomPlugin);
|
|
||||||
|
|
||||||
const defaultOptions = {
|
|
||||||
responsive: true,
|
|
||||||
aspectRatio: 2.6,
|
|
||||||
interaction: {
|
|
||||||
intersect: false,
|
|
||||||
mode: 'index',
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x:{
|
|
||||||
display: true,
|
|
||||||
title: {
|
|
||||||
display: true
|
|
||||||
},
|
|
||||||
type: 'time',
|
|
||||||
time: {
|
|
||||||
unit: 'hour',
|
|
||||||
displayFormats: {
|
|
||||||
'hour': 'MM.DD'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grid:{
|
|
||||||
drawTicks: true,
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
stepSize:3,
|
|
||||||
major:{enabled:true,},
|
|
||||||
z: 1,
|
|
||||||
display : true,
|
|
||||||
textStrokeColor : "#fff",
|
|
||||||
textStrokeWidth : 2,
|
|
||||||
color:"#000",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
y:{
|
|
||||||
type:'linear',
|
|
||||||
position:'top',
|
|
||||||
reverse:true,
|
|
||||||
display: true,
|
|
||||||
title: {
|
|
||||||
display: false,
|
|
||||||
text: ''
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
parsing: {
|
|
||||||
xAxisKey: 'date',
|
|
||||||
yAxisKey: 'depth'
|
|
||||||
},
|
|
||||||
elements:{
|
|
||||||
point:{
|
|
||||||
radius:1.7,
|
|
||||||
//backgroundColor:'#aaa',
|
|
||||||
//pointStyle:'triangle',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins:{
|
|
||||||
legend:{
|
|
||||||
display: true,
|
|
||||||
},
|
|
||||||
datalabels: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
enabled: true,
|
|
||||||
callbacks: {
|
|
||||||
label(tooltipItem) {
|
|
||||||
return tooltipItem.yLabel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const makeDataset = (data, label, color, width=1.5, dash) => ({
|
|
||||||
label: label,
|
|
||||||
data: data,
|
|
||||||
backgroundColor: color,
|
|
||||||
borderColor: color,
|
|
||||||
borderWidth: width,
|
|
||||||
borderDash: dash,
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function ChartDepthToDay({dataPlan, dataFact, dataForecast}) {
|
|
||||||
const chartRef = useRef(null)
|
|
||||||
const [chart, setChart] = useState()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let data = {
|
|
||||||
datasets: [
|
|
||||||
makeDataset(dataFact, 'Факт', '#0A0'),
|
|
||||||
makeDataset(dataForecast, 'Прогноз', 'purple', 1, [7,3]),
|
|
||||||
makeDataset(dataPlan, 'План', '#C004', 4),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
if((chartRef.current)&&(!chart)) {
|
|
||||||
let thisOptions = {}
|
|
||||||
Object.assign(thisOptions, defaultOptions)
|
|
||||||
|
|
||||||
let newChart = new Chart(chartRef.current, {
|
|
||||||
type: 'line',
|
|
||||||
plugins: [ChartDataLabels],
|
|
||||||
options: thisOptions,
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
setChart(newChart)
|
|
||||||
|
|
||||||
return () => chart?.destroy()
|
|
||||||
} else {
|
|
||||||
chart.data = data
|
|
||||||
chart.update()
|
|
||||||
}
|
|
||||||
}, [chart, dataPlan, dataFact, dataForecast])
|
|
||||||
|
|
||||||
return (<canvas ref={chartRef} />)
|
|
||||||
}
|
|
@ -7,7 +7,7 @@ import {
|
|||||||
makeNumericColumnPlanFact
|
makeNumericColumnPlanFact
|
||||||
} from "../../components/Table";
|
} from "../../components/Table";
|
||||||
import { invokeWebApiWrapperAsync } from '../../components/factory';
|
import { invokeWebApiWrapperAsync } from '../../components/factory';
|
||||||
import ChartDepthToDay from '../../components/charts/ChartDepthToDay';
|
import ChartTvD from '../WellOperations/ChartTvD';
|
||||||
import WellOperationsTable from './WellOperationsTable'
|
import WellOperationsTable from './WellOperationsTable'
|
||||||
import {
|
import {
|
||||||
calcAndUpdateStatsBySections,
|
calcAndUpdateStatsBySections,
|
||||||
@ -249,10 +249,10 @@ export default function ClusterSections({ clusterData }) {
|
|||||||
width={1500}
|
width={1500}
|
||||||
footer={null}
|
footer={null}
|
||||||
>
|
>
|
||||||
<ChartDepthToDay
|
<ChartTvD
|
||||||
dataPlan={tvdDataPlan}
|
dataPlan={tvdDataPlan}
|
||||||
dataFact={tvdDataFact}
|
dataFact={tvdDataFact}
|
||||||
dataForecast={tvdDataForecast} />
|
dataPredict={tvdDataForecast} />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
|
@ -6,12 +6,11 @@ import {
|
|||||||
makeTextColumn,
|
makeTextColumn,
|
||||||
makeGroupColumn,
|
makeGroupColumn,
|
||||||
makeColumn,
|
makeColumn,
|
||||||
makeNumericColumnPlanFact,
|
makeDateSorter,
|
||||||
makeDateSorter
|
makeNumericColumnPlanFact} from "../../components/Table";
|
||||||
} from "../../components/Table";
|
|
||||||
import { calcAndUpdateStatsBySections, makeFilterMinMaxFunction } from "./functions";
|
import { calcAndUpdateStatsBySections, makeFilterMinMaxFunction } from "./functions";
|
||||||
import { invokeWebApiWrapperAsync } from '../../components/factory';
|
import { invokeWebApiWrapperAsync } from '../../components/factory';
|
||||||
import ChartDepthToDay from '../../components/charts/ChartDepthToDay';
|
import ChartTvD from '../WellOperations/ChartTvD';
|
||||||
import WellOperationsTable from './WellOperationsTable'
|
import WellOperationsTable from './WellOperationsTable'
|
||||||
import { getOperations } from "./functions";
|
import { getOperations } from "./functions";
|
||||||
|
|
||||||
@ -206,10 +205,10 @@ useEffect(() => {
|
|||||||
width={1500}
|
width={1500}
|
||||||
footer={null}
|
footer={null}
|
||||||
>
|
>
|
||||||
<ChartDepthToDay
|
<ChartTvD
|
||||||
dataPlan={tvdDataPlan}
|
dataPlan={tvdDataPlan}
|
||||||
dataFact={tvdDataFact}
|
dataFact={tvdDataFact}
|
||||||
dataForecast={tvdDataForecast}
|
dataPredict={tvdDataForecast}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
@ -6,17 +6,24 @@ const minPrefix = "isMin"
|
|||||||
export const getOperations = async (idWell) => {
|
export const getOperations = async (idWell) => {
|
||||||
const ops = await WellOperationStatService.getTvd(idWell);
|
const ops = await WellOperationStatService.getTvd(idWell);
|
||||||
|
|
||||||
const planData = ops.map(el => {
|
const convert = wellOperationDto =>
|
||||||
return {key: el.plan?.id, depth: el.plan?.wellDepth, date: el.plan?.startDate}
|
({
|
||||||
}).filter(el => el.key)
|
key: wellOperationDto?.id,
|
||||||
|
depth: wellOperationDto?.depthStart,
|
||||||
|
date: wellOperationDto?.dateStart
|
||||||
|
})
|
||||||
|
|
||||||
const factData = ops.map(el => {
|
const planData = ops
|
||||||
return {key: el.fact?.id, depth: el.fact?.wellDepth, date: el.fact?.startDate}
|
.map(item => convert(item.plan))
|
||||||
}).filter(el => el.key)
|
.filter(el => el.key)
|
||||||
|
|
||||||
const predictData = ops.map(el => {
|
const factData = ops
|
||||||
return {key: el.predict?.id, depth: el.predict?.wellDepth, date: el.predict?.startDate}
|
.map(item => convert(item.fact))
|
||||||
}).filter(el => el.key)
|
.filter(el => el.key)
|
||||||
|
|
||||||
|
const predictData = ops
|
||||||
|
.map(item => convert(item.predict))
|
||||||
|
.filter(el => el.key)
|
||||||
|
|
||||||
return { operations: ops, plan: planData, fact: factData, predict: predictData }
|
return { operations: ops, plan: planData, fact: factData, predict: predictData }
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useState, useEffect } from "react"
|
import { useState, useEffect } from "react"
|
||||||
import { Table, makeDateSorter, makeNumericSorter, formatDate} from "../../components/Table"
|
import { Table, formatDate, makeDateSorter, makeNumericSorter} from "../../components/Table"
|
||||||
import { Button, Tooltip } from "antd"
|
import { Button, Tooltip } from "antd"
|
||||||
import { FilePdfOutlined, FileTextOutlined} from '@ant-design/icons'
|
import { FilePdfOutlined, FileTextOutlined} from '@ant-design/icons'
|
||||||
import { ReportService } from "../../services/api"
|
import { ReportService } from "../../services/api"
|
||||||
|
Loading…
Reference in New Issue
Block a user