core/websrc/components/RPlot.tsx
Giulio De Pasquale a7d888f00a renamed newdata
2020-12-16 11:27:53 +00:00

175 lines
5.0 KiB
TypeScript

import React, {Component} from "react"
import Plot from "react-plotly.js"
import {NewTickMessage, socket} from '../';
type FirstConnectData = {
ticks: Array<number>,
prices: Array<number>
}
type PriceLine = {
x0: number,
y0: number,
x1: number,
y1: number
}
type PlotState = {
x: Array<number>,
y: Array<number>,
current_price_line: PriceLine,
positions_price_lines: Array<PriceLine>,
}
class RPlot extends Component<{}, PlotState> {
state = {
x: [],
y: [],
current_price_line: {x0: 0, x1: 0, y0: 0, y1: 0},
positions_price_lines: []
}
constructor(props) {
super(props)
}
componentDidMount() {
socket.on("first_connect", (data: FirstConnectData) => {
const last_tick = data.ticks[data.ticks.length - 1];
const last_price = data.prices[data.prices.length - 1];
this.setState({
x: data.ticks,
y: data.prices,
current_price_line: {
x0: 0,
y0: last_price,
x1: last_tick,
y1: last_price
},
})
})
socket.on("new_tick", (data: NewTickMessage) => {
const new_x = [...this.state.x, data.tick];
const new_y = [...this.state.y, data.price];
// cutting to up to 500 entries (last 500)
const x = new_x.slice(Math.max(new_x.length - 500, 0));
const y = new_y.slice(Math.max(new_y.length - 500, 0));
const position_price_lines = data.positions.map((pstat): PriceLine => {
return {
x0: 0,
y0: pstat.base_price,
x1: data.tick,
y1: pstat.base_price
}
})
this.setState({
x: x,
y: y,
current_price_line: {
x0: 0,
y0: data.price,
x1: data.tick,
y1: data.price
},
positions_price_lines: position_price_lines
})
})
}
render() {
let additional_shapes = []
if (this.state.positions_price_lines.length > 0) {
additional_shapes = this.state.positions_price_lines.map((priceline: PriceLine) => {
return {
type: 'line',
x0: priceline.x0,
y0: priceline.y0,
x1: priceline.x1,
y1: priceline.y1,
line: {
color: 'rgb(1, 1, 1)',
width: 1,
dash: 'solid'
}
}
})
}
return (
<Plot
data={[
{
x: this.state.x,
y: this.state.y,
type: 'scatter',
mode: 'lines+markers',
},
]}
layout={{
margin: {
l: 50,
r: 50,
b: 50,
t: 50,
pad: 4
},
dragmode: "pan",
shapes: [
{
type: 'line',
x0: this.state.current_price_line.x0,
y0: this.state.current_price_line.y0,
x1: this.state.current_price_line.x1,
y1: this.state.current_price_line.y1,
line: {
color: 'rgb(50, 171, 96)',
width: 2,
dash: 'dashdot'
}
},
].concat(additional_shapes),
xaxis: {
title: {
text: 'Tick',
font: {
family: 'Courier New, monospace',
size: 18,
color: '#7f7f7f'
}
},
},
yaxis: {
title: {
text: 'Price',
font: {
family: 'Courier New, monospace',
size: 18,
color: '#7f7f7f'
}
},
tickformat: 'r',
}
}}
config={{
scrollZoom: true,
displayModeBar: false,
responsive: true,
}}
style={{width: '100%', height: '90%'}}
/>
)
}
}
export default RPlot;