From f434e396457b10e3245a97ccf37beadf95789151 Mon Sep 17 00:00:00 2001 From: Kamynale <47644905+Kamynale@users.noreply.github.com> Date: Sun, 29 Nov 2020 21:50:29 +0300 Subject: [PATCH 1/3] socket --- server/app.js | 249 +++++++++++++++++++++++++++----- src/views/app/gogo/start.jsx | 269 +++++++---------------------------- 2 files changed, 270 insertions(+), 248 deletions(-) diff --git a/server/app.js b/server/app.js index c7a2cef..683dd22 100644 --- a/server/app.js +++ b/server/app.js @@ -7,12 +7,20 @@ const bodyParser = require('body-parser'); const mysql = require('mysql'); const fs = require('fs'); const path = require('path'); -const params = require('express-route-params'); const config = require('./config'); +const params = require('express-route-params'); +const createStore = require('redux') +const Provider = require('react-redux') +const compression = require('compression'); +const morgan = require('morgan') +const io = require('socket.io')(); + + const app = express(); params(express); + // Define MySQL parameter in Config.js file. const pool = mysql.createPool({ host: config.host, @@ -38,28 +46,46 @@ config.facebook_api_key = '2640133479605924'; // let HOSTNAME = 'https://opexflow.com'; passport.use(new FacebookStrategy({ - clientID: config.facebook_api_key, - clientSecret: config.facebook_api_secret, - callbackURL: config.callback_url, - profileFields: ['id', 'displayName', 'name', 'gender', 'profileUrl', 'emails', 'photos'], -}, -((accessToken, refreshToken, profile, done) => { - process.nextTick(() => { - console.log(profile); - if (profile && profile.id) { - const photo = profile.photos && profile.photos[0] && profile.photos[0].value || ''; - const email = profile.emails && profile.emails[0] && profile.emails[0].value || ''; - - pool.query(`INSERT INTO Users SET - id = '${profile.id}', login = '${profile.displayName}', email = '${email}', photo='${photo}', createdAt = NOW(), balance = 10000 - ON DUPLICATE KEY UPDATE login = '${profile.displayName}', email = '${email}', photo='${photo}' - `); - - profile.accessToken = accessToken; - } - return done(null, profile); - }); -}))); + clientID: config.facebook_api_key, + clientSecret: config.facebook_api_secret, + callbackURL: config.callback_url, + profileFields: ['id', 'displayName', 'name', 'gender', 'profileUrl', 'emails', 'photos'] + }, + ((accessToken, refreshToken, profile, done) => { + process.nextTick(() => { + console.log(profile); + if (profile && profile.id) { + const photo = profile.photos && profile.photos[0] && profile.photos[0].value || ''; + const email = profile.emails && profile.emails[0] && profile.emails[0].value || ''; + + pool.query(`SELECT * from Users where id=${profile.id}`, (err, rows) => { + if (err) throw err; + if (rows && rows.length === 0) { + console.log('There is no such user, adding now'); + pool.query(`INSERT INTO Users SET id = '${profile.id}', login = '${profile.displayName}', email = '${email}', photo='${photo}'`); + } else { + console.log('User already exists in database'); + } + }); + + pool.query(`SELECT * from Transactions where id='${profile.id}'`, (err, rows) => { + if (err) throw err; + if (rows && rows.length === 0) { + console.log('There is no balance User in Transaction, adding now'); + pool.query(`INSERT INTO Transactions SET id = '${profile.id}'`); + } else { + console.log('Balance for User already exists in database'); + } + }); + + profile.accessToken = accessToken; + } + return done(null, profile); + }); + })) +); + + // app.set('views', __dirname + '/views'); // app.set('view engine', 'ejs'); @@ -69,7 +95,7 @@ function replaceHost(host) { } app.use(bodyParser.urlencoded({ extended: false })); -app.use(session({ secret: 'secret123', key: 'sid' })); //, resave: false, saveUninitialized: false })); +app.use(session({ secret: 'secret123', key: 'sid' })); app.use(passport.initialize()); app.use(passport.session()); @@ -94,6 +120,7 @@ app.get('/', (req, res) => { } }); + app.get('/api/account', (req, res) => { res.setHeader('Content-Type', 'application/json'); res.setHeader('Access-Control-Allow-Origin', replaceHost(HOSTNAME)); @@ -106,9 +133,12 @@ app.get('/api/account', (req, res) => { return res.end('{}'); } - pool.query(`SELECT * from Users where id=${req.user.id}`, (err, rows) => { - res.end(JSON.stringify({ user: req.user, finance: { balance: rows && rows[0] && rows[0].balance } })); - }); +/* pool.query(`SELECT user from Users where id=${req.user.id}` , (err, rows) => { + res.end(JSON.stringify({ user: req.user, finance: { balance: rows && rows[0] && rows[0].balance }})); + })*/ + pool.query(`SELECT * from Users,Transactions WHERE Users.id=Transactions.id`, (err, rows) => { + res.end(JSON.stringify({ user: req.user, finance: { balance: rows && rows[0] && rows[0].balance }})); + }) }); app.get('/api/account/:id', (req, res) => { @@ -134,7 +164,8 @@ app.get('/api/logout', (req, res) => { return res.end('{}'); }); -app.param('tick', /^\d+(min|h|d|m)$/i); + +app.param('tick', /^\d+(min|h|d|m)$/i) // ========= Работа с тиками ========== app.get('/api/stocks/ticks/:tick', ensureAuthenticated, (req, res) => { @@ -167,7 +198,8 @@ app.get('/api/stocks/ticks/:tick', ensureAuthenticated, (req, res) => { return res.end(JSON.stringify(ticks)); }); -app.param('price', /^\d+\.?\d*$/i); +app.param('price', /^\d+\.?\d*$/i) + // ========= Работа с тиками ========== app.get('/api/stocks/trades/buy/:price', ensureAuthenticated, (req, res) => { @@ -182,10 +214,59 @@ app.get('/api/stocks/trades/buy/:price', ensureAuthenticated, (req, res) => { return res.end('{}'); } - pool.query(`UPDATE Users SET balance = balance - '${req.params.price}' WHERE id = '${req.user.id}'`); - return res.end(JSON.stringify({})); + const sql = `SELECT balance FROM Transactions WHERE id='${req.user.id}' AND balance>=${req.params.price}`; + const transaction = `UPDATE Transactions SET stock='SBER', commission=0, price=${req.params.price}+commission, balance = balance - price WHERE id='${req.user.id}'` + const logs = `INSERT INTO Transactions_logs(id,balance,price,commission,stock) SELECT id,balance,price,commission,stock FROM Transactions WHERE id='${req.user.id}')` + let a = pool.getConnection(function (err, connection) { + + connection.query(sql, (err, results) => { + if (err) throw err; + if (results && results.length === 0) { + connection.release(); + console.log('Not enough money'); + } else { + connection.beginTransaction(function (err) { + if (err) { //Transaction Error (Rollback and release connection) + connection.rollback(function () { + connection.release(); + console.log('connection is lost') + //Failure + }); + } else { + connection.query(transaction, function (err, results) { + if (err) { //Query Error (Rollback and release connection) + connection.rollback(function () { + connection.release(); + console.log('no money'); + }); + } else { + connection.commit(function (err) { + if (err) { + connection.rollback(function () { + connection.release(); + console.log('lost!'); + }); + } else { + connection.release(); + console.log(`'balance update - '${req.params.price}`); + console.log('success!'); + connection.query(logs, (err, results) => { + console.log('Transactions logs added'); + }); + } + }); + } + }); + } + }); + } + }); + }); + console.log(a) }); + + app.get('/api/stocks/trades/sell/:price', ensureAuthenticated, (req, res) => { // TODO: сделать общее решение для локальной разработки. res.setHeader('Content-Type', 'application/json'); @@ -198,8 +279,55 @@ app.get('/api/stocks/trades/sell/:price', ensureAuthenticated, (req, res) => { return res.end('{}'); } - pool.query(`UPDATE Users SET balance = balance + '${req.params.price}' WHERE id = '${req.user.id}'`); - return res.end(JSON.stringify({})); + const sql = `SELECT balance FROM Transactions WHERE id='${req.user.id}' AND balance>=${req.params.price}`; + const transaction = `UPDATE Transactions SET stock='SBER', commission=0, price=${req.params.price}+commission, balance = balance + price WHERE id='${req.user.id}'` + const logs = `INSERT INTO Transactions_logs(id,balance,price,commission,stock) SELECT id,balance,price,commission,stock FROM Transactions WHERE id='${req.user.id}')` + + pool.getConnection(function (err, connection) { + + connection.query(sql, (err, results) => { + if (err) throw err; + if (results && results.length === 0) { + connection.release(); + console.log('Not enough money'); + } else { + connection.beginTransaction(function (err) { + if (err) { //Transaction Error (Rollback and release connection) + connection.rollback(function () { + connection.release(); + console.log('connection is lost') + //Failure + }); + } else { + connection.query(transaction, function (err, results) { + if (err) { //Query Error (Rollback and release connection) + connection.rollback(function () { + connection.release(); + console.log('no money'); + }); + } else { + connection.commit(function (err) { + if (err) { + connection.rollback(function () { + connection.release(); + console.log('lost!'); + }); + } else { + connection.release(); + console.log(`'balance update + '${req.params.price}`); + console.log('success!'); + connection.query(logs, (err, results) => { + console.log('Transactions logs added'); + }); + } + }); + } + }); + } + }); + } + }); + }); }); function ensureAuthenticated(req, res, next) { @@ -208,4 +336,59 @@ function ensureAuthenticated(req, res, next) { return next(); } +/* +// SSR + +app.use(compression()); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(morgan('dev')); +app.use(cookieParser()); + +// Set up homepage, static assets, and capture everything else +app.use(express.Router().get('/exchangerate')); +app.use(express.static(path.resolve(__dirname, '../build'))); + + +// We tell React Loadable to load all required assets and start listening - ROCK AND ROLL! +Loadable.preloadAll().then(() => { + app.listen(PORT, console.log(`App listening on port ${PORT}!`)); +}); + +// Handle the bugs somehow +app.on('error', error => { + if (error.syscall !== 'listen') { + throw error; + } + + const bind = typeof PORT === 'string' ? 'Pipe ' + PORT : 'Port ' + PORT; + + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +}); +*/ + +//socket.io +io.sockets.on('connection', function (socket) { + io.sockets.emit('getting_data', 'Loading Data for chart'); + setInterval(5000,function(data){ + let q = "SELECT * FROM stock"; + connection.query(q, function(err, rows) { + if (err) throw err; + res.end(JSON.stringify(rows)) + }); + }); +}); + + app.listen(3001); diff --git a/src/views/app/gogo/start.jsx b/src/views/app/gogo/start.jsx index 248eeb9..6763b05 100644 --- a/src/views/app/gogo/start.jsx +++ b/src/views/app/gogo/start.jsx @@ -1,237 +1,74 @@ import React, { PureComponent } from 'react'; import { Row, Button } from 'reactstrap'; -import Chart from 'react-apexcharts'; -import ApexCharts from 'apexcharts'; -import IntlMessages from '../../../helpers/IntlMessages'; import { Colxx, Separator } from '../../../components/common/CustomBootstrap'; -import Breadcrumb from '../../../containers/navs/Breadcrumb'; +import Chart from 'kaktana-react-lightweight-charts' +import io from "socket.io-client" -export default class Start extends PureComponent { + + +export default class Start extends PureComponent { constructor(props) { super(props); this.state = { - series: [{ - data: [], - }], options: { - chart: { - id: 'ticks_chart', - type: 'candlestick', - height: 350, - }, - title: { - text: 'CandleStick Chart', - align: 'left', - }, - xaxis: { - // type: 'datetime', - type: 'numeric' - }, - yaxis: { - tooltip: { - enabled: true, - }, - }, + alignLabels: true, + timeScale: { + rightOffset: 12, + barSpacing: 3, + fixLeftEdge: true, + lockVisibleTimeRangeOnResize: true, + rightBarStaysOnScroll: true, + borderVisible: true, + borderColor: "#fff000", + visible: true, + timeVisible: true, + secondsVisible: false + } }, - // Берём данные из LS, чтобы при возврате рисовался интересующий график. - currentTicks: window.localStorage.getItem('ticks') || '5min', - }; - } - - // lastDate = 1538884800000 - // [Timestamp, O, H, L, C] - // lastTick = [6604.98, 6606, 6604.07, 6606] - - componentDidMount() { - this.getChartData(); - } - - componentDidUpdate() { - if(!this.state.interactive) { - this.getChartData(); - this.interval && window.clearInterval(this.interval); - } else { - if (!this.interval) { - this.interval = window.setInterval(() => { - const dataBuff = this.state.dataBuff.slice(0); - const data = this.state.series[0].data.slice(0); - let nextData; - - if (this.state.dataBuff.length) { - nextData = dataBuff.shift(); - data.push(nextData); - - this.setState({ - dataBuff, - series: [{ - data - }] - }); - } else { - window.clearInterval(this.interval); - } - }, 250); - } - } - - if (this.state.series[0].data && this.state.series[0].data.length) { - ApexCharts.exec('ticks_chart', 'render', [{ - data: this.state.series[0].data - }]) + candlestickSeries: [{ + data: [ + { time: '2018-10-19', open: 180.34, high: 180.99, low: 178.57, close: 179.85 }, + { time: '2018-10-22', open: 180.82, high: 181.40, low: 177.56, close: 178.75 }, + { time: '2018-10-23', open: 175.77, high: 179.49, low: 175.44, close: 178.53 }, + { time: '2018-10-24', open: 178.58, high: 182.37, low: 176.31, close: 176.97 }, + { time: '2018-10-25', open: 177.52, high: 180.50, low: 176.83, close: 179.07 }, + { time: '2018-10-26', open: 176.88, high: 177.34, low: 170.91, close: 172.23 }, + { time: '2018-10-29', open: 173.74, high: 175.99, low: 170.95, close: 173.20 }, + { time: '2018-10-30', open: 173.16, high: 176.43, low: 172.64, close: 176.24 }, + { time: '2018-10-31', open: 177.98, high: 178.85, low: 175.59, close: 175.88 }, + { time: '2020-11-01', open: 176.84, high: 180.86, low: 175.90, close: 180.46 }, + { time: '2020-11-02', open: 182.47, high: 183.01, low: 177.39, close: 179.93 }, + { time: '2018-10-19', open: 180.34, high: 180.99, low: 178.57, close: 179.85 }, + { time: '2018-10-22', open: 180.82, high: 181.40, low: 177.56, close: 178.75 }, + { time: '2018-10-23', open: 175.77, high: 179.49, low: 175.44, close: 178.53 }, + { time: '2018-10-24', open: 178.58, high: 182.37, low: 176.31, close: 176.97 }, + { time: '2018-10-25', open: 177.52, high: 180.50, low: 176.83, close: 179.07 }, + { time: '2018-10-26', open: 176.88, high: 177.34, low: 170.91, close: 172.23 }, + { time: '2018-10-29', open: 173.74, high: 175.99, low: 170.95, close: 173.20 }, + { time: '2018-10-30', open: 173.16, high: 176.43, low: 172.64, close: 176.24 }, + { time: '2018-10-31', open: 177.98, high: 178.85, low: 175.59, close: 175.88 }, + { time: '2020-11-01', open: 176.84, high: 180.86, low: 175.90, close: 180.46 }, + { time: '2020-11-02', open: 182.47, high: 183.01, low: 177.39, close: 179.93 }, + { time: '2020-11-05', open: 181.02, high: 182.41, low: 179.30, close: 182.19 } + ] + }] } } - - getHost(postfix) { - // Костыль для локальной разработки, чтобы порты сервера и клиента разнести. - // TODO: сделать в едином месте - let host = `https://${window.location.host}/api/stocks/${postfix}`; - if (host.indexOf('3000') !== -1) { - // TODO: сделать в едином месте - host = host.replace('3000', '3001').replace('https', 'http'); - } - - return host; - } - - getChartData() { - this.loadedData || (this.loadedData = {}); - const current = this.loadedData[this.state.currentTicks]; - if (this.loadedData[this.state.currentTicks] === true) { - return; - } else if (current) { - ApexCharts.exec('ticks_chart', 'updateSeries', [{ - data: this.loadedData[this.state.currentTicks].series[0].data, - }]); - this.setState(this.loadedData[this.state.currentTicks]); - return; - } else { - this.loadedData[this.state.currentTicks] = true; - } - - /* - { - x: new Date(1538874000000), - y: [6600.55, 6605, 6589.14, 6593.01], - }, - */ - const x = new XMLHttpRequest(); - x.open('GET', this.getHost(`ticks/${this.state.currentTicks}`), true); - x.onload = () => { - const res = x.responseText && JSON.parse(x.responseText); - - const series = this.state.series.slice(0); - let name; - - series[0].data = !res || !Object.keys(res).length ? [] : res.map((t, i) => { - // ticker, per, date, time, open, hight, low, close, vol (объём торгов) - // SBER,5,08/07/20,12:30:00,210.6100000,210.6800000,210.4700000,210.6000000,73370 - const tick = t.split(','); - - if (!name) { - name = tick[0]; - } - - if (!tick[2] || !tick[3]) { - return; - } - - // console.log(`${tick[2]} ${tick[3]}`, [parseFloat(tick[4]), parseFloat(tick[5]), parseFloat(tick[6]), parseFloat(tick[7])]); - // [Timestamp, O, H, L, C] - return { - x: `${tick[2]} ${tick[3]}`, - y: [parseFloat(tick[4]), parseFloat(tick[5]), parseFloat(tick[6]), parseFloat(tick[7])], - - }; - }) - .filter(Boolean); - - this.loadedData[this.state.currentTicks] = { - series, - options: { - ...this.state.options, - title: { - ...this.state.options.title, - text: name, - }, - }, - }; - - this.setState(this.loadedData[this.state.currentTicks]); - - ApexCharts.exec('ticks_chart', 'updateSeries', [{ - data: series[0].data, - }]); - }; - x.withCredentials = true; - x.send(); + componentDidMount(){ + let socket = io.connect("https://localhost:3000"); + console.log(socket) + socket.on("getting_data", function(data) { + console.log(data); + }) } render() { return ( <> - - - {this.props.match && } - - - - - -

