受欢迎的博客标签

wechat-微信小程序Asp .Net Core开发实战记录(45)-canvas,图表插件wxcharts,WebSocket实时显示股票交易信息(行情回放)

Published

https://blog.csdn.net/lecepin/article/details/54632749

Prerequisites

小程序客户端

1.miniProgramSignalr.js

参考了微信小程序与AspNetCore SignalR聊天实例 20190326
// come from:https://www.cnblogs.com/LiangSW/p/9415246.html
var Hub = require("../utils/miniProgramSignalr.js")

2.图表插件wxchart

 

Step 1:小程序端作为Client Signalr端和服务器web api+Signalr 建立连接

//小程序客户端 //微信小程序与AspNetCore SignalR聊天实例 20190326
// come from:https://www.cnblogs.com/LiangSW/p/9415246.html
var Hub = require("../utils/miniProgramSignalr.js")

onLoad: function() {
 //接受推送过来股票数据的代码
    this.hubConnect = new Hub.HubConnection();

    //Step 1:连接服务器
    this.hubConnect.start("https://api.usdotnet.com/stocktick", {
      nickName: app.globalData.userInfo.nickName,
      avatar: app.globalData.userInfo.avatarUrl
    });
    this.hubConnect.onOpen = res => {
      console.log("成功开启股票数据连接")
    }



    //Step 2:实时处理接服务器受推送过来的数据
    this.hubConnect.on("receive", res => {

      var json = JSON.stringify(res);
      console.log("excute this.hubConnect.on(receive, res =>),成功接受股票数据包, data received from server is:" + json);
      });
}

 

 

/**
 * Created by ChenChao on 2016/9/27.
 */

var app = getApp();
var storage = require('../utils/storage.js');
var storage1 = require('../utils/storage1.js');
var ts = require('../utils/wxChart/time-sharing');
var axisShow = require('../utils/wxChart/axis-show');

//小程序客户端 //微信小程序与AspNetCore SignalR聊天实例 20190326
// come from:https://www.cnblogs.com/LiangSW/p/9415246.html
var Hub = require("../utils/miniProgramSignalr.js")

var message = '';
var text = '';
var user = {};
var length;
var zx_info_id;
var openid_talk;
var app = getApp();
var centendata = [];

//-----


var ts1, ts2; //分时
var tsd51, tsd52; //五日
var tsAxisShow; //分时手势坐标

//分时线配置数据
var getOptionTimeSharing1 = function(type, width) {
  return {
    name: type || 'time-sharing',
    width: width || 'auto',
    height: 200,
    axis: {
      row: 4,
      col: 4,
      paddingTop: 0,
      paddingBottom: 0,
      paddingLeft: 0,
      paddingRight: 0,
      color: '#cdcdcd'
    },
    xAxis: {
      data: [] //x 数据项
    },
    yAxis: [{
        type: 'line',
        lineColor: '#2F6098',
        background: 'rgba(53,125,222,0.1)',
        /*background: function () {  //渐变背景在IOS上会影响均线颜色,这个应该是小程序canvas的bug
            return ['rgba(53,125,222,0.3)', 'rgba(0,0,0,0)'];
        },*/
        data: []
      },
      {
        type: 'line',
        lineColor: '#A96F3E',
        data: []
      }
    ],
    callback: function(time) {
      var page = getCurrentPages();
      page = page[page.length - 1];
      page.setData({
        ts1RenderTime: time
      });
    }
  };
};

//均线数据
var getOptionTimeSharing2 = function(type, width) {
  return {
    name: type || 'time-sharing-b',
    width: width || 'auto',
    height: 80,
    axis: {
      row: 2,
      col: 4,
      showEdg: true,
      showX: true,
      showY: true,
      paddingTop: 5,
      paddingBottom: 14,
      paddingLeft: 0,
      paddingRight: 0,
      color: '#cdcdcd'
    },
    xAxis: {
      times: ['09:30', '15:00'],
      data: []
    },
    yAxis: [{
      type: 'bar',
      color: [],
      data: [],
      showMax: true
    }],
    callback: function(time) {
      var page = getCurrentPages();
      page = page[page.length - 1];
      page.setData({
        ts2RenderTime: time
      });
    }
  };
};
var getOptionTimeSharingAxis = function() {
  return {

  };
};
var timer = null;

