|
//获取应用实例
|
var app = getApp();
|
Page({
|
data: {
|
fontSize: 12, // 字体大小, 24rpx=12px
|
count: 10, // 展示的曲线次数
|
width: 0, // 画布宽
|
height: 300, // 画布高, wxss给定canvas高300px
|
dict: [// 所有曲线数据
|
{ cost: 1, transaction: "曲线", balance: 18.665, time: '2016-10-15 13:54:19' },
|
{ cost: 2, transaction: "曲线", balance: 5.7, time: '2016-10-15 13:54:19' },
|
{ cost: 3, transaction: "曲线", balance: 25.612, time: '2016-10-15 13:54:19' },
|
{ cost: 4, transaction: "曲线", balance: 38.258, time: '2016-10-15 13:54:19' },
|
{ cost: 5, transaction: "曲线", balance: 14, time: '2016-10-15 13:54:19' },
|
{ cost: 6, transaction: "曲线", balance: 14, time: '2016-10-15 13:54:19' },
|
{ cost: 7, transaction: "曲线", balance: 14, time: '2016-10-15 13:54:19' },
|
{ cost: 8, transaction: "曲线", balance: 14, time: '2016-10-15 13:54:19' },
|
{ cost: 9, transaction: "曲线", balance: 14, time: '2016-10-15 13:54:19' },
|
{ cost: 10, transaction: "曲线", balance: 0.00001, time: '2016-10-15 13:54:19' },
|
],
|
points: [], // 点的集合(包括点的横坐标x、纵坐标y、当前点的详情detail)
|
costArr: [], // 曲线jq集合
|
balanceArr: [], // ye_jq集合
|
tapDetail: {}, // 每个点对应的详情集合
|
lineLeft: 0, // 详情垂直线的初始左边距
|
gridMarginLeft: 35,// 表格左边距
|
gridMarginTop: 20, // 表格上边距
|
balance: 0, // 当前ye_(ye_卡片上的展示数据)
|
last_time: '',
|
switchBtn: true, // true:ye_ or false:交易额
|
options: {},
|
currentIndex: 0 // 当前点的索引,切换视图的时候保持当前详情
|
},
|
onLoad: function () {
|
var _this = this;
|
wx.getSystemInfo({
|
success: function (res) {
|
// 获取窗口宽, 计算画布宽
|
_this.setData({
|
'width': res.windowWidth
|
});
|
}
|
});
|
_this.sendRequest();
|
},
|
sendRequest() {
|
var _this = this;
|
/** 获取最近曲线数据绘制曲线图**/
|
var data = _this.data.dict;
|
var dict = data;
|
var len = dict.length,
|
xArr = [], // x轴坐标
|
yArr = [], // ye_点在画布中的纵坐标
|
balanceArr = [], // ye_jq集合
|
costArr = [], // 曲线jq集合
|
canvasWidth = _this.data.width,
|
spaceX = (canvasWidth - 2 * _this.data.gridMarginLeft) / (_this.data.count - 1), // 表示横坐标的间隔距离
|
canvasHeight = _this.data.height,
|
gridMarginTop = _this.data.gridMarginTop, // 曲线图上距离
|
gridMarginLeft = _this.data.gridMarginLeft, // 曲线图左距离
|
gridNum = 6, //横线行数
|
fontSize = _this.data.fontSize; //字号
|
// 横坐标&ye_&曲线
|
for (var i = 0; i < len; i++) {
|
xArr.push(i * spaceX);
|
balanceArr.push(parseFloat(dict[i].balance));
|
if (dict[i].transaction == '曲线') {
|
dict[i].cost = -Math.abs(dict[i].cost);
|
}
|
costArr.push(parseFloat(dict[i].cost));
|
}
|
_this.setData({
|
dict: data,
|
tapDetail: dict[dict.length - 1],
|
balance: parseFloat(data[data.length - 1].balance),
|
last_time: data[data.length - 1].time.split(' ')[0],
|
lineLeft: _this.data.width - _this.data.gridMarginLeft - 1,
|
switchArr: balanceArr, // 将纵坐标的值初始化为ye_集合
|
costArr: costArr, // 曲线集合,切换曲线的时候用
|
balanceArr: balanceArr
|
});
|
//canvas
|
var context = wx.createContext();
|
var options = {
|
canvasWidth: canvasWidth, // 矩形宽度
|
canvasHeight: canvasHeight, // 矩形高度
|
gridMarginTop: gridMarginTop, // 曲线图上距离
|
gridMarginLeft: gridMarginLeft, // 曲线图左距离
|
xArr: xArr, // 横坐标
|
gridNum: gridNum, // 横网格线数量
|
context: context, // canvas上下文
|
len: len, // 数据数组长度
|
spaceX: spaceX,
|
fontSize: fontSize
|
};
|
_this.setData({
|
options: options
|
});
|
context.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
/*
|
* 绘制横轴&纵轴&网格线
|
*/
|
_this.drawLineXY(_this.data.options, _this.data.switchArr);
|
|
/*
|
* 描点连线
|
*/
|
_this.drawPointLine(_this.data.options, _this.data.switchArr);
|
|
setTimeout(function () {
|
wx.drawCanvas({
|
canvasId: "firstCanvas",
|
actions: context.getActions(), // 获取绘图动作数组
|
reserve: true,
|
});
|
}, 500);
|
|
},
|
|
// 绘制横轴&纵轴&网格线
|
drawLineXY: function (options, switchArr) {
|
var context = options.context,
|
gridMarginLeft = options.gridMarginLeft,
|
gridMarginTop = options.gridMarginTop,
|
canvasHeight = options.canvasHeight,
|
canvasWidth = options.canvasWidth,
|
xArr = options.xArr,
|
tmp_yArr = switchArr,
|
gridNum = options.gridNum,
|
fontSize = options.fontSize;
|
|
/*
|
* ye_纵坐标&横网格线
|
* gridNum: 横网格线条数
|
* spaceY: 横网格间距
|
* spaceYe: 纵轴ye_的jq间隔
|
* tmp_minY: ye_的最小值
|
* tmp_maxY: ye_的最大值
|
*/
|
var tmp_minY = Math.min.apply(Math, tmp_yArr.map(function (e) { return Math.abs(e); })),
|
tmp_maxY = Math.max.apply(Math, tmp_yArr.map(function (e) { return Math.abs(e); })),
|
spaceYe = tmp_maxY / gridNum,
|
gridHeight = canvasHeight - 2 * gridMarginTop,
|
spaceY = gridHeight / gridNum;
|
|
// 绘制竖网格
|
context.setLineWidth(1);
|
context.setLineCap("round");
|
context.setStrokeStyle("#dddddd");
|
for (var i = 0; i < xArr.length; i++) {
|
context.beginPath();
|
context.moveTo(xArr[i] + gridMarginLeft, canvasHeight - gridMarginTop);
|
context.lineTo(xArr[i] + gridMarginLeft, gridMarginTop);
|
context.stroke();
|
context.closePath();
|
}
|
context.setStrokeStyle("#dddddd");
|
context.setFillStyle("#16b5cb");
|
|
// 绘制横网格&纵轴jq
|
for (var i = 0; i <= gridNum; i++) {
|
var numY = 0,
|
diff = 0;
|
// 纵轴jq
|
if (i === 0) {
|
numY = 0;
|
} else {
|
numY = (spaceYe * i).toFixed(0);
|
}
|
context.beginPath();
|
context.moveTo(xArr[0] + gridMarginLeft, gridMarginTop + spaceY * i);
|
context.lineTo(xArr[xArr.length - 1] + gridMarginLeft, gridMarginTop + spaceY * i);
|
context.stroke();
|
context.closePath();
|
|
context.beginPath();
|
context.setFontSize(fontSize);
|
var left = 25;
|
if (numY < 10) {
|
left = 15;
|
} else if (numY < 100) {
|
left = 20;
|
} else if (numY < 1000) {
|
left = 25;
|
}
|
context.fillText(numY, gridMarginLeft - left, canvasHeight - gridMarginTop - spaceY * i + 3);
|
context.closePath();
|
}
|
|
/*
|
* 绘制横轴和纵轴
|
*/
|
context.setLineWidth(2);
|
context.setStrokeStyle("#16b5cb");
|
context.beginPath();
|
context.moveTo(xArr[0] + gridMarginLeft, canvasHeight - gridMarginTop);
|
context.lineTo(canvasWidth - gridMarginLeft / 2, canvasHeight - gridMarginTop);
|
context.moveTo(xArr[0] + gridMarginLeft, canvasHeight - gridMarginTop);
|
context.lineTo(xArr[0] + gridMarginLeft, 0);
|
context.stroke();
|
context.closePath();
|
|
},
|
|
// 描点&连线
|
drawPointLine: function (options, switchArr) {
|
var _this = this;
|
var context = options.context,
|
yArr = [],
|
gridMarginLeft = options.gridMarginLeft,
|
gridMarginTop = options.gridMarginTop,
|
canvasHeight = options.canvasHeight,
|
canvasWidth = options.canvasWidth,
|
xArr = options.xArr,
|
gridNum = options.gridNum,
|
tmp_yArr = switchArr,
|
len = options.len,
|
spaceX = options.spaceX,
|
pointArr = [];
|
|
/*
|
* 点集的纵坐标
|
* 根据网格间距/ye_间距的比例算出点的对应纵坐标
|
* spaceY: 横网格间距
|
* spaceYe: 纵轴jq间隔
|
* tmp_minY: jq的最小值
|
* tmp_maxY: jq的最大值
|
* yArr: 点在画布中的纵坐标
|
*/
|
|
var tmp_minY = Math.min.apply(Math, tmp_yArr.map(function (e) { return Math.abs(e); })),
|
tmp_maxY = Math.max.apply(Math, tmp_yArr.map(function (e) { return Math.abs(e); })),
|
spaceYe = tmp_maxY / gridNum,
|
gridHeight = canvasHeight - 2 * gridMarginTop,
|
spaceY = gridHeight / gridNum,
|
switchBtn = Math.min.apply(Math, tmp_yArr) >= 0;
|
|
for (var i = 0; i < len; i++) {
|
yArr.push(gridHeight - (tmp_maxY - Math.abs(tmp_yArr[i])) * spaceY / spaceYe);
|
}
|
|
/*
|
* 描点连线
|
*/
|
for (var i = 0; i < len; i++) {
|
var x = xArr[i] + gridMarginLeft, // 横坐标
|
y = canvasHeight - gridMarginTop - yArr[i]; // 纵坐标
|
|
// 将点在画布中的坐标&曲线详情存入数组
|
pointArr.push({
|
x: x,
|
y: y,
|
detail: this.data.dict[i]
|
});
|
}
|
|
context.setStrokeStyle("#73b4ef");
|
context.setFillStyle("#16b5cb");
|
// 描点连线
|
for (var i = 0, pLen = pointArr.length; i < pLen; i++) {
|
|
if (pointArr[i + 1]) {
|
if ((switchBtn && tmp_yArr[i + 1] > tmp_yArr[i]) || (!switchBtn && (tmp_yArr[i] > 0 || tmp_yArr[i + 1] > 0))) {
|
context.setGlobalAlpha(0.66);
|
}
|
context.beginPath();
|
context.moveTo(pointArr[i].x, pointArr[i].y);
|
context.lineTo(pointArr[i + 1].x, pointArr[i + 1].y);
|
context.stroke();
|
context.beginPath();
|
}
|
|
context.setGlobalAlpha(1);
|
context.beginPath();
|
context.arc(pointArr[i].x, pointArr[i].y, 2, 0, 2 * Math.PI); // 画点
|
context.fill();
|
context.fillText((!switchBtn && tmp_yArr[i] > 0 ? '+' : '') + tmp_yArr[i], pointArr[i].x + 3, pointArr[i].y - 3); // 点的含义,画字
|
context.closePath();
|
|
pointArr[i].detail.balance = parseFloat(pointArr[i].detail.balance);
|
}
|
|
_this.setData({
|
points: pointArr
|
});
|
},
|
|
// 触摸详情
|
canvasTap: function (e) {
|
var _this = this;
|
// 手指在画布中的坐标
|
var tapX = e.detail.x,
|
tapY = e.detail.y,
|
points = _this.data.points,
|
pointsLen = points.length,
|
diffX = 0,
|
iwidth = (_this.data.width - 2 * _this.data.gridMarginLeft) / (_this.data.count - 1);
|
|
var i = Math.round((tapX - _this.data.gridMarginLeft) / iwidth);
|
|
_this.setData({
|
tapDetail: points[i].detail,
|
lineLeft: _this.data.gridMarginLeft + iwidth * i - 1, // 详情竖线的left
|
currentIndex: i // 当前点的索引,即显示当前详情
|
});
|
},
|
|
// 切换视图
|
switchBtn: function (e) {
|
var id = e.target.id;
|
if (!id || (id == 'balance' && this.data.switchBtn) || (id == 'cost' && !this.data.switchBtn)) {
|
return false;
|
}
|
var context = this.data.options.context;
|
context.clearRect(0, 0, this.data.canvasWidth, this.data.canvasHeight);
|
this.drawLineXY(this.data.options, this.data[id + 'Arr']);
|
this.drawPointLine(this.data.options, this.data[id + 'Arr']);
|
|
wx.drawCanvas({
|
canvasId: "firstCanvas",
|
actions: context.getActions(),
|
reverse: true
|
});
|
this.setData({
|
switchBtn: !this.data.switchBtn
|
});
|
}
|
|
});
|