公司項目主要是作股票及期貨行情展現及交易,h5相應的作了一些功能---能夠看行情圖及模擬交易,實盤交易存在必定的風險,老闆但願作本身的產品,這樣h5就尷尬了,不過不要緊,項目裏仍是有必定技術含量的---①設計到不少合約品種,場景多及複雜②設計一些功能模塊的同時,後臺沒之前牛氣了,此次須要他們的積極配合了(很感謝他們,主要是一些接口的配合),③涉及到大量的數據傳輸及緩存,④react組件與多組件配合使用(react+router+webpack+highstock+mobx)。下面圖片能夠說明上述幾點問題:javascript
廢話很少說,問題以下:css
一,官網的react-app腳手架 不支持ES7@裝飾器 ,數據層須要用extendObservable 封裝。須要用到數據的地方用inject包裝獲取下,代碼以下(顏色字體):html
//實時交易狀態管理組件
import {extendObservable,observable, action} from 'mobx';// 官網的create_app 不支持es7的@裝飾器 用extendObservable代替。
import UrlP from 'api/api';
import HttpP from "mixin/httpPub";
const Store = function(){
extendObservable(this, {//this指的就是 mobx Store
contractName:observable(""),//合約名字
/*歷史訂單*/
historyOrder:action(function(){
HttpP.NN_historyOrderP({data}).then(
(res)=>{
if(!res.result){
alert(res.message);
}else{
console.log(res)
if (res.result) {
。。。。。
}
}
}
);
}),
})
}
const traderStore = new Store();
export default traderStore;
上面是全局數據層,下面是獲取數據dom層。前端
// 策略頁面 import React, { Component } from 'react'; import './index.css'; import pubFn from "mixin/pubFn.js";//公共函數 import {Link,withRouter} from "react-router-dom"; import {observer,inject} from 'mobx-react';//mobx管裏頁面 能夠inject爲父級傳過來的props const DifOrderList = inject("traderStore")(observer(class DifOrderList extends Component { constructor(props) { super(props); this.state = { }; } componentDidMount () { } /*點擊切換持倉 歷史 */ typeClick (event) {/*請求訂單歷史數據*/this.props.traderStore.historyOrder(); } render() {//列表的數量 來判斷 合計dom 定位的位置 let style = { top:1.06*arrL+"rem", left:"0", } return ( <div className="difOrderList"> <ul className = "clearfix difOrderListTop"> { this.state.arrTypeChange.map( (Hname,index) => <li className = {Hname.clName} onClick = {this.typeClick.bind(this)} data-type = {Hname.type} key = {index}>{Hname.html}</li> ) } </ul> <ul className = "clearfix difOrderListPro"> { this.state.listA.map( (Hname,index) => <li className = "fl" style = {this.state.styleH} key = {index}>{Hname}</li> ) } </ul> </div> ); } })); export default withRouter(DifOrderList);
二,數據緩存如何去作?java
合約列表在每次點擊後,二次點擊不須要再去後臺請求歷史數據,一是由於數據量大,二是由於不斷請求大量數據,給後臺增長好多壓力,這樣就不得不要求前端在數據層上作一下緩存,首先想到的就是localstorage。可是不一樣合約有不一樣分時圖,不一樣k線圖,因此數據儲存是一個至關棘手的問題。react
function FArr() {//三維數組 for (var i = 0; i < 4; i++) { publicArr.push([]); } for (var i = 0; i < 4; i++) { for (var j = 0; j < 8; j++) { publicArr[i].push([]); } } for (var i = 0; i < 4; i++) { for (var j = 0; j < 8; j++) { for (var p = 0; p < 6; p++) { publicArr[i][j].push([]); } } } }
想來想去,用了一個三維數組在本地存儲數據,即:合約 k線類型 k線數據。可是在存儲的時候,其實用的是合約信息做爲屬性來切換數組下標的以此存儲不一樣的數據及對應不一樣的名稱: webpack
// 三維數組建立參數
var publicArr = [];
var M1 = 0,
M3 = 1,
M5 = 2,
M15 = 3,
M30 = 4,
H1 = 5,
D1 = 6,
M50 = 7;
var CL = 0,
GC = 1,
FDAX = 2,
HSI = 3;
var OP = 0,
HI = 1,
LO = 2,
CLO = 3,
VOL = 4,
Time = 5;web
根據點擊的合約,判斷對應的下標。api
publicArr[typeName][cNewNum][CLO].push(data.close);
publicArr[typeName][cNewNum][OP].push(data.open);
publicArr[typeName][cNewNum][HI].push(data.high);
publicArr[typeName][cNewNum][LO].push(data.low);
publicArr[typeName][cNewNum][Time].push(data.time);
publicArr[typeName][cNewNum][VOL].push(data.volume);數組
可是那麼多合約總不能用戶點擊一個存儲一個,每每這裏須要跟後臺配合,根據用戶習慣及產品需求,前端根據後臺字段來判斷要不要緩存此數據。
三,不合理寫法:不要在render裏直接把全局的數據拿來進行渲染(粉色字體),應該按藍色字體進行修改,
render() {
let ask = this.props.liveStore.handicapNavListObj.ask;
let bid = this.props.liveStore.handicapNavListObj.bid;
return ( <div className="futuresChangeNum clearfix"> <div className = "changeNumTop clearfix"> <div className = "fl clearfix changeNumTopLeft"> <div className = "clearfix changeNumTopLeftTop"> <i className = "fl"></i> <input className = "fl" value={this.props.liveStore.handicapNavListObj.key.contractKey} type="text" onChange = {this.contractNameChange.bind(this)}/> <b className = "fl"></b> </div> <div className = "clearfix changeNumTopLeftBot"> <div className = "fl clearfix changeNumTopLeftBotLeft"> <p className = "fl">手數</p> <h4 className = "fl">{this.state.num}</h4> </div> <div className = "fl clearfix changeNumTopLeftBotRight"> <p className = "fl">價格</p> <h4 className = "fl">{this.state.traderPricetype}</h4> </div> </div> </div> <div className = "fl changeNumTopRight"> <ul> <li className = "clearfix"> <span className = "fl">新</span> <h3 className = "fl">{this.props.liveStore.handicapNavListObj.lastPrice}</h3> <strong className = "fl">{this.props.liveStore.handicapNavListObj.volume}</strong> </li> <li className = "clearfix" > <span className = "fl">賣</span> <h3 className = "fl">{bid}</h3> <strong className = "fl">{this.props.liveStore.handicapNavListObj.bidSize}</strong> </li> <li className = "clearfix"> <span className = "fl">買</span> <h3 className = "fl">{ask}</h3> <strong className = "fl">{this.props.liveStore.handicapNavListObj.askSize}</strong> </li> </ul> </div> </div> </div> ); }
四,在項目裏好多地方須要切換畫圖,無論橫屏簡單展現仍是豎屏技術指標數據展現,都須要第三方插件highstock拿來畫圖,也就是須要把此插件接口暴露在全局,把highstock封裝了一個函數,用extendObservable給暴露在了全局
//第三方畫圖插件 highstock import Highcharts from 'highcharts/highstock'; import {extendObservable,observable, action, computed, useStrict} from 'mobx';// 官網的create_app 不支持es7的@裝飾器 用extendObservable代替。 var linecolor = "#000"; //x y軸線或刻度線的顏色值 var linecolor1 = "#2f84cc"; //k線圖的顏色 var bgcolor = "#20212a"; //表格背景的顏色 Highcharts.setOptions({ global: { //設置爲中國時間 useUTC: false }, lang:{ rangeSelectorZoom:"" } }); const ChartHcStore = function(){ extendObservable(this, {//this指的就是 mobox Store chartsetK:observable({}), isClickHc:action(function(id,time,data,weekflg,mk){ this.chartsetK = new Highcharts.StockChart(id, { chart: { }, tooltip:weekflg == 'MK' ? { }, //數據提示框。 credits: { // 網站標識 enabled: false //去版權 }, navigator: { // 底部導航內容 enabled: false }, scrollbar: { enabled: false }, }), }) } const chartHcStore = new ChartHcStore(); export default chartHcStore;
五,k線展現時間問題:股票後臺過來的數據因爲時間存在不連續問題,致使前端在畫圖的時候 出現不連續,不均勻的k線圖,爲了使x軸連續性前端根據請求來的數據個數,自行往數據數組裏添加連續的時間,可是就會存在用戶在查看每條k線的時候,時間不正確,因此在tooltip裏面,再把正確的時間給顯示出來便可。
data5MVoluem.push({
x: time + i * 60000,//自行定義的時間 是連續的
y: self.socket.volumDataAll[i],
color: oo > cc ? "#70edab" : "red",//判斷顏色
trueTime: pubFn.getTime(tt)//數據真正的時間 是展現給用戶看的
});
formatter: function() { //回調函數將格式化提示框中的文本。 var points = this.points; // console.log(points) if (points.length>=2) { var t = new Date(points[1].point.options.trueTime); var m = t.getMonth(); // 獲取月份(0-11,0表明1月,用的時候記得加上1) var d = t.getDate(); // 獲取日(1-31) var h = t.getHours(); // 獲取小時數(0-23) var mi = t.getMinutes(); // 獲取分鐘數(0-59) var tStr = m+"/"+d+" "+h+":"+mi; } if (points[0].point.open != undefined) { var s = '<div style=""><b style="color:#ccc">T:</b><span style="color:green;">'+tStr+'<span></div>'+ '<div style=""><b style="color:#ccc">最高:</b><span style="color:green;">'+points[0].point.high+'<span></div>'+ '<div style=""><b style="color:#ccc">最低:</b><span style="color:green;">'+points[0].point.low+'<span></div>'+ '<div style=""><b style="color:#ccc">開盤:</b><span style="color:green;">'+points[0].point.open+'<span></div>'+ '<div style=""><b style="color:#ccc">收盤:</b><span style="color:green;">'+points[0].point.close+'<span></div>'; } return s; }
先寫這麼多吧,現在國家金融領域在開放,難免之後會有大量的期貨在中國能夠交易(昨天原油期上市了)有興趣的朋友能夠一塊兒探討,也但願js在這塊領域作出本身的東西,而再也不被那麼輕視。謝謝。