Page({
  data: {
    tabName: '',
    ts: {}, //分时线
    ts5: {}, //连续5日分时线
    stock: '',
    code: '',
    time: '',
    yc: '',
    dataIndex: 0,
    ts1RenderTime: 0,
    ts2RenderTime: 0,
    timerIndex: 4,
    timerArray: ['50ms', '100ms', '200ms', '500ms', '1000ms'],
    isShowAxis: false,

    price: 21.09, //测试
    vol: 2356,

    news: '', //chat 的变量
    scrollTop: 0,
    message: '',
    text: text,
    nickName: '',
    avatarUrl: '',
    news_input_val: '',

    report: {}, //股票明细对象
    reportList: [], //存放成交明细
  },
  onLoad: function() {
    //获取分时图数据
    var tsData = storage.getTsData();
    //获取5日分时图数据
    var ts5Data = storage.getTs5Data();
    //赋值
    this.setData({
      dataIndex: 0,
      ts: tsData,
      ts5: ts5Data
    });

    this.tabChart({
      target: {
        dataset: {
          type: 'ts'
        }
      }
    });

    //-----20190326 add---
    //接受推送过来股票数据的代码
    this.hubConnect = new Hub.HubConnection();

    //连接服务器
    this.hubConnect.start("https://api.usdotnet.com/stocktick", {
      nickName: app.globalData.userInfo.nickName,
      avatar: app.globalData.userInfo.avatarUrl
    });
    this.hubConnect.onOpen = res => {
      console.log("成功开启股票数据连接")
    }



    //接服务器受推送过来的数据
    this.hubConnect.on("receive", res => {

      var json = JSON.stringify(res);
      console.log("excute this.hubConnect.on(receive, res =>),成功接受股票数据包, data received from server is:" + json);

      //存放13条成交明细供显示
      var that = this;
      let reportList = that.data.reportList;
      if (reportList.length < 13) {
        //在数组尾部加入
        reportList.push(res);
      } else {
        // 删除数组的第一个子集,并返回被删除的子集
        reportList.shift();
        //在尾部添加一个子集
        reportList.push(res);
      }

      centendata.push({
        content: res.msg,
        time: new Date().toLocaleString(),
        head_owner: res.avatar,
        is_show_right: 0
      });

      this.setData({
        report: res,
        reportList: reportList,
      })
    });

    //-----20190326 add end---
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function() {

  },

  onHide: function() {
    clearInterval(timer);
  },

  //选择当日/5日分时线标签
  tabChart: function(e) {
    this.clearTimer();
    var type = e.target.dataset.type;
    var data = this.data[type];
    this.setData({
      tabName: type,
      stock: data.name,
      code: data.code,
      time: data.info.time,
      yc: data.info.yc //昨日收盘价
    });
    this['init-' + type]();
  },

  //当日分时线
  'init-ts': function() {
    //获取当日分时线数据
    var data = this.data.ts;
    //初始化分时图
    ts1 = ts('time-sharing').init(getOptionTimeSharing1());
    //转换数据,画分时图
    this.renderTs1(data);
    //实际调用下面的
    // renderTs1: function(data) {
    //   ts1.metaData1(data, getOptionTimeSharing1());  转换处理数据
    //   ts1.draw(); 画图
    //  },

    //画成交量
    ts2 = ts('time-sharing-b').init(getOptionTimeSharing2());
    this.renderTs2(data);

    //画时间线
    tsAxisShow = axisShow('time-sharing-axis', {
      //todo: 配置项
      type: 'ts',
      height: 280,
      width: 'auto',
      maxY: 100,
      minY: 0
    });
    tsAxisShow.init();
  },

  //五日连续分时线
  'init-ts5': function() {
    var data = this.data.ts5;
    tsd51 = ts('time-sharing-5day').init(getOptionTimeSharing1('time-sharing-5day'));
    tsd52 = ts('time-sharing-5day-b').init(getOptionTimeSharing2('time-sharing-5day'));
    tsd51.metaData1(data, getOptionTimeSharing1('time-sharing-5day'));
    tsd51.draw();
    tsd52.metaData2(data, getOptionTimeSharing2('time-sharing-5day'));
    tsd52.draw();
  },

//将数据转换为可显示标准格式,然后显示:metadata1()和metadata2()方法为数据转化接口
  renderTs1: function(data) {
    //数据转换
    ts1.metaData1(data, getOptionTimeSharing1());
    ts1.draw();
  },

  renderTs2: function(data) {
    //数据转换
    ts2.metaData2(data, getOptionTimeSharing2());
    ts2.draw();
  },

  clearTimer: function() {
    clearInterval(timer);
    this.setData({
      dataIndex: 0
    });
  },

  reset: function() {
    this.clearTimer();

    var data = storage.getTsData();
    this.renderTs1(data);
    this.renderTs2(data);
  },

  //模拟动态变化
  dynamic: function() {
    var that = this;
    //获取分时时图数据
    var data = storage.getTsData();
    //获取分时图数据的数组项
    var origin = data.data.slice(0);
    var index = 0;
    var times = [50, 100, 200, 500, 1000];
    clearInterval(timer);

    //定时器
    timer = setInterval(function() {
      index += 1;
      if (index > 241 + 16) {
        clearInterval(timer);
        return;
      }

      //获取0到index的数组
      data.data = origin.slice(0, index);
     
      //分时线
      that.renderTs1(data);
     
      //成交量
      that.renderTs2(data);
     
      that.setData({
        dataIndex: index
      });
    }, times[this.data.timerIndex]);
  },

  bindTimeChange: function(e) {
    var index = e.detail.value;
    this.setData({
      timerIndex: index === '' ? 4 : index
    });
    this.dynamic();
  },

  axisStart: function(e) {
    var x = e.touches[0].x;
    var y = e.touches[0].y;
    this.data.isShowAxis = true;
    tsAxisShow.start(x, y);
  },
  axisMove: function(e) {
    if (this.data.isShowAxis) {
      var x = e.touches[0].x;
      var y = e.touches[0].y;
      tsAxisShow.move(x, y);
    }
  },
  axisStop: function() {
    this.data.isShowAxis = false;
    tsAxisShow.stop();
  },

  bindChange: function(e) {
    message = e.detail.value
  },

  //  ----发送股票代码---
  add: function(e) {
    //点击发送,调用服务器上的 sendMessage 方法
    this.hubConnect.send("SendMessage", message);
    centendata.push({
      content: message,
      time: new Date().toLocaleString(),
      head_owner: app.globalData.userInfo.avatarUrl,
      is_show_right: 1
    });
    this.setData({
      centendata: centendata
    })

    var tsData1 = storage1.getTsData();
    this.setData({
      ts: tsData1,
      stock: "e.detail.value.Name",
      code:"600929"
    })

    //分时线 
    //this.renderTs1(tsData1);
    ts1.draw();
    message = '';
  },

});

 

实例:实时显示交易信息

 

添加stock页面:

wxchart.js放入到pages/stock/中。

修改stock.wxml

stock.js代码:

// pages/stock/stock.js
//加载插件
var wxCharts = require('wxcharts.js');

Page({
  data: {},

  onLoad: function (options) {

    //建立连接
    wx.connectSocket({
      url: "ws://localhost:12345",
    })

    //连接成功
    wx.onSocketOpen(function() {
      wx.sendSocketMessage({
        data: 'stock',
      })
    })

    //接收数据
    wx.onSocketMessage(function(data) {
      var objData = JSON.parse(data.data);
      console.log(data);
        new wxCharts({
          canvasId: 'lineCanvas',//指定canvas的id
          animation: false,
          type: 'line',//类型是线形图
          categories: ['2012', '2013', '2014', '2015', '2016', '2017'],

          series: [{
            name: '交易量',
            data: objData,//websocket接收到的数据
            format: function (val) {
              if (typeof val == "string") {
                val = parseFloat(val);
              }
              return val.toFixed(2) + '万元';
            }
          },
          ],
          yAxis: {
            title: '交易金额 (万元)',
            format: function (val) {
              return val.toFixed(2);
            },
            min: 0
          },
          width: 320,
          height: 200
        });      
    })

    //连接失败
    wx.onSocketError(function() {
      console.log('websocket连接失败!');
    })
  },
})
 

 

实例效果:




1.微信小程序 chart 、K线图、分时图  

egchart.js

https://github.com/EGsnn/wxcharts

2.网页,小程序、app vue行情

https://github.com/jones2000/HQChart

支持前复权,后复权 支持日线,月线,周线,年线. 主图支持股票叠加 支持常用指标指标(目前以录入系统指标85个) 均线,BOLL,MACD,KDJ,VOL,RSI,BRAR,WR,BIAS,OBV,DMI,CR,PSY,CCI, DMA,TRIX,VR,EMV,ROC,MIM,FSL,CYR,MASS,WAD,CHO ..... 数据鼠标左右拖拽移动, 键盘移动十字光标移动,键盘缩放 支持通达信语法指标

3.股票网页版

https://github.com/roshanca/stock-chart

4.

https://github.com/Seedarchangel/TuChart

5.

blog:http://www.wxapp-union.com/forum.php?mod=viewthread&tid=2032&fromuid=2

https://github.com/hxbaishikele/kabul

6.股票分时图

https://github.com/zhakei988/wxapp

小程序blog

2.1 Canvas绘制股票K线图

http://www.mamicode.com/info-detail-2160652.html

2.2 小程序 - K线图画法

https://blog.csdn.net/sinat_27180253/article/details/80932177

 

app

5.各种金融类的自定义View,基金走势图、分时图、蜡烛图、各种指标等,一步一步构建庞大的基金自定View

https://github.com/Tophold/FinancialCustomerView

6.股票图,K线图,蜡烛图,高仿雪球股票,教你一步步实现股票图

blog:https://blog.csdn.net/qq_24531461/article/details/72972429

https://github.com/siyehua/KLineGraph

7.基于MPAndroidChart的专业股票图,如分时图和K线图KLine。

https://github.com/LambdaXiao/StockChart-MPAndroidChart

8.KChart for Android ;股票k线图

https://github.com/tifezh/KChartView

ios

1.

https://github.com/zhiyu/chartee

2.

https://github.com/YongbaoWang/StockChart

3.

https://github.com/chenxiaoyu3/BBStockChartView

4.iOS K线第二版:分时图,日周月K线图,五档图,长按,捏合缩放,全屏非全屏切换自适应等

https://github.com/WillkYang/YYStock