浅谈APP之历史股票通过echarts绘图
浅谈APP之历史股票通过echarts绘图
需求描述
今天我们需要做一个简单的历史股票收盘价格通过echarts进行绘图,效果如下:
业务实现
代码框架
代码框架如下:
.
依赖包下载
我们通过网站下载自己需要的涉及的图标,勾选之后进行下载:echarts
下载的依赖包echarts.min.js我们放到static/echarts下
代码实现
echarts.vue实现
实现代码如下:
<template>
<view>
<view class="echarts" :prop="option" :change:prop="echarts.update"></view>
</view>
</template>
<script>
export default {
name: 'Echarts',
props: {
option: {
type: Object,
required: true
}
}
}
</script>
<script module="echarts" lang="renderjs">
export default {
data() {
return {
chart: null
}
},
mounted() {
if (typeof window.echarts === 'object') {
this.init()
} else {
// 动态引入类库
const script = document.createElement('script')
// script.src = './static/echarts/echarts.min.js'
// script.src = './static/echarts/echarts.min.js'
script.src = './static/echarts/echarts.min.js'
script.onload = this.init
document.head.appendChild(script)
}
},
methods: {
/**
* 初始化echarts
*/
init() {
this.chart = echarts.init(this.$el)
this.update(this.option)
},
/**
* 监测数据更新
* @param {Object} option
*/
update(option) {
if (this.chart) {
// 因App端,回调函数无法从renderjs外传递,故在此自定义设置相关回调函数
if (option) {
// tooltip
if (option.tooltip) {
// 判断是否设置tooltip的位置
if (option.tooltip.positionStatus) {
option.tooltip.position = this.tooltipPosition()
}
// 判断是否格式化tooltip
if (option.tooltip.formatterStatus) {
option.tooltip.formatter = this.tooltipFormatter(option.tooltip.formatterUnit, option.tooltip.formatFloat2, option.tooltip.formatThousands)
}
}
// 设置新的option
this.chart.setOption(option, option.notMerge)
}
}
},
/**
* 设置tooltip的位置,防止超出画布
*/
tooltipPosition() {
return (point, params, dom, rect, size) => {
//其中point为当前鼠标的位置,size中有两个属性:viewSize和contentSize,分别为外层div和tooltip提示框的大小
let x = point[0]
let y = point[1]
let viewWidth = size.viewSize[0]
let viewHeight = size.viewSize[1]
let boxWidth = size.contentSize[0]
let boxHeight = size.contentSize[1]
let posX = 0 //x坐标位置
let posY = 0 //y坐标位置
if (x < boxWidth) { //左边放不开
posX = 5
} else { //左边放的下
posX = x - boxWidth
}
if (y < boxHeight) { //上边放不开
posY = 5
} else { //上边放得下
posY = y - boxHeight
}
return [posX, posY]
}
},
/**
* tooltip格式化
* @param {Object} unit 数值后的单位
* @param {Object} formatFloat2 是否保留两位小数
* @param {Object} formatThousands 是否添加千分位
*/
tooltipFormatter(unit, formatFloat2, formatThousands) {
return params => {
let result = ''
unit = unit ? unit : ''
for (let i in params) {
if (i == 0) {
result += params[i].axisValueLabel
}
let value = '--'
if (params[i].data !== null) {
value = params[i].data
// 保留两位小数
if (formatFloat2) {
value = this.formatFloat2(value)
}
// 添加千分位
if (formatThousands) {
value = this.formatThousands(value)
}
}
// #ifdef H5
result += '\n' + params[i].seriesName + ':' + value + ' ' + unit
// #endif
// #ifdef APP-PLUS
result += '<br/>' + params[i].marker + params[i].seriesName + ':' + value + ' ' + unit
// #endif
}
return result
}
},
/**
* 保留两位小数
* @param {Object} value
*/
formatFloat2(value) {
let temp = Math.round(parseFloat(value) * 100) / 100
let xsd = temp.toString().split('.')
if (xsd.length === 1) {
temp = (isNaN(temp) ? '0' : temp.toString()) + '.00'
return temp
}
if (xsd.length > 1) {
if (xsd[1].length < 2) {
temp = temp.toString() + '0'
}
return temp
}
},
/**
* 添加千分位
* @param {Object} value
*/
formatThousands(value) {
if (value === undefined || value === null) {
value = ''
}
if (!isNaN(value)) {
value = value + ''
}
let re = /\d{1,3}(?=(\d{3})+$)/g
let n1 = value.replace(/^(\d+)((\.\d+)?)$/, function(s, s1, s2) {
return s1.replace(re, '$&,') + s2
})
return n1
}
}
}
</script>
<style lang="scss" scoped>
.echarts {
width: 100%;
height: 100%;
}
</style>
index.vue实现
实现代码如下:
<template>
<view>
<view class="uni-list">
<view class="uni-list-cell">
<view class="uni-list-cell-db">
<input class="uni-input" type="number" placeholder="请输入股票代码" @blur="moveAway"/>
<picker class="pickerDate" mode="date" :value="date1" :start="startDate" :end="endDate"
@change="bindDateChangeStart">
<view class="uni-input">开始时间:{{date1}}</view>
</picker>
<picker class="pickerDate" mode="date" :value="date2" :start="startDate" :end="endDate"
@change="bindDateChangeEnd">
<view class="uni-input">结束时间:{{date2}}</view>
</picker>
</view>
<button type="primary" @click="searchHistoryPrice">查询</button>
</view>
</view>
<view class="content">
<echarts :option="option3" style="height: 400px;"></echarts>
</view>
</view>
</template>
<script>
function getDate() {
const date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate() - 1;
month = month > 9 ? month : '0' + month;
day = day > 9 ? day : '0' + day;
return `${year}-${month}-${day}`;
}
function getStartDate() {
const date = new Date();
let year = date.getFullYear() - 10;
let month = date.getMonth() + 1;
let day = date.getDate() - 1;
month = month > 9 ? month : '0' + month;
day = day > 9 ? day : '0' + day;
return `${year}-${month}-${day}`;
}
export default {
data() {
return {
index: 0,
codePrice: '',
date1: getDate(),
date2: getDate(),
startDate: getStartDate(),
endDate: getDate(),
option3: {
xAxis: {
type: 'category',
data: []
},
yAxis: {
type: 'value'
},
series: [
{
data: [],
type: 'line'
}
]
},
}
},
methods: {
bindDateChangeStart: function (e) {
this.date1 = e.detail.value
console.log(this.date1)
},
bindDateChangeEnd: function (e) {
this.date2 = e.detail.value
console.log(this.date2)
},
moveAway: function (e) {
this.codePrice = e.detail.value
console.log(e.detail.value)
},
searchHistoryPrice: function (e) {
uni.request({
url: 'https://route.showapi.com/131-47?appKey=key&begin=' + this.date1 + '&type=bfq&end=' + this.date2 + '&code=' + this.codePrice,
method:'GET',
success: (res) => {
if(res.statusCode === 200){
const dataList = res.data.showapi_res_body.list;
const datePrice = dataList.map(datePrice => datePrice.date);
const closePrice = dataList.map(closePirce => closePirce.close_price);
this.option3.series[0].data = closePrice;
this.option3.xAxis.data = datePrice;
}
else{
console.error('请求失败',res);
}
},
fail: (err) => {
console.error('请求出错',err);
}
});
}
}
}
</script>
<style>
.uni-picker-tips {
font-size: 20px;
color: #666;
margin-bottom: 15px;
padding: 0 15px;
}
view,input{
font-size: 20px;
color: #666;
margin-bottom: 15px;
padding: 0 15px;
}
input{
border: #4CD964;
}
</style>
pages.json实现
实现代码如下:
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "历史股价查询"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "历史股价查询",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
}
至此,我们的业务实现完成。