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.
 
 
 

563 lines
14 KiB

<template>
<div ref="bottomRadarRef" id="bottomRadarChart" style="heigh: 100%; width: 100%;"></div>
</template>
<script setup>
import { ref } from 'vue'
import * as echarts from 'echarts'
const bottomRadarRef = ref(null)
let bottomRadarChart = null
function initEmotionalBottomRadar(KlineData, barAndLineData) {
let bottomRadarChartDom = document.getElementById('bottomRadarChart')
bottomRadarChart = echarts.init(bottomRadarChartDom)
// 日期-作为x轴
let dateArray = KlineData.map(subArray => subArray[0])
// k线,取前四个即可
let kLineDataArray = KlineData.map(subArray => subArray.slice(1, 5))
// 红线,取第二个值
let redLineDataArray = barAndLineData.map(subArray => subArray[1])
// 色块数据格式化
let barTotalDataArray = barAndLineData.map(subArray => subArray.slice(2, 6))
// 删掉
// barTotalDataArray[0] = [0, 0, 0, 0]
// barTotalDataArray[8] = [1, 1, 1, 1]
// barTotalDataArray[9] = [0, 0, 1, 1]
// barTotalDataArray[13] = [1, 0, 1, 0]
// barTotalDataArray[16] = [0, 0, 1, 0]
// 黄色块、黄色加仓资金、紫色柱子、蓝色柱子
let yellowBlockDataArray = []
let yellowLineDataArray = []
let purpleLineDataArray = []
let blueLineDataArray = []
let transparentFillingDataArray = []
// 黄色块:为1 0-4显示柱体
// 黄色加仓资金文字:为1 在4的位置展示文字
// 紫色柱子:为1 1-80显示柱体
// 蓝色柱子:为1 0-40显示柱体
// 因数据要互相叠加展示,所以需要数据处理。base适用于 ECharts 4.x 及以上版本
barTotalDataArray.forEach((item) => {
if (item[0]) {
yellowBlockDataArray.push(4)
if (item[3]) {
// 40-4
blueLineDataArray.push(36)
if (item[2]) {
// 80-40
purpleLineDataArray.push(40)
transparentFillingDataArray.push(0)
} else {
purpleLineDataArray.push(0)
transparentFillingDataArray.push(0)
}
} else {
blueLineDataArray.push(0)
if (item[2]) {
// 80-4
purpleLineDataArray.push(76)
transparentFillingDataArray.push(0)
} else {
purpleLineDataArray.push(0)
transparentFillingDataArray.push(0)
}
}
} else if (!item[0]) {
yellowBlockDataArray.push(0)
if (item[3]) {
blueLineDataArray.push(40)
if (item[2]) {
// 80-40
purpleLineDataArray.push(40)
transparentFillingDataArray.push(0)
} else {
purpleLineDataArray.push(0)
transparentFillingDataArray.push(0)
}
} else {
blueLineDataArray.push(0)
if (item[2]) {
// 80-1,base为1
purpleLineDataArray.push(79)
transparentFillingDataArray.push(1)
} else {
purpleLineDataArray.push(0)
transparentFillingDataArray.push(0)
}
}
}
// 加仓资金
if (item[1]) {
yellowLineDataArray.push(1)
} else if (!item[1]) {
yellowLineDataArray.push(0)
}
})
// 配置图表选项,很多操作和展示已限制,如果需要需放开
let option = {
// backgroundColor: '#000046', // 设置整个图表的背景色
tooltip: {
show: false, // 不展示tip
// 当前echart版本十字准星独立渲染了; 4.x+才有showAxisPointer
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
},
backgroundColor: 'rgba(255, 255, 255, 0.8)',
borderColor: '#ccc',
borderWidth: 1,
padding: 10,
textStyle: {
color: '#333'
},
formatter: function (params) {
let result = `<div style="font-weight: bold;">${params[0].name}</div>`
params.forEach(param => {
let value = param.value
let color = param.color
if (param.seriesType === 'candlestick') {
result += `<div style="color: ${color}"><i class="fa fa-square mr-1"></i>${param.seriesName}: 开 ${value[0]}, 收 ${value[1]}, 低 ${value[2]}, 高 ${value[3]}</div>`
} else {
result += `<div style="color: ${color}"><i class="fa fa-square mr-1"></i>${param.seriesName}: ${value}</div>`
}
})
return result
}
},
legend: {
// data: ['K线', '红线', '色块'], 不要展示图例
type: 'scroll',
pageButtonItemGap: 2,
pageButtonPosition: 'end',
textStyle: {
color: '#666'
}
},
grid: [
{
left: '3%',
right: '3%',
top: '20px',
bottom: '50%',
height: '300px',
// containLabel: true
},
{
left: '3%',
right: '3%',
top: '320px',
bottom: '25%',
height: '300px',
// containLabel: true
},
{
left: '3%',
right: '3%',
top: '620px',
bottom: '50px',
height: '300px',
// containLabel: true
}
],
xAxis: [
{
type: 'category',
data: dateArray,
gridIndex: 0,
boundaryGap: true, // 保持间距,不要离y轴太近,不然重叠了
axisLine: {
// show: false,
lineStyle: {
color: '#837b7b', // x轴线颜色
}
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitLine: {
show: false // 不要x轴的分割线
},
axisPointer: {
link: {
xAxisIndex: 'all'
}
}
},
{
type: 'category',
data: dateArray,
gridIndex: 1,
boundaryGap: true,
axisLine: {
// show: false,
lineStyle: {
// color: '#008000'
color: '#837b7b'
}
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitLine: {
show: false
},
axisPointer: {
link: {
xAxisIndex: 'all'
}
}
},
{
type: 'category',
data: dateArray,
gridIndex: 2,
axisLine: {
lineStyle: {
color: '#837b7b'
}
},
axisTick: {
show: true, // 显示刻度线
alignWithLabel: true,
lineStyle: {
color: '#999', // 颜色
width: 1, // 宽度
type: 'solid' // 线样式(solid/dashed/dotted)
}
},
axisLabel: {
color: '#000000',
interval: 'auto',
rotate: 45
},
splitLine: {
show: false
},
axisPointer: {
link: {
xAxisIndex: 'all'
}
}
}
],
yAxis: [
{
type: 'value',
gridIndex: 0,
splitNumber: 4,
axisLine: {
lineStyle: {
color: '#837b7b' // y轴坐标轴颜色
}
},
axisTick: {
show: true
},
axisLabel: {
width: 50, // 宽度限制
color: '#000000',
formatter: function (value, index) {
if (index === 0) {
return '0'
}
return value.toFixed(2)
}
},
splitLine: {
show: false,
lineStyle: {
color: '#837b7b',
type: 'dotted' // 设置网格线类型 dotted:虚线 solid:实线
}
},
// min: 4,
scale: true, // 不强制包含0,不然k线图底部空余太多
},
{
type: 'value',
gridIndex: 1,
splitNumber: 3,
axisLine: {
lineStyle: {
color: '#837b7b'
}
},
axisTick: {
show: true
},
splitNumber: 5, // 刻度数量
axisLabel: {
width: 50, // 宽度限制
color: '#000000',
formatter: function(value, index) {
// 如果没有刻度数量,其他方法获取不到y轴刻度总长
if (index === 0) {
return '0'
} else if (index === 5) {
return ''
}
return value
}
},
splitLine: {
show: false,
lineStyle: {
color: '#837b7b',
type: 'dotted'
}
},
},
{
type: 'value',
gridIndex: 2,
splitNumber: 2,
axisLine: {
lineStyle: {
color: '#837b7b'
}
},
axisTick: {
show: true
},
splitNumber: 5, // 刻度数量
axisLabel: {
width: 50, // 宽度限制
color: '#000000',
formatter: function(value, index) {
if (index === 5) {
return ''
}
return value
}
},
splitLine: {
show: false,
lineStyle: {
color: '#837b7b',
type: 'dotted' // 设置网格线类型 dotted:虚线 solid:实线
}
},
splitNumber: 5,
min: function(value) {
return 0 // 最小值
},
max: function(value) {
return value.max + 10 // 比最大值高10, 避免最高点和上一个图表x轴重合
}
}
],
dataZoom: [
{
type: 'slider',
xAxisIndex: [0, 2],
// start: 80,
// end: 100,
show: false
},
{
type: 'slider',
xAxisIndex: [0, 2],
// start: 80,
// end: 100,
show: false
},
{
type: 'slider',
xAxisIndex: [0, 2],
// 一次性全部 or 后20%
// start: 80,
// end: 100,
show: false, // 先不显示
borderColor: '#CFD6E3',
dataBackground: {
// 线
lineStyle: {
color: '#CFD6E3'
},
// 阴影
areaStyle: {
color: 'rgba(241,243,247,0.5)'
}
}
},
],
series: [
{
name: 'K线',
type: 'candlestick',
data: kLineDataArray,
xAxisIndex: 0,
yAxisIndex: 0,
itemStyle: {
color: '#ef232a', // 上涨颜色 (红)
color0: '#14b143', // 下跌颜色 (绿)
borderColor: '#ef232a',
borderColor0: '#14b143',
normal: {
color: '#ef232a', // 上涨颜色 (红)
color0: '#14b143', // 下跌颜色 (绿)
borderColor: '#ef232a',
borderColor0: '#14b143',
opacity: function(params) {
// 收盘价 > 开盘价时为阳线,设置边框不透明、填充透明
return params.data[2] > params.data[1] ? 0 : 1
}
}
}
},
{
name: '红线',
type: 'line',
data: redLineDataArray,
xAxisIndex: 1,
yAxisIndex: 1,
symbol: 'none',
sampling: 'average',
itemStyle: {
normal: {
color: '#ef232a'
}
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(33, 150, 243, 0.4)' },
{ offset: 1, color: 'rgba(33, 150, 243, 0)' }
]
}
}
},
{
name: '基础base',
type: 'bar',
stack: 'total',
// barGap: '-100%', // 重叠
xAxisIndex: 2,
yAxisIndex: 2,
barCategoryGap: '0%',
itemStyle: {
normal: {
color: '#ffffff',
borderWidth: 0,
}
},
data: transparentFillingDataArray,
},
{
name: '黄色块',
type: 'bar',
stack: 'total',
// barGap: '-100%', // 重叠
xAxisIndex: 2,
yAxisIndex: 2,
barCategoryGap: '0%', // 类目间柱条间距为0
itemStyle: {
normal: {
color: 'rgba(255, 255, 0, 1)',
borderWidth: 0,
// 加仓资金的文字显示
label: {
show: (params) => {
return yellowLineDataArray[params.dataIndex] > 0
},
position: 'top',
textStyle: {
color: 'rgba(255, 255, 0, 1)'
},
formatter: (params) => {
return yellowLineDataArray[params.dataIndex] > 0 ? '加仓资金' : ''
}
}
}
},
data: yellowBlockDataArray,
},
{
name: '蓝色',
type: 'bar',
stack: 'total',
xAxisIndex: 2,
yAxisIndex: 2,
barCategoryGap: '0%', // 类目间柱条间距为0
label: {
show: true,
position: 'inside'
},
itemStyle: {
normal: {
color: 'rgba(34, 196, 190, 1)',
borderWidth: 0
}
},
data: blueLineDataArray
},
{
name: '紫色',
type: 'bar',
stack: 'total',
xAxisIndex: 2,
yAxisIndex: 2,
barCategoryGap: '0%', // 类目间柱条间距为0
label: {
show: true,
position: 'inside'
},
itemStyle: {
normal: {
color: 'rgba(191, 87, 222, 1)',
borderWidth: 0
}
},
data: purpleLineDataArray
},
]
}
// 使用配置项显示图表
bottomRadarChart.setOption(option)
// 监听窗口大小变化,调整图表尺寸
window.addEventListener('resize', () => {
bottomRadarChart.resize()
})
}
// 暴露给父级
defineExpose({
initEmotionalBottomRadar
})
onBeforeUnmount(() => {
// 组件卸载时销毁图表
if (bottomRadarChart) {
bottomRadarChart.dispose()
}
})
</script>
<style>
#bottomRadarChart{
min-width: 100%;
/* min-height: 100%; */
height:1040px;
/* padding-bottom: 3rem; */
}
</style>