- {[ - // '1min', - '5min', - '10min', - ].map((t, i) => - - )} - -
-
- {Boolean(this.state.series[0].data.length) && ( - - )} + @@ -261,6 +98,8 @@ export default class Start extends PureComponent { x.open('GET', this.getHost(`trades/sell/${price}`), true); x.withCredentials = true; x.send(); + + console.log('sell', price); }} size="lg" > From fb37190c811b523ff8ad07c9258ddbbb364c8bfa Mon Sep 17 00:00:00 2001 From: Kamynale <47644905+Kamynale@users.noreply.github.com> Date: Tue, 1 Dec 2020 11:33:12 +0300 Subject: [PATCH 2/3] socket with comments --- .gitignore | 3 + package-lock.json | 311 ++++++++++++++++++++++++++++++++++++ package.json | 6 +- server/app.js | 29 ++-- src/views/app/bots/sber.jsx | 12 ++ 5 files changed, 348 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 3e7fc92..3ebc440 100644 --- a/.gitignore +++ b/.gitignore @@ -105,4 +105,7 @@ dist .DS_Store +.idea/ +.idea + build diff --git a/package-lock.json b/package-lock.json index 5a7cf22..00c6fb5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2376,6 +2376,15 @@ "@babel/types": "^7.3.0" } }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, "@types/classnames": { "version": "2.2.10", "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.10.tgz", @@ -2386,11 +2395,58 @@ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, + "@types/component-emitter": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", + "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==" + }, + "@types/connect": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", + "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==", + "requires": { + "@types/node": "*" + } + }, + "@types/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==" + }, + "@types/cors": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.8.tgz", + "integrity": "sha512-fO3gf3DxU2Trcbr75O7obVndW/X5k8rJNZkLXlQWStTHhP71PkRqjwPIEI0yMnJdg9R9OasjU+Bsr+Hr1xy/0w==", + "requires": { + "@types/express": "*" + } + }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==" }, + "@types/express": { + "version": "4.17.9", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.9.tgz", + "integrity": "sha512-SDzEIZInC4sivGIFY4Sz1GG6J9UObPwCInYJjko2jzOf/Imx/dlpume6Xxwj1ORL82tBbmN4cPDIDkLbWHk9hw==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.14.tgz", + "integrity": "sha512-uFTLwu94TfUFMToXNgRZikwPuZdOtDgs3syBtAIr/OXorL1kJqUJT9qCLnRZ5KBOWfZQikQ2xKgR2tnDj1OgDA==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", @@ -2442,6 +2498,11 @@ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, + "@types/mime": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz", + "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==" + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -2493,6 +2554,11 @@ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, + "@types/qs": { + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", + "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==" + }, "@types/quill": { "version": "1.3.10", "resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz", @@ -2501,6 +2567,11 @@ "parchment": "^1.1.2" } }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, "@types/react": { "version": "16.9.38", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.38.tgz", @@ -2523,6 +2594,15 @@ "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.27.tgz", "integrity": "sha1-nbVjk33YaRX2kJK8QyWdL0hXjkE=" }, + "@types/serve-static": { + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.8.tgz", + "integrity": "sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA==", + "requires": { + "@types/mime": "*", + "@types/node": "*" + } + }, "@types/sortablejs": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.10.4.tgz", @@ -5130,6 +5210,11 @@ "lodash.clone": "^4.5.0" } }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -5190,11 +5275,21 @@ } } }, + "base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" + }, "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, "base64url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", @@ -6283,6 +6378,11 @@ "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", "dev": true }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -6607,6 +6707,15 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", @@ -7884,6 +7993,87 @@ "once": "^1.4.0" } }, + "engine.io": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.0.4.tgz", + "integrity": "sha512-4ggUX5pICZU17OTZNFv5+uFE/ZyoK+TIXv2SvxWWX8lwStllQ6Lvvs4lDBqvKpV9EYXNcvlNOcjKChd/mo+8Tw==", + "requires": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.1.0", + "engine.io-parser": "~4.0.0", + "ws": "^7.1.2" + }, + "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "ws": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz", + "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==" + } + } + }, + "engine.io-client": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-4.0.4.tgz", + "integrity": "sha512-and4JRvjv+BQ4WBLopYUFePxju3ms3aBRk0XjaLdh/t9TKv2LCKtKKWFRoRzIfUZsu3U38FcYqNLuXhfS16vqw==", + "requires": { + "base64-arraybuffer": "0.1.4", + "component-emitter": "~1.3.0", + "debug": "~4.1.0", + "engine.io-parser": "~4.0.1", + "has-cors": "1.1.0", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.2.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "ws": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.5.tgz", + "integrity": "sha512-C34cIU4+DB2vMyAbmEKossWq2ZQDr6QEyuuCzWrM9zfw1sGc0mYiJ0UnG9zzNykt49C2Fi34hvr2vssFQRS6EA==" + } + } + }, + "engine.io-parser": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.1.tgz", + "integrity": "sha512-v5aZK1hlckcJDGmHz3W8xvI3NUHYc9t8QtTbqdR5OaH3S9iJZilPubauOm+vLWOMMWzpE3hiq92l9lTAHamRCg==" + }, "enhanced-resolve": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz", @@ -9940,6 +10130,11 @@ "ansi-regex": "^2.0.0" } }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -14833,6 +15028,16 @@ "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" }, + "parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -19108,6 +19313,102 @@ "kind-of": "^3.2.0" } }, + "socket.io": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.0.3.tgz", + "integrity": "sha512-TC1GnSXhDVmd3bHji5aG7AgWB8UL7E6quACbKra8uFXBqlMwEDbrJFK+tjuIY5Pe9N0L+MAPPDv3pycnn0000A==", + "requires": { + "@types/cookie": "^0.4.0", + "@types/cors": "^2.8.8", + "@types/node": "^14.14.7", + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.1.0", + "engine.io": "~4.0.0", + "socket.io-adapter": "~2.0.3", + "socket.io-parser": "~4.0.1" + }, + "dependencies": { + "@types/node": { + "version": "14.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz", + "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "socket.io-adapter": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.0.3.tgz", + "integrity": "sha512-2wo4EXgxOGSFueqvHAdnmi5JLZzWqMArjuP4nqC26AtLh5PoCPsaRbRdah2xhcwTAMooZfjYiNVNkkmmSMaxOQ==" + }, + "socket.io-client": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-3.0.3.tgz", + "integrity": "sha512-kwCJAKb6JMqE9ZYXg78Dgt8rYLSwtJ/g/LJqpb/pOTFRZMSr1cKAsCaisHZ+IBwKHBY7DYOOkjtkHqseY3ZLpw==", + "requires": { + "@types/component-emitter": "^1.2.10", + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~4.1.0", + "engine.io-client": "~4.0.0", + "parseuri": "0.0.6", + "socket.io-parser": "~4.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "socket.io-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.2.tgz", + "integrity": "sha512-Bs3IYHDivwf+bAAuW/8xwJgIiBNtlvnjYRc4PbXgniLmcP1BrakBoq/QhO24rgtgW7VZ7uAaswRGxutUnlAK7g==", + "requires": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.1.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "sockjs": { "version": "0.3.19", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", @@ -22198,6 +22499,11 @@ "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, "xregexp": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", @@ -22544,6 +22850,11 @@ } } }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, "yup": { "version": "0.29.1", "resolved": "https://registry.npmjs.org/yup/-/yup-0.29.1.tgz", diff --git a/package.json b/package.json index 90e092d..6f4e501 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,8 @@ "sequelize": "^6.2.4", "sequelize-cli": "^6.1.0", "shelljs": "^0.8.4", + "socket.io": "^3.0.3", + "socket.io-client": "^3.0.3", "sortablejs": "^1.10.2", "tmp": "^0.2.1", "video.js": "^7.8.4", @@ -87,12 +89,12 @@ "yup": "^0.29.1" }, "scripts": { - "start": "react-scripts start", + "start": "set HTTPS=true&&react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "server": "nodemon server/app", - "dev": "HTTPS=true concurrently \"npm run server\" \"npm run start\"", + "dev": "concurrently \"npm run server\" \"npm run start\"", "lint": "eslint --debug src/", "lint:write": "eslint --debug src/ --fix", "precommit": "lint-staged" diff --git a/server/app.js b/server/app.js index 683dd22..bc5c45a 100644 --- a/server/app.js +++ b/server/app.js @@ -12,8 +12,7 @@ const params = require('express-route-params'); const createStore = require('redux') const Provider = require('react-redux') const compression = require('compression'); -const morgan = require('morgan') -const io = require('socket.io')(); + @@ -379,16 +378,24 @@ app.on('error', error => { */ //socket.io -io.sockets.on('connection', function (socket) { - io.sockets.emit('getting_data', 'Loading Data for chart'); - setInterval(5000,function(data){ - let q = "SELECT * FROM stock"; - connection.query(q, function(err, rows) { - if (err) throw err; - res.end(JSON.stringify(rows)) +let server = app.listen(3001); +const io = require('socket.io')(server); + +// Подключение клиента +io.on('connection', function (socket) { + const { id } = socket.client; + console.log(`User connected: ${id}`); + setInterval(5000, function (data) { + // Подключение к Mysql, с выбором всех данных из таблицы stock + let q ="SELECT * FROM stock"; + connection.query(q, function (err, rows) { + if (err) throw err; + console.log(rows) + // отправление данных на клиент + io.emit('showrows', rows); + }); }); }); -}); -app.listen(3001); + diff --git a/src/views/app/bots/sber.jsx b/src/views/app/bots/sber.jsx index c9e7791..fb15c02 100644 --- a/src/views/app/bots/sber.jsx +++ b/src/views/app/bots/sber.jsx @@ -11,6 +11,7 @@ import * as tf from '@tensorflow/tfjs'; import { TradeGameAgent } from './sber/trade_agent'; import { TradeGame, NUM_ACTIONS, ALL_ACTIONS, getStateTensor } from './sber/trade_game'; +import io from "socket.io-client"; let game; let qNet; @@ -151,6 +152,17 @@ export default class Sber extends Component { // lastTick = [6604.98, 6606, 6604.07, 6606] componentDidMount() { + // Переменные для подключение к серверу + let socket = io.connect("http://localhost:3002"); + console.log(socket) + // Подключение к серверу socket + socket.on('connection', function(data){ + console.log('connected', data) + }) + // Вывод массива даты + socket.on('showrows', function(rows) { + console.log(rows); + }) this.getChartData(); this.resetState(); } From 6d56fa55cd67f35b217c4e2dc0e08be33aafb01a Mon Sep 17 00:00:00 2001 From: Kamynale <47644905+Kamynale@users.noreply.github.com> Date: Thu, 3 Dec 2020 15:13:59 +0300 Subject: [PATCH 3/3] chart --- server/app.js | 13 +- src/views/app/bots/sber.jsx | 271 +++++++++++++----------------------- 2 files changed, 106 insertions(+), 178 deletions(-) diff --git a/server/app.js b/server/app.js index bc5c45a..0c1bfe9 100644 --- a/server/app.js +++ b/server/app.js @@ -379,22 +379,27 @@ app.on('error', error => { //socket.io let server = app.listen(3001); -const io = require('socket.io')(server); +const io = require('socket.io')(server, { + path: '/test', + cors: { + origin: '*', + } +}); // Подключение клиента io.on('connection', function (socket) { const { id } = socket.client; console.log(`User connected: ${id}`); - setInterval(5000, function (data) { +/* setInterval( function (data) {*/ // Подключение к Mysql, с выбором всех данных из таблицы stock let q ="SELECT * FROM stock"; - connection.query(q, function (err, rows) { + pool.query(q, function (err, rows) { if (err) throw err; console.log(rows) // отправление данных на клиент io.emit('showrows', rows); }); - }); +/* },5000);*/ }); diff --git a/src/views/app/bots/sber.jsx b/src/views/app/bots/sber.jsx index fb15c02..c51a0d8 100644 --- a/src/views/app/bots/sber.jsx +++ b/src/views/app/bots/sber.jsx @@ -1,7 +1,5 @@ import React, { Component } from 'react'; import { Row, Button } from 'reactstrap'; -import Chart from 'react-apexcharts'; -import ApexCharts from 'apexcharts'; import { Colxx, Separator } from '../../../components/common/CustomBootstrap'; import Breadcrumb from '../../../containers/navs/Breadcrumb'; import IconCard from '../../../components/cards/IconCard'; @@ -11,7 +9,9 @@ import * as tf from '@tensorflow/tfjs'; import { TradeGameAgent } from './sber/trade_agent'; import { TradeGame, NUM_ACTIONS, ALL_ACTIONS, getStateTensor } from './sber/trade_game'; +import Chart from 'kaktana-react-lightweight-charts' import io from "socket.io-client"; +import {replace} from "formik"; let game; let qNet; @@ -101,171 +101,99 @@ export default class Sber extends Component { super(props); this.state = { - balance: 10000, - stocks: 0, - maxBuyStocks: 40, - lastStockPrice: 0, - commission: 0.05, - logs: [], - - series: [{ - data: [], - }], - options: { - chart: { - id: 'ticks_chart', - type: 'candlestick', - height: 350, - }, - title: { - text: 'CandleStick Chart', - align: 'left', - }, - xaxis: { - // type: 'datetime', - type: 'numeric' - }, - yaxis: { - tooltip: { - enabled: true, + balance: 10000, + stocks: 0, + maxBuyStocks: 40, + lastStockPrice: 0, + commission: 0.05, + logs: [], + + series: [{ + data: [], + }], +/* options: { + chart: { + id: 'ticks_chart', + type: 'candlestick', + height: 350, + }, + title: { + text: 'CandleStick Chart', + align: 'left', }, - }, + xaxis: { + // type: 'datetime', + type: 'numeric' + }, + yaxis: { + tooltip: { + enabled: true, + }, + }, + },*/ + // Берём данные из LS, чтобы при возврате рисовался интересующий график. + currentTicks: window.localStorage.getItem('ticks') || '5min', + //Начало настроек для нового графика + options: { + alignLabels: true, + timeScale: { + rightOffset: 12, + barSpacing: 3, + fixLeftEdge: true, + lockVisibleTimeRangeOnResize: true, + rightBarStaysOnScroll: true, + borderVisible: true, + borderColor: "#fff000", + visible: true, + timeVisible: true, + secondsVisible: false + } }, - // Берём данные из LS, чтобы при возврате рисовался интересующий график. - currentTicks: window.localStorage.getItem('ticks') || '5min', - }; - } - - resetState() { - this.setState({ - balance: 10000, - stocks: 0, - maxBuyStocks: 40, - lastStockPrice: 0, - commission: 0.05, - logs: [], - }); - } - - // lastDate = 1538884800000 - // [Timestamp, O, H, L, C] - // lastTick = [6604.98, 6606, 6604.07, 6606] - - componentDidMount() { - // Переменные для подключение к серверу - let socket = io.connect("http://localhost:3002"); - console.log(socket) - // Подключение к серверу socket - socket.on('connection', function(data){ - console.log('connected', data) - }) - // Вывод массива даты - socket.on('showrows', function(rows) { - console.log(rows); - }) - this.getChartData(); - this.resetState(); - } - - componentDidUpdate() { - if(!this.state.interactive) { - // this.getChartData(); + // Дата для нового графика из mysql + candlestickSeries: [{ + data: [ +/* { time: '', open: '', high: '', low: '', close: '' }*/ + ] + }] } } - getHost(postfix) { - // Костыль для локальной разработки, чтобы порты сервера и клиента разнести. - // TODO: сделать в едином месте - let host = `https://${window.location.host}/api/stocks/${postfix}`; - if (host.indexOf('3000') !== -1) { - // TODO: сделать в едином месте - host = host.replace('3000', '3001').replace('https', 'http'); - } - - return host; - } - - getChartData() { - this.loadedData || (this.loadedData = {}); - const current = this.loadedData[this.state.currentTicks]; - if (this.loadedData[this.state.currentTicks] === true) { - return; - } else if (current) { - ApexCharts.exec('ticks_chart', 'updateSeries', [{ - data: this.loadedData[this.state.currentTicks].series[0].data, - }]); - this.setState(this.loadedData[this.state.currentTicks]); - return; - } else { - this.loadedData[this.state.currentTicks] = true; - } - - /* - { - x: new Date(1538874000000), - y: [6600.55, 6605, 6589.14, 6593.01], - }, - */ - const x = new XMLHttpRequest(); - x.open('GET', this.getHost(`ticks/${this.state.currentTicks}`), true); - x.onload = () => { - const res = x.responseText && JSON.parse(x.responseText); - - const series = this.state.series.slice(0); - let name; - - series[0].data = !res || !Object.keys(res).length ? [] : res.map((t, i) => { - // ticker, per, date, time, open, hight, low, close, vol (объём торгов) - // SBER,5,08/07/20,12:30:00,210.6100000,210.6800000,210.4700000,210.6000000,73370 - const tick = t.split(','); - - if (!name) { - name = tick[0]; - } - - if (!tick[2] || !tick[3]) { - return false; - } - - // console.log(`${tick[2]} ${tick[3]}`, [parseFloat(tick[4]), parseFloat(tick[5]), parseFloat(tick[6]), parseFloat(tick[7])]); - // [Timestamp, O, H, L, C] - return { - x: `${tick[2]} ${tick[3]}`, - y: [parseFloat(tick[4]), parseFloat(tick[5]), parseFloat(tick[6]), parseFloat(tick[7])], - - }; + componentDidMount() { + // Переменные для подключение к серверу + let socket = io.connect("http://localhost:3001", { + path: '/test' + }); + console.log(socket) + // Подключение к серверу socket + socket.on('connection', function(data){ + console.log('connected', data) }) - .filter(Boolean); - - this.loadedData[this.state.currentTicks] = { - series, - options: { - ...this.state.options, - title: { - ...this.state.options.title, - text: name, - }, - }, - stocksData: res.map(r => { - const tick = r.split(','); - if (!tick[2] || !tick[3]) { - return false; - } - - // SBER,5,08/07/20,12:30:00,210.6100000,210.6800000,210.4700000,210.6000000,73370 - // Для упрощения наблюдений увеличиваем стоимость акций, чтобы следить за целыми числами - return [tick[2] + ' ' + tick[3], parseInt(tick[5] * 10, 10), tick[8]]; - }).filter(Boolean) - }; - - this.setState(this.loadedData[this.state.currentTicks]); - - // ApexCharts.exec('ticks_chart', 'updateSeries', [{ - // data: series[0].data, - // }]); - }; - x.withCredentials = true; - x.send(); + // Вывод массива даты и перебор из mysql + socket.on('showrows', function(rows) { + let arrRows = JSON.stringify(rows) + console.log(arrRows) + arrRows.split("},").forEach(function (line) { + const arr = line.toString().split(',') + console.log(arr) + const vol = arr.map(elem => elem.trim()); +/* console.log(vol[3], vol[5], vol[6], vol[7], vol[8]);*/ + let dataChart = vol[3]+' '+vol[5]+' '+vol[6]+' '+vol[7]+' '+vol[8] + //чистил и преобразовал массив + let arrTick = dataChart.replace('"date":"', '').replace('Z"', 'Z').replace('"open":', '').replace('"high":', '').replace('"low":', '').replace('"close":', '').split(' '); + console.log(arrTick) + let d = {time:arrTick[0],open:arrTick[1],high:arrTick[2],low:arrTick[3],close:arrTick[4]} + console.log(d) + this.setState.candlestickSeries({data:d}) + /*this.setState.candlestickSeries.data({time:arrTick[0],open:arrTick[1],high:arrTick[2],low:arrTick[3],close:arrTick[4]})*/ + }) + +/* rows.forEach(function (line) { + const arr = line.toString().split(',') + console.log(arr) + const vol = arr.map(elem => elem.trim()); + console.log(vol[8]) + })*/ + }) } render() { @@ -278,8 +206,8 @@ export default class Sber extends Component { {this.props.match && } - - + + {/*

@@ -304,19 +232,12 @@ export default class Sber extends Component { )}
*/}
+{/* Рендер чарта*/} - {Boolean(this.state.series[0].data.length) && ( - - )} - - - + + +