core/websrc/components/RPlot.tsx
2020-12-14 16:02:01 +00:00

160 lines
4.5 KiB
TypeScript

import React from "react"
import { Component } from "react"
import Plot from "react-plotly.js"
import { NewTickData, 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>,
h_price_line: PriceLine,
v_price_line: PriceLine
}
class RPlot extends Component<{}, PlotState> {
constructor(props) {
super(props)
}
state = {
x: [],
y: [],
h_price_line: { x0: 0, x1: 0, y0: 0, y1: 0 },
v_price_line: { x0: 0, x1: 0, y0: 0, y1: 0 },
}
componentDidMount() {
socket.on("first_connect", (data: FirstConnectData) => {
var last_tick = data.ticks[data.ticks.length - 1]
var last_price = data.prices[data.prices.length - 1]
this.setState({
x: data.ticks,
y: data.prices,
h_price_line: {
x0: 0,
y0: last_price,
x1: last_tick,
y1: last_price
},
v_price_line: {
x0: last_tick,
y0: 0,
x1: last_tick,
y1: last_price
}
})
})
socket.on("new_tick", (data: NewTickData) => {
var new_x = [...this.state.x, data.tick]
var new_y = [...this.state.y, data.price]
// cutting to up to 500 entries (last 500)
var x = new_x.slice(Math.max(new_x.length - 500, 0))
var y = new_y.slice(Math.max(new_y.length - 500, 0))
this.setState({
x: x,
y: y,
h_price_line: {
x0: 0,
y0: data.price,
x1: data.tick,
y1: data.price
},
v_price_line: {
x0: data.tick,
y0: 0,
x1: data.tick,
y1: data.price
}
})
})
}
render() {
return (
<Plot
data={[
{
x: this.state.x,
y: this.state.y,
type: 'scatter',
mode: 'lines+markers',
"marker.colorbar": { tickformat: "r" }
},
]}
layout={{
margin: {
l: 50,
r: 50,
b: 50,
t: 50,
pad: 4
},
dragmode: "pan",
// autosize: true,
shapes: [
{
type: 'line',
x0: this.state.h_price_line.x0,
y0: this.state.h_price_line.y0,
x1: this.state.h_price_line.x1,
y1: this.state.h_price_line.y1,
line: {
color: 'rgb(50, 171, 96)',
width: 2,
dash: 'dashdot'
}
},
],
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;