做的是移动端的VUE + Vant。走势图每一条线都是一个canvas实现的
页面结构
部分参数我用“***”打个码,这里tbody动态创建,
<table id="zstable">
<thead>
<tr>
<th
:rowspan="rowspan"
width="130px"
:style="{
width: lotteryType == '****' ? '30%' : ''
}"
>
<div class="expectNo-box">
<van-dropdown-menu active-color="#eac886">
<van-dropdown-item
v-model="expectNoValue"
:options="expectNoOption"
@change="changeExpectNo"
/>
</van-dropdown-menu>
</div>
</th>
<th
v-if="lotteryType == '**'"
:rowspan="rowspan"
width="98px"
>
<span class="openNum">开奖号码</span>
</th>
<th :colspan="lotteryType == 'lottery'?'':colspan">
{{ tabsData[tabscurrent].title }}
</th>
</tr>
<tr v-if="lotteryType == '****'">
<th :style="{ width: '70%' }">
<td :style="{ display: 'inline-block', height: '25px', position: 'relative', width: '100%' }">
<span
v-for="(item, index) in 5"
:key="'lotterySpan' + index"
class="lotterySpan"
:style="{left:`${index * 20}%`}"
>{{
index == 0 ? index : index + '0'
}}</span
>
</td>
<td></td>
</th>
</tr>
<tr v-else>
<th v-for="(item, index) in colspan" :key="index">
<span
v-if="
oneBegin.indexOf(
Number(lotteryInfo.lotteryId)
) != -1
"
>{{ index + 1 }}</span
>
<span v-else>{{ index }}</span>
</th>
</tr>
</thead>
<tbody id="tbody" ref="tbody"></tbody>
<div id="canvasBox"></div>
</table>
js 部分
- 创建tbody
注意:
这里因为canvas画布是附着在“<div id="canvasBox"></div>”中的
“<div id='canvasdiv'></div>”,所以每次都会重新创建
“<div id='canvasdiv'></div>”这个盒子,以达到清除之前的画布
CreateTbody() {
let tbody = '';
let canvasDiv = '';
let isZeroBegin = false;
if (
this.zeroBegin.indexOf(Number(this.lotteryInfo.lotteryId)) != -1
) {
isZeroBegin = true;
}
let data = this.RUNS[this.tabscurrent].data;
if (this.lotteryType == '****') {
for (let i = 0; i < data.length; i++) {
tbody += '<tr>';
for (let j = 0; j < data[i].length; j++) {
if (j == 0 || data[i][j] == 0) {
tbody += `<td><span id="T${i}_${data[i][j]}" class="lotteryTbodySpan" style="left:${j*2}%">${
data[i][j] == 0 && !isZeroBegin
? j
: data[i][j] == 0 && isZeroBegin
? j - 1
: data[i][j]
}</span></td>`;
}
}
tbody += '</tr>';
}
} else {
for (let i = 0; i < data.length; i++) {
tbody += '<tr>';
for (let j = 0; j < data[i].length; j++) {
tbody += `<td id="T${i}_${data[i][j]}"><span>${
data[i][j] == 0 && !isZeroBegin
? j
: data[i][j] == 0 && isZeroBegin
? j - 1
: data[i][j]
}</span></td>`;
}
tbody += '</tr>';
}
}
canvasDiv = "<div id='canvasdiv'></div>";
$('#zstable #tbody').html(tbody);
$('#canvasBox').html(canvasDiv);
},
- 创建连线方法 (这里就是网上找到的那个里面的方法 Html5 canvas 绘制彩票走势图.)
drawLine() {
let ids = '';
for (let i = 0; i < this.RUNS[this.tabscurrent].data.length; i++) {
ids += 'T' + i + '_0,';
}
ids = ids.substring(0, ids.length - 1);
this.CreateLine(ids, 20, '#dcbd85', 'canvasdiv', '#dcbd85');
},
CreateLine(ids, w, c, div, bg) {
let list = ids.split(',');
for (let j = list.length - 1; j > 0; j--) {
let tid = $('#' + list[j]);
let fid = $('#' + list[j - 1]);
let f_width = fid.outerWidth();
let f_height = fid.outerHeight();
let f_position = fid.position();
let f_top = f_position.top;
let f_left = f_position.left;
let t_position = tid.position();
let t_top = t_position.top;
let t_left = t_position.left;
let cvs_left = Math.min(f_left, t_left);
let cvs_top = Math.min(f_top, t_top);
let cvs = document.createElement('canvas');
let cvsWidth =
Math.abs(f_left - t_left) < w
? w
: Math.abs(f_left - t_left);
let cvsHeight = Math.abs(f_top - t_top);
cvs.width = cvsWidth;
cvs.height = cvsHeight;
cvs.style.top = cvs_top + parseInt(f_height / 2) + 'px';
cvs.style.left = cvs_left + parseInt(f_width / 2) + 'px';
cvs.style.position = 'absolute';
let cxt = cvs.getContext('2d');
cxt.save();
cxt.strokeStyle = c;
cxt.lineWidth = 1;
cxt.lineJoin = 'round';
cxt.beginPath();
cxt.moveTo(f_left - cvs_left, f_top - cvs_top);
cxt.lineTo(t_left - cvs_left, t_top - cvs_top);
cxt.closePath();
cxt.stroke();
cxt.restore();
$('#' + div).append(cvs);
}
}
和后端约定好了数据的返回格式,“0” 代表中奖球号,对应数组索引index的数值,例如: data[0] 里面 “0” 为中奖号码,展示值为 “3”;
4. 最后使用
vanTabsChange(val, title) {
console.warn(val);
console.warn(title);
this.tabscurrent = val;
if (this.current == 1) {
setTimeout(() => {
this.CreateTbody();
this.drawLine();
}, 100);
} else if (this.current == 2) {
setTimeout(() => {
this.CreateTbody();
this.drawLine();
this.clearLine();
}, 100);
}
},
效果图
之后又发现另一个更简便的,纯JS就可以实现
链接: 前端 JS实现彩票开奖走势图 连线.