You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

509 lines
20 KiB

<!DOCTYPE html>
<html lang="cn">
<head>
<meta charset="UTF-8">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>风控</title>
<link href="../vendors/dcat-admin/adminlte/index.min.css" rel="stylesheet">
<script src="https://sses.cxicoin.com/vendors/dcat-admin/adminlte/echarts.min.js"></script>
<script src="https://sses.cxicoin.com/vendors/dcat-admin/adminlte/vue.min.js"></script>
<script src="https://sses.cxicoin.com/vendors/dcat-admin/adminlte/index.js"></script>
<script src="https://sses.cxicoin.com/vendors/dcat-admin/adminlte/axios.min.js"></script>
<style>
body {
background: #4CA1AF;
/* fallback for old browsers */
background: -webkit-linear-gradient(to right, #C4E0E5, #4CA1AF);
/* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #C4E0E5, #4CA1AF);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
.chart1 {
height: 400px;
border: 1px solid #996;
}
.chart2{
height: 400px;
border: 1px solid #996;
}
.form {
margin: 20px 0;
}
.s-input {
width: 100px;
}
.kline-button{
padding-top: 5px;
}
</style>
</head>
<body>
<div id="app">
<div class="form">
<el-date-picker v-model="day" type="date" @change="changeDate" placeholder="选择日期">
</el-date-picker>
<el-select name="" @change="changeSymbol" placeholder="请选择币种" v-model="coin" >
<!--<el-option :value="1" label="GITP/USDT"></el-option>-->
<!--<el-option :value="1" label="BT/USDT"></el-option>-->
<!--<el-option :value="3" label="TKB/USDT"></el-option>-->
<el-option :value="1" label="AAAAA/USDT"></el-option>
<el-option :value="2" label="BTU/USDT"></el-option>
<el-option :value="3" label="BLK/USDT"></el-option>
<el-option :value="4" label="TVC/USDT"></el-option>
<el-option :value="5" label="MGC/USDT"></el-option>
<el-option :value="6" label="DSR/USDT"></el-option>
</el-select>
<el-select name="" @change="changePeriod" placeholder="请选择周期" v-model="period" >
<el-option :value="1" label="1分钟"></el-option>
<!--{{-- <el-option :value="5" label="5分钟"></el-option>--}}-->
<!--{{-- <el-option :value="15" label="15分钟"></el-option>--}}-->
<el-option :value="30" label="30分钟"></el-option>
<!--{{-- <el-option :value="60" label="1小时"></el-option>--}}-->
</el-select>
开:<el-input class="s-input" type="text" v-model="open" @change="setLine" placeholder="开盘价"></el-input>
收:<el-input class="s-input" type="text" v-model="close" @change="setLine" placeholder="收盘价"></el-input>
低:<el-input class="s-input" type="text" v-model="low" @change="setLine" placeholder="最低价"></el-input>
高:<el-input class="s-input" type="text" v-model="high" @change="setLine" placeholder="最高价"></el-input>
最小市值:<el-input class="s-input" type="text" v-model="min_amount" @change="setLine" placeholder="最小市值"></el-input>
最大市值:<el-input class="s-input" type="text" v-model="max_amount" @change="setLine" placeholder="最大市值"></el-input>
{{-- <el-button type="primary" plain @click="getKlineData">获取K线</el-button>--}}
<el-button type="success" plain @click="saveLine" :loading="saveLoading">保存</el-button>
<el-button type="info" plain @click="generateKline" :loading="generateLoading">生成K线</el-button>
</div>
<div class="chart1" id="chart1" v-loading="loading1"></div>
<div class="chart2" id="chart2" v-loading="loading2"></div>
</div>
<script>
Date.prototype.Format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
/**
* Next we will register the CSRF Token as a common header with Axios so that
* all outgoing HTTP requests automatically have it attached. This is just
* a simple convenience so we don"t have to attach every token manually.
*/
window.csrf_token = document.head.querySelector('meta[name="csrf-token"]');
if (csrf_token) {
axios.defaults.headers.common['X-CSRF-TOKEN'] = csrf_token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
axios.defaults.baseURL = '{{admin_url()}}';
function axiosRequest(method, url, params){
return new Promise((resolve, reject) => {
axios({
method: method,
url: url,
data: method === "POST" || method === "PUT" || method==="PATCH"? params : null,
params: method === "GET" || method === "DELETE" ? params : null,
withCredentials: true,
cache:false
}).then(function (result) {
resolve(result.data);
}).catch(function (error) {
console.log(error);
});
});
}
new Vue({
el: '#app',
data: {
loading1:false,
loading2:false,
saveLoading:false,
generateLoading:false,
pointData: [],
klineFormData: [],
klineMockXData:[],
klineMockYData:[],
myChart: undefined,
klineDom: undefined,
pricePencent: 0.1,
day: new Date(),
coin: 1,
period: 30,
open: '',
close: '',
low: '',
high: '',
min_amount: '',
max_amount: ''
},
mounted() {
this.getKlineConfig();
},
methods: {
//时间格式化
formatTime(dt){
var year = dt.getFullYear(); //年
var month = dt.getMonth() +1; //月
var date = dt.getDate(); //日
month = month < 10 ? "0" + month : month;
date = date <10 ? "0" + date : date;
var str = year + "-" + month + "-" + date + " 00:00:00";
return str;
},
changeDate() {
console.log(this.day)
this.getKlineConfig();
},
changePeriod(){
this.getKlineConfig();
},
changeSymbol(){
this.getKlineConfig();
},
getKlineConfig(){
var date = this.formatTime(this.day)
console.log({date})
axiosRequest('GET','/getKlineConfig',{"datetime":date,"period":this.period,"coin":this.coin}).then(response=>{
console.log(response);
if(response.config){
this.open = response.config.open;
this.close = response.config.close;
this.low = response.config.low;
this.high = response.config.high;
this.min_amount = response.config.min_amount;
this.max_amount = response.config.max_amount;
}else{
this.open = '';
this.close = '';
this.low = '';
this.high = '';
this.min_amount = '';
this.max_amount = '';
}
this.max = response.max.toFixed(5);
this.min = response.min.toFixed(5);
this.pointData = response.lists;
this.klineFormData = response.klineFormData;
this.klineMockXData = response.dateKline// 时间线
this.klineMockYData = response.klineData// 对应数据
this.initLine();
this.initKline();
this.setLine();
});
},
initLine() {
this.myChart = window.echarts.init(document.getElementById('chart1'));
let onPointDragging = this.onPointDragging;
let showTooltip = this.showTooltip;
let hideTooltip = this.hideTooltip;
let updatePosition = this.updatePosition;
let renderDraw = this.renderDraw;
setTimeout(function () {
renderDraw()
}, 10)
window.addEventListener('resize', updatePosition);
this.myChart.on('dataZoom', updatePosition);
},
onPointDragging(dataIndex, pos) {
let data = this.pointData;
// console.log({data})
var position = this.myChart.convertFromPixel('grid', pos);
// console.log(dataIndex); // 第几条
//console.log(position[1]); // 偏移量-最终值
// this.klineMockYData[nextIndex][2] = 1; 开收高低
data[dataIndex] = [data[dataIndex][0], position[1]];
this.klineMockYData[dataIndex][1] = this.pointData[dataIndex][1];
let nextIndex = dataIndex+1;
if(typeof this.klineMockYData[nextIndex] === 'object'){
this.klineMockYData[nextIndex][0] = this.pointData[dataIndex][1];
}
// update klineFormData
this.klineFormData[dataIndex].close = this.pointData[dataIndex][1];
if(this.klineFormData[nextIndex]){
this.klineFormData[nextIndex].open = this.pointData[dataIndex][1];
}
var aa = (Math.random() * (0.003 - 0.0001) + 0.0001).toFixed(4);
var bb = (Math.random() * (0.003 - 0.0001) + 0.0001).toFixed(4);
// 当前线条大于开盘价
if(this.klineFormData[dataIndex].open > this.pointData[dataIndex][1]){
this.klineMockYData[dataIndex][3] = this.pointData[dataIndex][1]*(1 - aa * 1);
// this.klineMockYData[dataIndex][2] = this.pointData[dataIndex][1]*(1 + bb * 1);
}else{
// console.log(1 + aa * 1);
this.klineMockYData[dataIndex][2] = this.pointData[dataIndex][1]*(1 + aa * 1);
// this.klineMockYData[dataIndex][3] = this.pointData[dataIndex][1]*(1 - bb * 1);
}
// 当前线条大于开盘价
if(this.klineFormData[nextIndex].close > this.pointData[dataIndex][1]){
this.klineMockYData[nextIndex][3] = this.pointData[dataIndex][1]*(1 - bb * 1);
}else{
// console.log(1 + aa * 1);
this.klineMockYData[nextIndex][2] = this.pointData[dataIndex][1]*(1 + bb * 1);
}
// Update data
this.myChart.setOption({
series: [{
id: 'chart1',
data: data
}]
});
this.klineDom.setOption({
series: [{
type: 'k',
data: this.klineMockYData
}]
});
},
updatePosition() {
var self = this
this.myChart.setOption({
graphic: this.pointData.map(function (item, dataIndex) {
return {
position: self.myChart.convertToPixel('grid', item)
};
})
});
},
showTooltip(dataIndex) {
this.myChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: dataIndex
});
},
hideTooltip(dataIndex) {
this.myChart.dispatchAction({
type: 'hideTip'
});
},
renderDraw() {
let self = this;
let onPointDragging = this.onPointDragging;
let showTooltip = this.showTooltip;
let hideTooltip = this.hideTooltip;
let updatePosition = this.updatePosition;
let renderDraw = this.renderDraw;
this.myChart.setOption({
graphic: this.pointData.map(function (item, dataIndex) {
return {
type: 'circle',
position: self.myChart.convertToPixel('grid', item),
shape: {
cx: 0,
cy: 0,
r: 5
},
invisible: true,
draggable: true,
ondrag: function (dx, dy) {
onPointDragging(dataIndex, [this.x, this.y]);
},
onmousemove: function () {
showTooltip(dataIndex);
},
onmouseout: function () {
hideTooltip(dataIndex);
},
ondragend: function () {
updatePosition()
},
z: 100
};
})
});
},
generateKline(){
this.generateLoading = true;
var datetime = this.formatTime(this.day)
var config = {
datetime: datetime,
open: this.open,
close: this.close,
low: this.low,
high: this.high,
min_amount: this.min_amount,
max_amount: this.max_amount,
currency_coin: this.coin
}
axiosRequest('GET','/generateKline',config).then(response=>{
console.log(response);
this.generateLoading = false;
this.max = response.max.toFixed(5);
this.min = response.min.toFixed(5);
this.pointData = response.lists;
this.klineFormData = response.klineFormData;
this.klineMockXData = response.dateKline// 时间线
this.klineMockYData = response.klineData// 对应数据
this.initLine();
this.initKline();
this.setLine();
});
},
// 保存趋势线
saveLine(){
this.saveLoading = true;
var datetime = this.formatTime(this.day)
var data = {
"coin":this.coin,
datetime: datetime,
open: this.open,
close: this.close,
low: this.low,
high: this.high,
min_amount: this.min_amount,
max_amount: this.max_amount,
klineFormData: this.klineFormData
}
axiosRequest('POST','/kline-save',data).then(response=>{
this.saveLoading = false;
console.log(response)
});
},
// 初始化走势线
setLine() {
/*let price = (this.max * 1 + this.min * 1) / 2;
// 一天的长度
let len = (86400000 / (this.period * 60 * 1000)).toFixed(8) * 1;
let cuuretDay = new Date(this.day).getTime()
// 生成默认数据
let attr = new Array(len).fill('').map((item, idx) => [cuuretDay + (idx + 1) * this.period * 60 * 1000, price]);
this.pointData = attr;*/
var option;
option = {
tooltip: {
triggerOn: 'none',
formatter: function (params) {
return '时间: ' + new Date(params.data[0]).Format('yyyy-MM-dd hh:mm:ss') + '<br>收盘: ' + params.data[1].toFixed(5);
}
},
dataZoom: [{
type: 'inside'
}],
grid: {
top: '4%',
bottom: '4%',
left: '4%',
right: '4%',
},
xAxis: {
type: 'time',
axisLine: { onZero: false }
},
yAxis: {
min: this.min,
max: this.max,
type: 'value',
axisLine: { onZero: false }
},
series: [
{
id: 'chart1',
type: 'line',
smooth: true,
symbolSize: 5,
data: this.pointData
}
]
};
this.myChart.setOption(option, true);
setTimeout(() => {
this.renderDraw();
this.initializeKLine();
}, 30)
},
// -----预览K线----
initKline() {
this.klineDom = echarts.init(document.getElementById('chart2'));
var that = this;
this.klineDom.setOption({
backgroundColor: '#EDEDED',
xAxis: {
data: []
},
yAxis: {
max: this.max,
min: this.min,
},
series: [{
type: 'k',
data: [],
}],
grid: {
left: 30,
right: 20,
top: 10,
bottom: 30
},
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 1],
start: 10,
end: 100
},
{
show: true,
xAxisIndex: [0, 1],
type: 'slider',
bottom: 10,
start: 10,
end: 100
}
],
});
},
initializeKLine() {
this.klineDom.setOption({
xAxis: {
data: this.klineMockXData
},
series: [{
type: 'k',
data: this.klineMockYData
}]
});
},
},
})
</script>
</body>
</html>