import React, {Component} from "react" import Plot from "react-plotly.js" import {socket} from '../'; import {EventName, NewTickMessage} from "../types"; 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(EventName.FirstConnect, (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(EventName.NewTick, (data: NewTickMessage) => { 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((state) => ({ x: state.x.concat(data.tick), y: state.y.concat(data.price), 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: 110, r: 20, b: 100, t: 20, 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: '100%'}} /> ) } } export default RPlot;