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.
 
 
 

457 lines
12 KiB

<template>
<view class="content">
<!-- #ifdef APP-PLUS || H5 -->
<view @click="echarts.onClick" :prop="option" :change:prop="echarts.updateEcharts" id="echarts" class="echarts">
</view>
<!-- #endif -->
<!-- #ifndef APP-PLUS || H5 -->
<view> APPH5 环境不支持</view>
<!-- #endif -->
</view>
</template>
<script>
// 数据意义:开盘(open),收盘(close),最低(lowest),最高(highest),数量(vol)
function splitData(rawData) {
let raw = JSON.parse(JSON.stringify(rawData))
let categoryData = [];
let values = [];
let volumes = [];
for (let i = 0; i < raw.length; i++) {
categoryData.push(raw[i].splice(0, 1)[0]);
values.push(raw[i]);
// console.log(raw[i],'*****')
// volumes.push([i, raw[i][4], raw[i][0] >= raw[i][1] ? 1 : -1]);
volumes.push([i, raw[i][3], raw[i][0] >= raw[i][1] ? 1 : -1]);
}
return {
categoryData: categoryData,
values: values,
volumes: volumes
};
}
function calculateMA(dayCount, values) {
let result = [];
for (let i = 0, len = values.length; i < len; i++) {
if (i < dayCount) {
result.push('-');
continue;
}
let sum = 0;
for (let j = 0; j < dayCount; j++) {
sum += values[i - j][1];
}
result.push(+(sum / dayCount).toFixed(3));
}
return result;
}
export default {
props: {
kData,
// 初始数据
initData: {
type: Array,
required: true
},
upColor: {
type: String,
default: 'rgb(49,186,160)'
},
downColor: {
type: String,
default: 'rgb(252,95,95)'
},
// 警戒线颜色
markLineColor: {
type: String,
default: '#ffffff'
},
// 警戒线文字颜色
markLineLabelColor: {
type: String,
default: '#ffffff'
},
// 警戒线第二排文字
markLineYTime: {
type: String,
default: '最新价'
},
// 警戒线文字背景颜色
markLineLabelBackgroundColor: {
type: String,
default: '#00b6ff'
},
// Y轴颜色
yAxisSplitLineColor: {
type: String,
default: '#333'
},
// Y轴刻度值颜色
yAxisAxisLabelColor: {
type: String,
default: '#fff'
},
// 背景图
backgroundImageUrl: {
type: String,
default: '#000'
},
},
data() {
return {
option: {},
oldData: {}
}
},
onShow() {
console.log(this.kData);
this.init(this.kData)
},
mounted() {
if (this.initData.length > 0) {
this.init(this.initData)
}
},
methods: {
// 追加数据
addData(oo) {
let isUp = false;
let isUpIndex = true;
for (let i = 0; i < this.oldData.length; i++) {
// console.log(listData[i][0], oo[0],listData[i][0] != oo[0])
if (this.oldData[i][0] == oo[0]) {
isUp = true;
isUpIndex = i;
this.oldData[isUpIndex] = oo
}
}
if (!isUp) {
this.oldData.shift();
this.oldData.push(oo)
}
this.changeOption(this.oldData)
},
// 初始化数据
init(data) {
console.log(data);
this.oldData = JSON.parse(JSON.stringify(data));
this.changeOption(this.oldData)
},
changeOption(res) {
let data = splitData(JSON.parse(JSON.stringify(res)));
this.option = {
// animation: false,
animationEasing: 'elasticOut',
legend: {
show: false,
bottom: 10,
left: 'center',
data: ['Dow-Jones index', 'MA5', 'MA10']
},
tooltip: {
trigger: 'axis',
confine: true,
axisPointer: {
type: 'line',
},
backgroundColor: 'rgba(255, 255, 255, 0.8)',
position: function (pos, params, el, elRect, size) {
let obj = { top: 10 };
obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30;
return obj;
},
extraCssText: 'width: 170px'
},
axisPointer: {
type: 'line',
lineStyle: {
type: 'solid',
color: '#ffffff'
},
link: { xAxisIndex: 'all' },
label: {
backgroundColor: '#777'
}
},
visualMap: {
show: false,
seriesIndex: 3,
dimension: 2,
pieces: [{
value: 1,
color: this.downColor
}, {
value: -1,
color: this.upColor
}]
},
grid: [
{
top: '4%',
left: '2%',
right: '18%',
height: '65%',
bottom: '0%',
borderWidth: 20
},
{
left: '2%',
right: '18%',
bottom: '5%',
height: '25%'
}
],
graphic: [
{
type: 'image', // 图形元素类型
id: 'logo', // 更新或删除图形元素时指定更新哪个图形元素,如果不需要用可以忽略。
right: 'center', // 根据父元素进行定位 (居中)
bottom: 'middle', // 根据父元素进行定位 (0%), 如果bottom的值是 0,也可以删除该bottom属性值。
z: 0, // 层叠
bounding: 'all', // 决定此图形元素在定位时,对自身的包围盒计算方式
style: {
image: this.backgroundImageUrl, // 这里一定要注意、注意,必须是https开头的图片路径地址
width: '100%',
height: '100%'
}
}],
xAxis: [
{
show: false,
type: 'category',
},
{
type: 'category',
gridIndex: 1,
data: data.categoryData,
// scale: true,
// boundaryGap: false,
axisTick: { show: false },
minorTick: { show: false },
axisLine: { onZero: false },
axisLabel: { onZero: false },
// splitNumber: 20,
min: 'dataMin',
max: 'dataMax',
axisPointer: {
label: {
formatter: function (params) {
let seriesValue = (params.seriesData[0] || {}).value;
return params.value
+ (seriesValue != null
? '\n' + echarts.format.addCommas(seriesValue)
: ''
);
}
}
}
}
],
yAxis: [
{
scale: true,
position: 'right',
splitLine: {
show: true,
lineStyle: {
color: this.yAxisSplitLineColor
}
},
axisLabel: {
show: true,
color: this.yAxisAxisLabelColor,
},
minorTick: {
show: true,
splitNumber: 10,
lineStyle: {
color: this.yAxisAxisLabelColor,
}
}
},
{
scale: true,
gridIndex: 1,
splitNumber: 1,
axisLabel: { show: false },
axisLine: { show: false },
axisTick: { show: false },
splitLine: { show: false }
}
],
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 1],
zoomOnMouseWheel: false,
moveOnMouseMove: false,
moveOnMouseWheel: false,
start: 0,
end: 100,
},
{
show: true,
xAxisIndex: [0, 1],
type: 'inside',
zoomOnMouseWheel: false,
moveOnMouseMove: false,
moveOnMouseWheel: false,
top: '85%',
start: 0,
end: 100,
}
],
series: [
{
name: 'Dow-Jones index',
type: 'candlestick',
data: data.values,
itemStyle: {
color: this.upColor,
color0: this.downColor,
borderColor: null,
borderColor0: null
},
tooltip: {
formatter: function (param) {
param = param[0];
return [
'Date: ' + param.name + '<hr size=1 style="margin: 3px 0">',
'Open: ' + param.data[0] + '<br/>',
'Close: ' + param.data[1] + '<br/>',
'Lowest: ' + param.data[2] + '<br/>',
'Highest: ' + param.data[3] + '<br/>'
].join('');
}
},
markLine: {
symbol: 'none', //去掉警戒线最后面的箭头
data: [
{
silent: false,//鼠标悬停事件 true没有,false有
yAxis: data.values[data.values.length - 1][1],// 警戒线的标注值,可以有多个yAxis,多条警示线 或者采用 {type : 'average', name: '平均值'},type值有 max min average,分为最大,最小,平均值
lineStyle: { //警戒线的样式 ,虚实 颜色
type: "solid",
color: this.markLineColor,
},
label: {
position: "end",//将警示值放在哪个位置,三个值“start”,"middle","end" 开始 中点 结束
color: this.markLineLabelColor,
// backgroundColor:"#00b6ff",
fontSize: "12px",
formatter: [
'{a|{c}}',
'{b|' + this.markLineYTime + '}'
].join('\n'),
// formatter:"{c}\n最新价",
rich: {
a: {
padding: 4,
backgroundColor: this.markLineLabelBackgroundColor,
align: 'right',
},
b: {
padding: 4,
backgroundColor: this.markLineLabelBackgroundColor,
align: 'right',
},
}
},
},
]
},
},
{
name: 'MA5',
type: 'line',
symbol: "none",
data: calculateMA(5, data.values),
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'MA10',
type: 'line',
symbol: "none",
data: calculateMA(10, data.values),
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'Volume',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
data: data.volumes
}
]
}
},
onViewClick(options) {
console.log(options)
}
}
}
</script>
<script module="echarts" lang="renderjs">
let myChart
export default {
mounted() {
if (typeof window.echarts === 'function') {
this.initEcharts()
} else {
// 动态引入较大类库避免影响页面展示
const script = document.createElement('script')
// view 层的页面运行在 www 根目录,其相对路径相对于 www 计算
script.src = 'static/echarts.min.js'
script.onload = this.initEcharts.bind(this)
document.head.appendChild(script)
}
},
methods: {
initEcharts() {
myChart = echarts.init(document.getElementById('echarts'), null, {renderer: 'svg'})
// 观测更新的数据在 view 层可以直接访问到
myChart.setOption(this.option)
},
updateEcharts(newValue, oldValue, ownerInstance, instance) {
// 监听 service 层数据变更
if (myChart) {
myChart.setOption(newValue)
}
},
onClick(event, ownerInstance) {
// 调用 service 层的方法
ownerInstance.callMethod('onViewClick', {
test: 'test'
})
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.echarts {
width: 100%;
height: 482px;
overflow: hidden;
width: 100%;
background-color: #12023e;
}
</style>