forked from ddrilling/asb_cloud_front
monitoring screen redesign
This commit is contained in:
parent
b1d73e33b9
commit
10b6dcc307
52
src/components/ChartTimeOnlineFooter.jsx
Normal file
52
src/components/ChartTimeOnlineFooter.jsx
Normal file
@ -0,0 +1,52 @@
|
||||
import {ValueDisplay} from './Display'
|
||||
import {ControlOutlined} from '@ant-design/icons'
|
||||
import {Popover} from 'antd'
|
||||
|
||||
export const ChartTimeOnlineFooter = (props) =>{
|
||||
const { data,
|
||||
lineIdle,
|
||||
lineSp,
|
||||
linesOther} = props
|
||||
|
||||
let sp = null
|
||||
let idle = null
|
||||
|
||||
if(data && lineSp)
|
||||
sp = data[lineSp.xAccessorName]
|
||||
|
||||
if(data && lineIdle)
|
||||
idle = data[lineIdle.xAccessorName]
|
||||
|
||||
let spField = <ValueDisplay value={sp}/>
|
||||
|
||||
let popContent = linesOther?.map(line =>{
|
||||
let val = null
|
||||
if(data)
|
||||
val = data[line.xAccessorName]
|
||||
return (
|
||||
<div key={line.label}>
|
||||
{line.label}
|
||||
<ValueDisplay value={val}/>
|
||||
</div>)
|
||||
})
|
||||
|
||||
if(popContent)
|
||||
spField = <Popover content={popContent}>
|
||||
<div style={{display:"flex"}}>
|
||||
<ControlOutlined className='display_label'/>
|
||||
{spField}
|
||||
</div>
|
||||
</Popover>
|
||||
else
|
||||
spField = <div style={{display:"flex"}}>
|
||||
{spField}
|
||||
</div>
|
||||
|
||||
return(<div>
|
||||
{spField}
|
||||
<div style={{display:"flex"}}>
|
||||
<span className='display_label'>х.х.</span>
|
||||
<ValueDisplay value={idle}/>
|
||||
</div>
|
||||
</div>)
|
||||
}
|
26
src/components/CustomColumn.jsx
Normal file
26
src/components/CustomColumn.jsx
Normal file
@ -0,0 +1,26 @@
|
||||
import {Display} from './Display'
|
||||
|
||||
export const CustomColumn = ({data}) => {
|
||||
const dataLast = data[data.length -1]
|
||||
|
||||
const lines = [
|
||||
{label:'Рот., об/мин', accessorName:'rotorSpeed'},
|
||||
{label:'Долото, м', accessorName:'bitDepth'},
|
||||
{label:'Забой, м', accessorName:'wellDepth'},
|
||||
{label:'Расход, м³/ч', accessorName:'flow'},
|
||||
{label:'Расход х.х., м³/ч', accessorName:'flowIdle'},
|
||||
]
|
||||
|
||||
if(dataLast)
|
||||
lines.forEach(line => line.value = dataLast[line.accessorName]?.toPrecision(4)??'-' )
|
||||
else
|
||||
lines.forEach(line => line.value = '-' )
|
||||
|
||||
return (<>
|
||||
{lines.map(line => <Display className='border_small display_flex_container'
|
||||
kay={line.label}
|
||||
label={line.label}
|
||||
value={line.value}
|
||||
suffix={line.units}/>)}
|
||||
</>)
|
||||
}
|
23
src/components/Display.jsx
Normal file
23
src/components/Display.jsx
Normal file
@ -0,0 +1,23 @@
|
||||
export const ValueDisplay = ({prefix, value, suffix}) =>{
|
||||
let val = '---'
|
||||
|
||||
if(value)
|
||||
if(Number.isFinite(+value))
|
||||
val = (+value).toPrecision(4)??'---'
|
||||
else
|
||||
val = value
|
||||
|
||||
return(<span className='display_value'>{prefix} {val} {suffix}</span>)
|
||||
}
|
||||
|
||||
export const Display = (props)=>{
|
||||
const {label} = props
|
||||
|
||||
return <div className={props.className}>
|
||||
<div className='display_label'>{label}</div>
|
||||
<div style={{display:"flex", flexGrow:1}}>
|
||||
<ValueDisplay {...props}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
27
src/components/ModeDisplay.jsx
Normal file
27
src/components/ModeDisplay.jsx
Normal file
@ -0,0 +1,27 @@
|
||||
const modeNames = {
|
||||
0: "Ручной",
|
||||
1: "Бурение в роторе",
|
||||
2: "Проработка",
|
||||
3: "Бурение в слайде",
|
||||
4: "Спуск СПО",
|
||||
5: "Подъем СПО",
|
||||
6: "Подъем с проработкой",
|
||||
|
||||
10: "БЛОКИРОВКА",
|
||||
}
|
||||
|
||||
export const ModeDisplay = (props)=>{
|
||||
let value = '---'
|
||||
|
||||
if(props.data.length > 0){
|
||||
let lastFullData = props.data[props.data.length - 1]
|
||||
let index = lastFullData['mode']
|
||||
if(index >= 0)
|
||||
value = modeNames[index] ?? index
|
||||
}
|
||||
|
||||
return(<>
|
||||
<span className="display_label">Режим:</span>
|
||||
<span className="display_value">{value}</span>
|
||||
</>)
|
||||
}
|
6
src/components/Well.jsx
Normal file
6
src/components/Well.jsx
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
export const Well = (props) => {
|
||||
|
||||
return(<div></div>)
|
||||
}
|
@ -14,16 +14,17 @@ import 'chartjs-adapter-date-fns';
|
||||
|
||||
Chart.register( TimeScale, LinearScale, LineController, LineElement, PointElement, Legend );
|
||||
|
||||
const defailtOptions = {
|
||||
maintainAspectRatio: false,
|
||||
aspectRatio:0.4,
|
||||
const defaultOptions = {
|
||||
//maintainAspectRatio: false,
|
||||
aspectRatio:0.45,
|
||||
animation: false,
|
||||
scales: {
|
||||
y:{
|
||||
type: 'time',
|
||||
reverse:true,
|
||||
time: {
|
||||
unit: 'second',
|
||||
//unit: 'second',
|
||||
//round:'second',
|
||||
stepSize: 20,
|
||||
displayFormats: {
|
||||
millisecond: 'HH:mm:ss.SSS',
|
||||
@ -44,7 +45,7 @@ const defailtOptions = {
|
||||
ticks: {
|
||||
z: 1,
|
||||
textStrokeColor : "#ffff",
|
||||
textStrokeWidth : 1,
|
||||
textStrokeWidth : 2,
|
||||
color:"#000",
|
||||
}
|
||||
},
|
||||
@ -84,6 +85,19 @@ export type ChartTimeBaseProps = {
|
||||
options?: ChartOptions<keyof ChartTypeRegistry>,
|
||||
}
|
||||
|
||||
const timeUnitByInterval = (intervalSec:number):String =>{
|
||||
if(intervalSec < 24*60*60)
|
||||
return 'second'
|
||||
|
||||
if(intervalSec < 30*24*60*60)
|
||||
return 'day'
|
||||
|
||||
if(intervalSec < 365*24*60*60)
|
||||
return 'week'
|
||||
else
|
||||
return 'year'
|
||||
}
|
||||
|
||||
export const ChartTimeBase: React.FC<ChartTimeBaseProps> = (props) => {
|
||||
const chartRef = useRef<HTMLCanvasElement>(null)
|
||||
|
||||
@ -92,7 +106,7 @@ export const ChartTimeBase: React.FC<ChartTimeBaseProps> = (props) => {
|
||||
useEffect(()=>{
|
||||
if(chartRef.current && (!chart)){
|
||||
let thisOptions = {}
|
||||
Object.assign(thisOptions, defailtOptions, props.options)
|
||||
Object.assign(thisOptions, defaultOptions, props.options)
|
||||
|
||||
let newChart = new Chart(chartRef.current, {
|
||||
type: 'line',
|
||||
@ -104,17 +118,14 @@ export const ChartTimeBase: React.FC<ChartTimeBaseProps> = (props) => {
|
||||
}
|
||||
}, [chart, props.options, props.dataParams])
|
||||
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
if(!chart)
|
||||
return
|
||||
|
||||
//mergeDataSets(chart.data, props.dataParams.data)
|
||||
chart.data = props.dataParams.data
|
||||
|
||||
if(props.dataParams.yStart){
|
||||
let interval = props.dataParams.yInterval ?? 600
|
||||
let interval = Number(props.dataParams.yInterval ?? 600)
|
||||
let start = new Date(props.dataParams.yStart)
|
||||
let end = new Date(props.dataParams.yStart)
|
||||
end.setSeconds(end.getSeconds() + interval)
|
||||
@ -123,6 +134,8 @@ export const ChartTimeBase: React.FC<ChartTimeBaseProps> = (props) => {
|
||||
chart.options.scales.y.max = end.getTime()
|
||||
chart.options.scales.y.min = start.getTime()
|
||||
chart.options.scales.y.ticks.display = props.dataParams.displayLabels ?? true
|
||||
chart.options.scales.y.time.unit = timeUnitByInterval(interval)
|
||||
chart.options.scales.y.time.stepSize = Math.round(interval/24)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,9 @@ function GetOrCreateDatasetByLineConfig (data: ChartTimeData, lineConfig: LineC
|
||||
export type LineConfig = {
|
||||
type?: string
|
||||
label: string
|
||||
xAcessorName: string
|
||||
yAcessorName: string
|
||||
units?: string
|
||||
xAccessorName: string
|
||||
yAccessorName: string
|
||||
color?:string
|
||||
borderColor?: string
|
||||
backgroundColor?: string
|
||||
@ -39,14 +40,17 @@ export type LineConfig = {
|
||||
}
|
||||
|
||||
export type ChartTimeProps = {
|
||||
label?: string,
|
||||
yDisplay: Boolean,
|
||||
// linePv?: LineConfig,
|
||||
// lineSp?: LineConfig,
|
||||
// lineIdle?: LineConfig,
|
||||
lines: LineConfig[],
|
||||
data: any[],
|
||||
interval: number,
|
||||
}
|
||||
|
||||
export const ChartTime: React.FC<ChartTimeProps> = (props) => {
|
||||
|
||||
export const ChartTimeOnline: React.FC<ChartTimeProps> = (props) => {
|
||||
const [dataParams, setDataParams] = useState<ChartTimeDataParams>({data: {datasets:[]}, yStart: new Date(), })
|
||||
|
||||
useEffect(()=>{
|
||||
@ -56,23 +60,30 @@ export const ChartTime: React.FC<ChartTimeProps> = (props) => {
|
||||
|| (props.data.length === 0))
|
||||
return
|
||||
|
||||
setDataParams((preDataParams) => {
|
||||
props.lines.forEach(lineCfg => {
|
||||
let dataset = GetOrCreateDatasetByLineConfig(dataParams.data, lineCfg)
|
||||
let dataset = GetOrCreateDatasetByLineConfig(preDataParams.data, lineCfg)
|
||||
let points = props.data.map(dataItem => {return{
|
||||
x: dataItem[lineCfg.xAcessorName],
|
||||
y: new Date(dataItem[lineCfg.yAcessorName])}
|
||||
x: dataItem[lineCfg.xAccessorName],
|
||||
y: new Date(dataItem[lineCfg.yAccessorName])}
|
||||
})
|
||||
dataset.data = [ ...dataset.data, ...points, ].slice(-1024)
|
||||
//dataset.data = [ ...dataset.data, ...points,].slice(-1024)
|
||||
let data = [ ...dataset.data, ...points,]
|
||||
if(points?.length > 2)
|
||||
data.sort((a,b) => a.y > b.y ? 1 : -1)
|
||||
if(data.length > 1024)
|
||||
data.splice(0, (1024 - data.length))
|
||||
dataset.data = data;
|
||||
});
|
||||
|
||||
dataParams.yStart = new Date()
|
||||
dataParams.yStart.setSeconds(dataParams.yStart.getSeconds() - props.interval)
|
||||
dataParams.yInterval = props.interval
|
||||
dataParams.displayLabels = props.yDisplay
|
||||
preDataParams.yStart = new Date()
|
||||
preDataParams.yStart.setSeconds(preDataParams.yStart.getSeconds() - props.interval)
|
||||
preDataParams.yInterval = props.interval
|
||||
preDataParams.displayLabels = props.yDisplay
|
||||
return preDataParams
|
||||
})
|
||||
|
||||
setDataParams(dataParams)
|
||||
|
||||
}, [ props.data, props.lines, props.interval])
|
||||
}, [ props.data, props.lines, props.interval, props.yDisplay])
|
||||
|
||||
return(<ChartTimeBase dataParams = {dataParams} />)
|
||||
}
|
@ -4,7 +4,7 @@ import logo from '../images/logo_32.png'
|
||||
import { useState } from 'react'
|
||||
import { Switch, Route, Redirect, Link} from "react-router-dom"
|
||||
import Wells from './Wells'
|
||||
import Well from './Well'
|
||||
import TelemetryView from './TelemetryView'
|
||||
import Files from './Files'
|
||||
|
||||
const { Header, Content, Sider } = Layout
|
||||
@ -43,7 +43,19 @@ export default function Main(){
|
||||
<Link to="/well">Мониторинг</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="2" icon= {<FolderOutlined />}>
|
||||
<Link to="/file">файлы</Link>
|
||||
<Link to="/file">Архив</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="3" icon= {<FolderOutlined />}>
|
||||
<Link to="/file">Сообщения</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="4" icon= {<FolderOutlined />}>
|
||||
<Link to="/file">Рапорт</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="5" icon= {<FolderOutlined />}>
|
||||
<Link to="/file">Анализ</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="6" icon= {<FolderOutlined />}>
|
||||
<Link to="/file">Файлы</Link>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
</Sider>
|
||||
@ -56,7 +68,7 @@ export default function Main(){
|
||||
<Files />
|
||||
</Route>
|
||||
<Route path="/well/:id">
|
||||
<Well/>
|
||||
<TelemetryView/>
|
||||
</Route>
|
||||
<Route path="/well">
|
||||
<Wells />
|
||||
|
158
src/pages/TelemetryView.jsx
Normal file
158
src/pages/TelemetryView.jsx
Normal file
@ -0,0 +1,158 @@
|
||||
import { useState, useEffect} from 'react';
|
||||
import { Row, Col, Select, } from 'antd'
|
||||
import { ChartTimeOnline} from '../components/charts/ChartTimeOnline'
|
||||
import { ChartTimeOnlineFooter} from '../components/ChartTimeOnlineFooter'
|
||||
import { CustomColumn} from '../components/CustomColumn'
|
||||
import { ModeDisplay } from '../components/ModeDisplay';
|
||||
import { Display } from '../components/Display';
|
||||
|
||||
import { useParams} from 'react-router-dom'
|
||||
import { Subscribe} from '../services/signalr'
|
||||
import { DataService} from '../services/api'
|
||||
|
||||
const {Option} = Select
|
||||
|
||||
const dash = [7,3]
|
||||
|
||||
const blockHeightGroup = {
|
||||
label:"Высота блока",
|
||||
yDisplay: false,
|
||||
linePv: { label:"blockHeight", units:'м', xAccessorName : "blockHeight", yAccessorName : "date", color:'#333' },
|
||||
}
|
||||
|
||||
const blockSpeedGroup = {
|
||||
label:"Скорость блока",
|
||||
yDisplay: false,
|
||||
linePv: { label:"blockSpeed", units:'м/ч', xAccessorName : "blockSpeed", yAccessorName : "date", color:'#0a0' },
|
||||
lineSp: { label:"blockSpeedSp", units:'м/ч', xAccessorName : "blockSpeedSp", yAccessorName : "date", color:'#0a0' },
|
||||
}
|
||||
|
||||
const pressureGroup = {
|
||||
label:"Давтение",
|
||||
yDisplay: false,
|
||||
linePv: { label:"pressure", units:'атм', xAccessorName : "pressure", yAccessorName : "date", color:'#c00' },
|
||||
lineSp: { label:"pressureSp", units:'атм', xAccessorName : "pressureSp", yAccessorName : "date", color:'#c00' },
|
||||
lineIdle: { label:"pressureIdle", units:'атм', xAccessorName : "pressureIdle", yAccessorName : "date", color:'#c00' },
|
||||
linesOther: [
|
||||
{ label:"мекс. перепад", units:'атм', xAccessorName : "pressureDeltaLimitMax", yAccessorName : "date", color:'#c00' },
|
||||
],
|
||||
}
|
||||
|
||||
const axialLoadGroup = {
|
||||
label:"Осевая нагрузка",
|
||||
yDisplay: false,
|
||||
linePv: { label:"axialLoad", units:'т', xAccessorName : "axialLoad", yAccessorName : "date", color:'#00a' },
|
||||
lineSp: { label:"axialLoadSp", units:'т', xAccessorName : "axialLoadSp", yAccessorName : "date", color:'#00a', dash },
|
||||
linesOther: [
|
||||
{ label:"axialLoadLimitMax", units:'т', xAccessorName : "axialLoadLimitMax", yAccessorName : "date", color:'#00a' },
|
||||
],
|
||||
}
|
||||
|
||||
const hookWeightGroup = {
|
||||
label:"Ввес на крюке",
|
||||
yDisplay: false,
|
||||
linePv: { label:"hookWeight", units:'т', xAccessorName : "hookWeight", yAccessorName : "date", color:'#0aa' },
|
||||
lineIdle: { label:"hookWeightIdle", units:'т', xAccessorName : "hookWeightIdle", yAccessorName : "date", color:'#0aa', dash },
|
||||
linesOther: [
|
||||
{ label:"hookWeightLimitMin", units:'т', xAccessorName : "hookWeightLimitMin", yAccessorName : "date", color:'#0aa' },
|
||||
{ label:"hookWeightLimitMax", units:'т', xAccessorName : "hookWeightLimitMax", yAccessorName : "date", color:'#0aa' },
|
||||
],
|
||||
}
|
||||
|
||||
const rotorTorqueGroup = {
|
||||
label:"Момент на роторе",
|
||||
yDisplay: false,
|
||||
linePv: { label:"rotorTorque", units:'кН·м', xAccessorName : "rotorTorque", yAccessorName : "date", color:'#a0a' },
|
||||
lineSp: { label:"rotorTorqueSp", units:'кН·м', xAccessorName : "rotorTorqueSp", yAccessorName : "date", color:'#a0a' },
|
||||
lineIdle: { label:"rotorTorqueIdle", units:'кН·м', xAccessorName : "rotorTorqueIdle", yAccessorName : "date", color:'#a0a' },
|
||||
linesOther: [
|
||||
{ label:"rotorTorqueLimitMax", units:'кН·м', xAccessorName : "rotorTorqueLimitMax", yAccessorName : "date", color:'#a0a' },
|
||||
],
|
||||
}
|
||||
|
||||
const paramsGroups = [blockHeightGroup, blockSpeedGroup, pressureGroup, axialLoadGroup, hookWeightGroup, rotorTorqueGroup]
|
||||
|
||||
export const Column = ({lineGroup, data, interval})=>{
|
||||
let lines = [lineGroup.linePv]
|
||||
|
||||
if(lineGroup.lineSp)
|
||||
lines.push(lineGroup.lineSp)
|
||||
|
||||
let dataLast = null
|
||||
let pv = null
|
||||
if(data?.length > 0 ){
|
||||
dataLast = data[data.length - 1];
|
||||
if(lineGroup.linePv)
|
||||
pv = dataLast[lineGroup.linePv?.xAccessorName]
|
||||
}
|
||||
|
||||
return(
|
||||
<>
|
||||
<Display
|
||||
label={lineGroup.label}
|
||||
value={pv}
|
||||
suffix={lineGroup.linePv?.units}/>
|
||||
<ChartTimeOnline
|
||||
data={data}
|
||||
yDisplay={lineGroup.yDisplay}
|
||||
lines={lines}
|
||||
interval={interval}/>
|
||||
<ChartTimeOnlineFooter
|
||||
data={dataLast}
|
||||
{...lineGroup} />
|
||||
</>)
|
||||
}
|
||||
|
||||
export default function TelemetryView(props){
|
||||
let { id } = useParams();
|
||||
const [saubData, setSaubData] = useState([])
|
||||
const [chartInterval, setchartInterval] = useState(600)
|
||||
|
||||
const handleReceiveDataSaub = (data)=>{
|
||||
if(data){
|
||||
setSaubData(data)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect( ()=> {
|
||||
DataService.get(id)
|
||||
.then(handleReceiveDataSaub)
|
||||
.catch(error=>console.error(error))
|
||||
|
||||
return Subscribe('ReceiveDataSaub', `well_${id}`, handleReceiveDataSaub)
|
||||
}, [id]);
|
||||
|
||||
const colSpan = 24/(paramsGroups.length )
|
||||
|
||||
return(<div>
|
||||
{/* <div>Well id: {id}; points count: {saubData.length}</div> */}
|
||||
<Row style={{marginBottom:'1rem'}}>
|
||||
<Col>
|
||||
<ModeDisplay data={saubData}/>
|
||||
</Col>
|
||||
<Col>
|
||||
Интервал:
|
||||
<Select defaultValue="600" onChange={setchartInterval}>
|
||||
<Option value='600'>10 минут</Option>
|
||||
<Option value='1800'>30 минут</Option>
|
||||
<Option value='3600'>1 час</Option>
|
||||
<Option value='21600'>6 час</Option>
|
||||
<Option value='86400'>1 день</Option>
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={2} >
|
||||
<CustomColumn data={saubData} />
|
||||
</Col>
|
||||
<Col span={24 - 2}>
|
||||
<Row>
|
||||
{paramsGroups.map(group=>
|
||||
<Col span={colSpan} className='border_small' key={group.label}>
|
||||
<Column data={saubData} lineGroup={group} interval={chartInterval}/>
|
||||
</Col>)}
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>)
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
import React, { useState, useEffect,} from 'react';
|
||||
import { Row, Col} from 'antd'
|
||||
import {ChartTime} from '../components/charts/ChartTime'
|
||||
|
||||
import {useParams} from 'react-router-dom'
|
||||
import {Subscribe} from '../services/signalr'
|
||||
import {DataService} from '../services/api'
|
||||
|
||||
const dash = [7,3]
|
||||
|
||||
const lineParameters = [
|
||||
{
|
||||
yDisplay: true,
|
||||
lines:[
|
||||
{ label:"blockHeight", xAcessorName : "blockHeight", yAcessorName : "date", color:'#aaf' },
|
||||
],
|
||||
},
|
||||
{
|
||||
yDisplay: false,
|
||||
lines:[
|
||||
{ label:"blockSpeed", xAcessorName : "blockSpeed", yAcessorName : "date", color:'#0a0' },
|
||||
{ label:"blockSpeedSp", xAcessorName : "blockSpeedSp", yAcessorName : "date", color:'#0a0', dash },
|
||||
],
|
||||
},
|
||||
{
|
||||
yDisplay: false,
|
||||
lines:[
|
||||
{ label:"pressure", xAcessorName : "pressure", yAcessorName : "date", color:'#a00' },
|
||||
{ label:"pressureSp", xAcessorName : "pressureSp", yAcessorName : "date", color:'#a00', dash },
|
||||
],
|
||||
},
|
||||
{
|
||||
yDisplay: false,
|
||||
lines:[
|
||||
{ label:"axialLoad", xAcessorName : "axialLoad", yAcessorName : "date", color:'#00a' },
|
||||
{ label:"axialLoadSp", xAcessorName : "axialLoadSp", yAcessorName : "date", color:'#00a', dash },
|
||||
],
|
||||
},
|
||||
{
|
||||
yDisplay: false,
|
||||
lines:[
|
||||
{ label:"вес", xAcessorName : "hookWeight", yAcessorName : "date", color:'#0aa' },
|
||||
{ label:"вес макс", xAcessorName : "hookWeightLimitMax", yAcessorName : "date", color:'#0aa', dash },
|
||||
],
|
||||
},
|
||||
{
|
||||
yDisplay: false,
|
||||
lines:[
|
||||
{ label:"rotorTorque", xAcessorName : "rotorTorque", yAcessorName : "date", color:'#a0a' },
|
||||
{ label:"rotorTorqueSp", xAcessorName : "rotorTorqueSp", yAcessorName : "date", color:'#a0a', dash },
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
const interval = 600
|
||||
|
||||
export default function Well(props){
|
||||
let { id } = useParams();
|
||||
const [saubData, setSaubData] = useState([])
|
||||
|
||||
const handleReceiveDataSaub = (data)=>{
|
||||
if(data)
|
||||
setSaubData(data)
|
||||
}
|
||||
|
||||
useEffect( ()=> {
|
||||
DataService.get(id)
|
||||
.then(handleReceiveDataSaub)
|
||||
.catch(error=>console.error(error))
|
||||
|
||||
return Subscribe('ReceiveDataSaub', `well_${id}`, handleReceiveDataSaub)
|
||||
},
|
||||
[id]);
|
||||
|
||||
let colSpan = 24/lineParameters.length
|
||||
let cols = lineParameters.map(line =>
|
||||
<Col span={colSpan}>
|
||||
<ChartTime data={saubData} {...line} interval={interval}/>
|
||||
</Col>)
|
||||
|
||||
return(<div>
|
||||
<div>Well id: {id}; points count: {saubData.length}</div>
|
||||
<Row height='100%'>{cols}</Row>
|
||||
|
||||
</div>)
|
||||
}
|
@ -58,19 +58,44 @@
|
||||
min-height: 280;
|
||||
}
|
||||
|
||||
#components-layout-demo-top-side-2 .logo {
|
||||
float: left;
|
||||
width: 120px;
|
||||
height: 31px;
|
||||
margin: 16px 24px 16px 0;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.ant-row-rtl #components-layout-demo-top-side-2 .logo {
|
||||
float: right;
|
||||
margin: 16px 0 16px 24px;
|
||||
}
|
||||
|
||||
.site-layout-background {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.border_small{
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.display_flex_container{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.display_label{
|
||||
font-size: 16px;
|
||||
color: rgb(70, 70, 70);
|
||||
text-align: left;
|
||||
justify-content: baseline;
|
||||
margin: 1px 1rem 1px 1rem;
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.display_value{
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: rgb(50, 50, 50);
|
||||
text-align: right;
|
||||
justify-content: flex-end;
|
||||
align-items:baseline;
|
||||
margin: 1px 1rem 1px 1rem;
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.display_small_value{
|
||||
color: rgb(50, 50, 50);
|
||||
text-align: right;
|
||||
justify-content: baseline;
|
||||
margin: 1px 1rem 1px 1rem;
|
||||
flex: auto;
|
||||
}
|
Loading…
Reference in New Issue
Block a user